有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java paintComponent()输出错误

我正在尝试制作一个程序,它将连接我在JPanel中单击的两个点。我想用一条线把这两点连接起来。每当我使用鼠标单击时,我都会显示我的(x1,y1)和(x2,y2)坐标值,并且这些值中没有错误。但是,当显示线时,它似乎不遵循我指定的坐标,而是在不同的位置输出,并且失真。大多数线条都会被某些东西切割,我认为这是线条创建的矩形,因为我使用了setBounds()。另外,我添加了一个系统。出来println(“”)在我的paintComponent函数中,我注意到它打印了多次(每次单击后增加1次),尽管它应该只打印一次。有人能帮我吗?谢谢

以下是导致错误的两个类:

第1类:

import java.awt.event.MouseEvent;
import javax.swing.JPanel;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Arch. Don Saborrido
 */
public class twixtBoard extends JPanel implements java.awt.event.MouseListener{
    int x1 = 0, x2, y1 = 0, y2;
    DrawLine line;
    //DrawLine line;


    public twixtBoard(){
       //requestFocus();
        setLayout(null);
        setVisible(false);
        setBounds(0,0,600,450);
        setOpaque(false);
        setFocusable(false);
        addListener();
    }

    public void addListener(){
        addMouseListener(this);
    }

    public void mouseClicked(MouseEvent e) {
        if (x1 == 0 || y1 == 0){
                    x1 = e.getX();
                    y1 = e.getY();
                    System.out.println(x1 + " " + y1);
        }
        else{
            x2 = e.getX();
            y2 = e.getY();
            //System.out.println(x2 + " " + y2);
            line = new DrawLine(x1, y1, x2, y2);
            line.setBounds(x1, y1, x2, y2);
            System.out.println("" + line.getLocation());
            //line.setOpaque(false);
            add(line);
            x1 = x2;
            y1 = y2;
            repaint();
        }
    }

    public void mousePressed(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseReleased(MouseEvent e) {
        ///throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseExited(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }
}

2级(油漆级):

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Arch. Don Saborrido
 */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
//import java.awt.geom.Line2D;
import javax.swing.JPanel;

public class DrawLine extends JPanel{
    int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
    //Line2D line;
    Stroke[] s = new Stroke[] {new BasicStroke(10.0f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND)};
    //new BasicStroke(25.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL),
    //new BasicStroke(25.0f, BasicStroke.CAP_SQUARE,BasicStroke.JOIN_MITER)
    GeneralPath path = new GeneralPath();

    public DrawLine(int start_x, int start_y, int end_x, int end_y){
        x1 = start_x;
        y1 = start_y;
        x2 = end_x;
        y2 = end_y;
        System.out.println(x1+ " " + y1+ " " + x2+ " " + y2+ " ");
    }

    @Override
    protected void paintComponent(Graphics g) {
        System.out.println("entered paint");
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLACK);
        g2.setStroke(s[0]);
        path.moveTo(x1,y1);
        System.out.println("x1 = " + x1 + " y1 = " + y1);
        path.lineTo(x2,y2);
        System.out.println("x2 = " + x2 + " y2 = " + y2);
        System.out.println("" + path.getBounds2D());
        g2.draw(path);
        //line = new Line2D.Float(x1, y1, x2, y2);
        //if(x1 != x2 && y1 != y2)
            //g2.draw(line);
    }
}

共 (3) 个答案

  1. # 1 楼答案

    line = new DrawLine(x1, y1, x2, y2);
    ine.setBounds(x1, y1, x2, y2);
    add(line); 
    

    基本逻辑在我看来是错误的。不能只使用4个值来表示大小和位置

    位置将是x1/x2和y1/y2中的最小值

    那么大小(宽度、高度)就是(x1-x2)和(y1-y2)的绝对值

    然后当你画这条线的时候,你会画一条从(0,0)到(宽度,高度)的线

    也许来自Custom Painting Approaches的代码示例将有助于提供稍微不同的解决方案

  2. # 2 楼答案

    其中一个问题是,你计算的宽度和高度是错误的。它们将是x1和x2以及y1和y2之间的差异

    您也可以使用java的Graphics类更轻松地实现这一点。有drawLine()这样的方法,这可能会让你的生活更轻松

  3. # 3 楼答案

    这是一个非常复杂的方法

    尝试以下方法:

    • 创建一个包含四个变量的类(例如LineClass):x1、x2、y1和y2
    • 保留生成行的ArrayList
    • 使用g.drawline(line.x1、line.y1、line.x2、line.y2)在JPanel上绘制ArrayList中的每一行,其中line是ArrayList的元素
    class MainClass extends JPanel implements MouseListener {
      boolean clickedOnce = false;
      ArrayList<Line> lines = new ArrayList<Line>();
      int x, y;
      MainClass () {
        // init...
        addMouseListener(this);
      }
      // more MouseEvent methods
      public void mouseClicked(MouseEvent e) {
        if (!clickedOnce){
          x=e.getX(); 
          y = e.getY();
          clickedOnce = true;
        }
        else{
          lines.add(new Line(x,y,e.getX(), e.getY());
          clickedOnce = false;
          repaint();
        }
      }
    
      public void paintComponent (Graphics g) {
        super.paintComponent(g);
        for (Line l: lines)
          g.drawLine(l.x1, l.y2, l.x2, l.y2);
      }
    
      private class Line {
        public int x1, y1, x2, y2;
        Line (int x1, int y1, int x2, int y2) {
          this.x1 = x1;
          this.x2 = x2;
          this.y1 = y1;
          this.y2 = y2;
        }
      }
    }