Java运行+重绘=灰色窗口

标签 java swing jpanel paint

我正在尝试使用 JFrame/JPanels repaint(); 等等,但是当我启动一个线程,并通过 run while true 调用 repaint 时,它只会吐出一行System.out.println("as"); 我放置它来检查循环是否正在运行。

所以问题是: 为什么在循环中调用 repaint 时我的绘图会消失? (似乎只显示了带有 canvas_width/heightJFrame,没有面板等。)

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
    frame.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel(new GridLayout());

    frame.getContentPane().add(p);
    Something s = new Something();

    p.add(s);
    p.setBackground(Color.black);
    frame.pack();

}

还有一些类:

public class Something extends JPanel implements Runnable {


public Something(){
    Thread t = new Thread();
    t.start();
    run();

}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.cyan);
    g.fillRect(0, 0, getWidth()-150, getHeight()-100);
    g.setColor(Color.BLACK);
    g.fillOval(10, 10, 25, 25);

}


@Override
public void run() {
    while(true){
    repaint();
    System.out.println("as");

    try {
        Thread.sleep(1);
    } catch (InterruptedException e){}
    }
}
}

任何有关 contentpane 的帮助都是值得赞赏的,因为我不确定这是否正确完成。

最佳答案

不要在 Thread 中调用 Thread.sleep(n),而是实现一个 Swing Timer 来重复任务。这确保了在事件调度线程上调用 repaint()

参见Concurrency in Swing更多细节。

此外,每 1 毫秒重新绘制一次是非常乐观的。

工作中的 SSCCE E.G. (请注意,此版本实际上更改了生成的绘制操作的坐标,只是为了让我们知道正在发生某些事情!

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Something extends JPanel {

    static final int CANVAS_WIDTH = 400;
    static final int CANVAS_HEIGHT = 100;
    private int xDelta = 0;

public Something(){
    ActionListener animater = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            repaint();
        }
    };
    Timer t = new Timer(10,animater);
    t.start();
}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.cyan);
    g.fillRect(0, 0, getWidth()-(xDelta--), getHeight()-100);
    g.setColor(Color.BLACK);
    g.fillOval(xDelta, 10, 25, 25);

    if (xDelta<0) {
        xDelta = CANVAS_WIDTH;
    }
}

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

public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel(new GridLayout());

    frame.getContentPane().add(p);
    Something s = new Something();

    p.add(s);
    p.setBackground(Color.black);
    frame.pack();
    frame.setResizable(false);
    frame.setVisible(true);
}
}

关于Java运行+重绘=灰色窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16353651/

相关文章:

java - 如何使用工厂模式来获取数据库客户端的实例?

java - 即使没有进度变化,onProgressChanged 也会运行

java - 如何更改未装饰框架中的背景颜色?

java - 将 JPanel 行添加到 JTable 模型

java - Android 高分板

java - 哈希字符串的字节转换,java 与 python

java - 均匀对齐对象

Java JComboBox 选择最后一个值

java - 使用鼠标事件时 JPanel 重绘不可见

java - 如果选中复选框,则将 JPanel 设置为可见