java - 图形循环故障,如何修复?
问题描述
我一直在努力做到这一点,以便有 20 个盒子,每个盒子有 3 种不同的尺寸和 3 种不同的颜色,随机选择,但我不能让它们在不同的时间出现,它们只是互相干扰,颜色也有干扰在一起和类似的东西,有人知道如何解决吗?这是我到目前为止得到的:
import java.awt.*;
import javax.swing.*;
public class testwork extends JPanel { //JPanel is a class
int l = 0;
private int x = 10;
private int y = 500;
private void move()
{
x++;
}
boolean red = false;
boolean blue = false;
boolean green = false;
@Override
public void paint(Graphics g) { //JPanel is a class defined in
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Color rectColor = new Color(0, 66, 89);
g2d.setColor(rectColor);
//belt
g2d.setColor(Color.lightGray);
g2d.fillRect(0,450,1500,200);
g2d.fillRect(700,0,200,1000);
g2d.setColor(Color.orange);
for (int i = -10000; i<10000; i=i+50) {
int m= i++;
g2d.fillRect(m, 450, 25, 200);
}
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(700, 450, 200, 200);
//boxes
while (l<=20) {
if (Math.random() < 0.5)
{g2d.setColor(Color.RED);;}
else if (Math.random() < 0.5) {g2d.setColor(Color.GREEN);}
else {g2d.setColor(Color.BLUE);}
if (Math.random() < 0.5)
{g2d.fillRect(x,y,50,50);}
else if (Math.random() < 0.5) {g2d.fillRect(x,y,50,100);}
else {g2d.fillRect(x,y,100,50);}
l++;
}
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Frame"); //Add our JPanel to the frame
frame.add(new attempt());//instantiate a new object
frame.setSize(1500, 1000);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testwork p = new testwork();
frame.add(p);
while (true)
{
p.move(); //Updates the coordinates
p.repaint();
Thread.sleep(10); //Pauses for a moment
}}
}
解决方案
不幸的是,你做错了很多事情。
- 覆盖
paintComponent
而不是paint
。 - 不要使用
Thread.sleep
. 使用 aSwing timer
和 anActionListener
- 你在绘画方法上做得太多了。所有事件处理(包括调用
repaint()
)都在事件调度线程 (EDT) 上完成。因此,您的所有更新都在 paintComponent 内部完成,因此当您退出时,只会显示最后绘制的对象。更新您的坐标、数据结构和其他任何需要在您的绘制方法之外绘制的内容。
把你boiler plate code
放在你的 Testwork 类构造函数中。这是一个例子。
public Testwork() {
setPreferredSize(new Dimension(1000, 700));
Timer timer = new Timer(0, this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
// sizes the frame and jpanel and organizes the components.
frame.pack();
// centers the window in the screen
frame.setLocationRelativeTo(null);
// sets the delay in milliseconds
timer.setDelay(100);
// starts the timer
timer.start();
}
这将是您的 actionListener 代码。
public void actionPerformed(ActionEvent ae) {
// update any variables that need to be used int he
// paint routine here. That means if you want to move something
// update the coordinates here and then use them in the paint method.
}
当你启动时,你的应用程序,这样做
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Testwork());
}
推荐阅读
- linux - 如何告诉用户空间程序停止发送?或者发送了多少个字符?
- python - Python Beautiful Soup 没有循环结果
- java - 如何获取动态设置为 TextView 的文本?
- firebase - 如何使颤振飞镖中的流与提供者一起使用
- sql - 当 F9 在查询结果窗口中返回正确的值时,为什么 F5 在脚本输出窗口中返回四舍五入的数字
- javascript - 危险行为disallowedcontent让我在某些情况下插入js
- android - NFC支付环
- java - 如何覆盖 compareTo 方法?
- flutter - 颤振遍历带有地图的按钮列表
- ios - 在 iPhone XR 模拟器上横向使用 SwifUI NavigationView 的任何经验?