简体   繁体   中英

Jframe not repainting issue

I have a program which is simple in function. On start, it creates a random circle which it places in the window/frame. When that circle is clicked, it should dissappear, and spawn a new circle elsewhere. the issue is, my program does this, but you see all the past circles unless you minimize/reopen the window. I cannot get it to repaint without my help... and I do NOT know why. Here is my code.

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();


        }
    });
}

}

Your code works perfectly fine for me, however...

  • Don't override paint of top level containers like JFrame , JFrame contains a JRootPane , which contains a contentPane and may also have a visible glassPane , all of which can overpaint what is painted within the paint method. As a general rule, you shouldn't extend from JFrame (or other top level containers), you are locking yourself into a single use case, reducing the re-usability of your component and you're not actually any new functionality to the class. Instead, use a JPanel and override it's paintComponent method
  • Call super.paint before doing any custom painting. If, however, you use a JPanel , call super.paintComponent . Painting is performed by a series of methods which are chained together to generate the final output. See Painting in AWT and Swing and Performing Custom Painting for more details
  • Consider using something like x = r.nextInt(this.getWidth() - 150) + 75; and y = r.nextInt(this.getWidth() - 150) + 75; instead of your while loops, I think you might find them safer to use

For example...

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();
        }

    }

}

Or, based on what I believe you're trying to do, you could simply do something like...

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();
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM