我有一个功能简单的程序。一开始,它会创建一个随机圆圈,放置在窗口/框架中。单击该圆圈时,它应该消失,并在其他地方生成一个新圆圈。问题是,我的程序执行此操作,但除非您最小化/重新打开窗口,否则您将看到所有过去的圈子。没有我的帮助,我不能把它重新绘制......我不知道为什么。这是我的代码。
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();
}
});
}
}
答案 0 :(得分:4)
你的代码对我来说非常好,但是......
paint
等顶级容器的JFrame
,JFrame
包含JRootPane
,其中包含contentPane
,也可能会显示glassPane
paint
,所有这些都可以覆盖JFrame
方法中绘制的内容。作为一般规则,您不应该从JPanel
(或其他顶级容器)扩展,您将自己锁定在一个用例中,减少组件的可重用性,而您实际上并不是新的课堂的功能。相反,请使用paintComponent
并覆盖它的super.paint
方法JPanel
。但是,如果您使用super.paintComponent
,请致电x = r.nextInt(this.getWidth() - 150) + 75;
。绘画由一系列方法执行,这些方法链接在一起以产生最终输出。有关详细信息,请参阅Painting in AWT and Swing和Performing 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