Swing重绘出血

时间:2017-02-16 08:08:58

标签: java multithreading swing

我正在尝试使用Java Swing编写一个程序,在JPanel上绘制随机行。为此,我已经覆盖了JPanel的paintComponent(Graphics g)方法。

我还使用Thread来重新绘制重新绘制之间固定延迟的组件。

线程由JButton控制,可以启动和停止组件的绘制。

然后整个面板嵌入JFrame并显示在屏幕上。

当我执行代码并开始绘画时,我看到“开始”按钮正在“流血”到我正在绘制随机线的JPanel

任何人都可以解释为什么会这样吗?

这是用于重新创建问题的可执行Java代码。我还添加了截图以便更清晰。

package application;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RandomLines extends JPanel implements Runnable{
    private static final long serialVersionUID = 3312914356515718206L;

    private boolean running = false;
    private boolean init = false;

    private Point startPoint = getRandomPoint();
    private Point endPoint = getRandomPoint();

    public RandomLines() {
        setBounds(0, 0, 400, 400);
        setPreferredSize(new Dimension(400, 400));
    }

    @Override
    public synchronized void paintComponent(Graphics g) {
        if(init == false) { 
            g.setColor(Color.cyan);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.black);

            init = true;
        }
        g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
    }

    public void run() {
        while(running) {
            repaint();
            delay();
            startPoint = endPoint;
            endPoint = getRandomPoint();
        }
    }

    private void delay() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
        }
    }

    private Point getRandomPoint() {
        int w = getWidth();
        int h = getHeight();

        int randX = (int) (Math.random() * 10000 % w);
        int randY = (int) (Math.random() * 10000 % h);

        return new Point(randX, randY);
    }

    public void createAndShowGui() {
        JFrame frame = new JFrame("Random Lines");
        frame.setSize(400, 400);
        frame.add(this);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton b = new JButton("Start");
        b.addActionListener(al -> {
            if (running == false) {
                frame.setVisible(true);
                running = true;
                b.setText("Stop");
                Thread t = new Thread(RandomLines.this);
                t.start();
            } else {
                frame.setVisible(false);
                frame.dispose();
                running = false;
                b.setText("Start");
            }
        });
        JOptionPane.showOptionDialog(null, b, "Control Random Lines", JOptionPane.OK_OPTION, JOptionPane.PLAIN_MESSAGE, null, new String[]{"Close"}, null);
    }

    public static void main(String[] args) {
        RandomLines rl = new RandomLines();
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                rl.createAndShowGui();
            }
        });
    }

}

这是一个解释“流血”问题的屏幕截图。

Here is a screen shot explaining the "bleeding" problem..

我希望我已经详细解释了这个问题,让其他人了解。如果您需要更多详细信息,请与我们联系。

  

更新

我观察到的一个问题是当我使用多个监视器并在两个不同的监视器上使用JOptionPane和JFrame时。问题不会发生。

但为什么它首先发生呢?

0 个答案:

没有答案