Jframe没有重新绘制问题

时间:2015-07-08 01:33:03

标签: java swing drawing 2d

我有一个功能简单的程序。一开始,它会创建一个随机圆圈,放置在窗口/框架中。单击该圆圈时,它应该消失,并在其他地方生成一个新圆圈。问题是,我的程序执行此操作,但除非您最小化/重新打开窗口,否则您将看到所有过去的圈子。没有我的帮助,我不能把它重新绘制......我不知道为什么。这是我的代码。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;

public class Core extends JFrame implements MouseListener{
public static ArrayList<Ellipse2D> list = new ArrayList<Ellipse2D>();
Random r = new Random();


public Ellipse2D  spawn(){

    int x = r.nextInt(this.getWidth());
    int y = r.nextInt(this.getHeight());

    while(x<75||x>this.getWidth()-150){
        x = r.nextInt(this.getWidth());
    }
    while(y<75||y>this.getHeight()-150){
        y = r.nextInt(this.getHeight());
    }
    System.out.println("MAKING SHAPE at :" + x + " AND " + y);
    return new  Ellipse2D.Double(x, y, 75, 75);
}
public void mouseClicked(MouseEvent me) {
    // Save the coordinates of the click lke this.
    if(list.get(0).contains(me.getPoint())){
        System.out.println("CLICKED SHAPE!");
        list.clear();

        list.add(spawn());


    }
    revalidate();
  repaint();
}

public void mouseEntered(MouseEvent e) {
}

public void mouseReleased(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

@Override
public void paint(Graphics g) {

    if(list.size()==0){
        System.out.println("oops");

    }
    if(!list.isEmpty()){

    System.out.println("DRAW");
int x =(int) list.get(0).getX();
int y =(int) list.get(0).getY();
int width = (int) list.get(0).getWidth();
int height = (int) list.get(0).getHeight();

    g.setColor(Color.red);
    g.drawOval(x,y, width, height);
    }


}
public Core(){

setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addMouseListener(this);
list.add(spawn());
setVisible(true);
}
public static void main(String args[]) {

    EventQueue.invokeLater(new Runnable() {
        public void run() {
            new Core();


        }
    });
}

}

1 个答案:

答案 0 :(得分:4)

你的代码对我来说非常好,但是......

  • 不要覆盖paint等顶级容器的JFrameJFrame包含JRootPane,其中包含contentPane,也可能会显示glassPane paint,所有这些都可以覆盖JFrame方法中绘制的内容。作为一般规则,您不应该从JPanel(或其他顶级容器)扩展,您将自己锁定在一个用例中,减少组件的可重用性,而您实际上并不是新的课堂的功能。相反,请使用paintComponent并覆盖它的super.paint方法
  • 在进行任何自定义绘画之前调用JPanel。但是,如果您使用super.paintComponent,请致电x = r.nextInt(this.getWidth() - 150) + 75;。绘画由一系列方法执行,这些方法链接在一起以产生最终输出。有关详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting
  • 考虑使用y = r.nextInt(this.getWidth() - 150) + 75;import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.util.ArrayList; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Core { public static void main(String args[]) { EventQueue.invokeLater(new Runnable() { public void run() { new Core(); } }); } public Core() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new CorePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class CorePane extends JPanel { private ArrayList<Ellipse2D> list = new ArrayList<Ellipse2D>(); private Random r = new Random(); public Ellipse2D spawn() { int x = r.nextInt(this.getWidth()); int y = r.nextInt(this.getHeight()); x = r.nextInt(this.getWidth() - 150) + 75; y = r.nextInt(this.getWidth() - 150) + 75; System.out.println("MAKING SHAPE at :" + x + " AND " + y); return new Ellipse2D.Double(x, y, 75, 75); } public CorePane() { addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { // Save the coordinates of the click lke this. if (list.get(0).contains(me.getPoint())) { list.clear(); list.add(spawn()); } revalidate(); repaint(); } }); } @Override public void invalidate() { super.invalidate(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (list.isEmpty()) { list.add(spawn()); } } }); } @Override public Dimension getPreferredSize() { return new Dimension(500, 500); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (!list.isEmpty()) { for (Ellipse2D ellipse : list) { g2d.setColor(Color.red); g2d.draw(ellipse); } } g2d.dispose(); } } } 之类的东西代替你的while循环,我想你可能会觉得使用它们更安全

例如......

public class CorePane extends JPanel {

    private Random r = new Random();
    private Ellipse2D ellipse;

    public Ellipse2D spawn() {

        int x = r.nextInt(this.getWidth());
        int y = r.nextInt(this.getHeight());

        x = r.nextInt(this.getWidth() - 150) + 75;
        y = r.nextInt(this.getWidth() - 150) + 75;
        System.out.println("MAKING SHAPE at :" + x + " AND " + y);
        return new Ellipse2D.Double(x, y, 75, 75);
    }

    public CorePane() {
        addMouseListener(new MouseAdapter() {

            public void mouseClicked(MouseEvent me) {
                if (ellipse != null && ellipse.contains(me.getPoint())) {
                    ellipse = spawn();
                }
                revalidate();
                repaint();
            }
        });
    }

    @Override
    public void invalidate() {
        super.invalidate();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                spawn();
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500, 500);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        if (ellipse != null) {
            g2d.setColor(Color.red);
            g2d.draw(ellipse);
        }
        g2d.dispose();
    }

}

或者,基于我认为你想要做的事情,你可以简单地做一些像......

hGet