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...
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 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 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.