Java 自定义绘画未按预期工作

Java 自定义绘画未按预期工作,java,swing,jpanel,awt,Java,Swing,Jpanel,Awt,我正在制作一个GUI应用程序,用于查找和绘制一组点的凸包 这是框架: public class Frame extends JFrame{ Panel panel = new Panel(); JButton drawHull = new JButton("Draw Convex Hull"); Frame(String title) { super(title); // setLayout setLayout(new BorderLayout()); // ad

我正在制作一个GUI应用程序,用于查找和绘制一组点的凸包

这是框架:

public class Frame extends JFrame{
Panel panel = new Panel();
JButton drawHull = new JButton("Draw Convex Hull");
Frame(String title) {
    super(title);
    // setLayout
    setLayout(new BorderLayout());
    // add components to the frame
    add(panel, BorderLayout.CENTER);
    add(drawHull, BorderLayout.SOUTH);
    // add actionListener for drawHull button
    drawHull.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            panel.drawConvexHull();
        }
    }
    );
}
}
框架包含一个按钮(位于框架底部)和一个
面板
对象

下面是
面板
类:

public class Panel extends JPanel{
ArrayList<Point> points = new ArrayList<Point>();
public Panel() {
    addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            points.add(new Point(e.getX(), e.getY()));
            repaint();
        }
    });
}
@Override
protected void paintComponent(Graphics g) {
    if(!points.isEmpty()) {
        Point p = points.get(points.size()-1);
        g.fillOval(p.x-2, p.y-2, 4, 4);
    }
}
public void drawConvexHull() {
    // code for finding convex hull
}
}
公共类面板扩展了JPanel{
ArrayList points=新的ArrayList();
公共事务委员会(){
addMouseListener(新的MouseAdapter(){
@凌驾
公共无效mouseClicked(MouseEvent e){
添加(新点(e.getX(),e.getY());
重新油漆();
}
});
}
@凌驾
受保护组件(图形g){
如果(!points.isEmpty()){
p点=points.get(points.size()-1);
g、 椭圆形(p.x-2,p.y-2,4,4);
}
}
公共无效DrawConvxHull(){
//求凸壳的代码
}
}
我在
面板
类中添加了一个
mouseListener
,这样当用户单击面板上的任意位置时,就会画出一个点

当我运行代码时,一切看起来都很好。这是一个运行示例

现在问题来了:

我一单击面板,就会发生这种情况

框架顶部会出现一个按钮为什么会发生这种情况?

还有一件事。单击顶部的此按钮时,将绘制一个点。在这里,看一看:


paintComponent
中未调用
super.paintComponent(g)
背景未重新绘制,导致面板组件上出现不可预测的结果

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    for (Point point: points) {
        g.fillOval(point.x - 2, point.y - 2, 4, 4);
    }
}

如果不在
paintComponent
中调用
super.paintComponent(g)
,则不会重新绘制背景,从而导致面板组件上出现不可预知的结果

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    for (Point point: points) {
        g.fillOval(point.x - 2, point.y - 2, 4, 4);
    }
}

如果不在
paintComponent
中调用
super.paintComponent(g)
,则不会重新绘制背景,从而导致面板组件上出现不可预知的结果

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    for (Point point: points) {
        g.fillOval(point.x - 2, point.y - 2, 4, 4);
    }
}

如果不在
paintComponent
中调用
super.paintComponent(g)
,则不会重新绘制背景,从而导致面板组件上出现不可预知的结果

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    for (Point point: points) {
        g.fillOval(point.x - 2, point.y - 2, 4, 4);
    }
}


如果我这样做:
If(firstTime){super.paintComponent(g);}
同样的事情也会发生,只要做
super.paintComponent(g)另一种方法是在每次添加点时清除面板,并使用for循环再次绘制所有点。但是我不想使用这种方法。如果我简单地添加
super.paintComponent(g)
,前面的点就会被擦除。只有一点是显示的,在“脏”的喷漆面板上,按照您建议的方式进行操作是混乱和不可预测的。刷新整个面板并绘制所有点,如果我这样做:
if(firstTime){super.paintComponent(g);}
同样的事情发生,只需执行
super.paintComponent(g)另一种方法是在每次添加点时清除面板,并使用for循环再次绘制所有点。但是我不想使用这种方法。如果我简单地添加
super.paintComponent(g)
,前面的点就会被擦除。只有一点是显示的,在“脏”的喷漆面板上,按照您建议的方式进行操作是混乱和不可预测的。刷新整个面板并绘制所有点,如果我这样做:
if(firstTime){super.paintComponent(g);}
同样的事情发生,只需执行
super.paintComponent(g)另一种方法是在每次添加点时清除面板,并使用for循环再次绘制所有点。但是我不想使用这种方法。如果我简单地添加
super.paintComponent(g)
,前面的点就会被擦除。只有一点是显示的,在“脏”的喷漆面板上,按照您建议的方式进行操作是混乱和不可预测的。刷新整个面板并绘制所有点,如果我这样做:
if(firstTime){super.paintComponent(g);}
同样的事情发生,只需执行
super.paintComponent(g)另一种方法是在每次添加点时清除面板,并使用for循环再次绘制所有点。但是我不想使用这种方法。如果我简单地添加
super.paintComponent(g)
,前面的点就会被擦除。只有一点是显示的,在“脏”的喷漆面板上,按照您建议的方式进行操作是混乱和不可预测的。刷新整个面板并绘制所有点