行为不一致

时间:2014-01-07 15:33:19

标签: java swing awt

以下代码在运行时会出现不一致的行为。在某些运行中,画布最终呈灰色,但在其他运行中,它最终会变成蓝色。为什么会这样,我该如何纠正呢?

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

public class psw extends JFrame {
    String symbols="~ ! @ # $ % ^ & * ( ) _ = + : ; < , > . ? / | \\ '";

    public static void main(String[] args){
    psw app=new psw();
    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
    app.setSize(600, 450);
    app.setVisible(true);
    app.getContentPane().setBackground(new Color(30,144,255));

    @Override    
    public void paint(Graphics g) {
        g.setColor(new Color(255,255,255));
        g.drawRect(10, 10, 60, 50);
        g.drawLine(60, 50, 220, 20);
        g.drawString(symbols, 10, 150);
    }
}

2 个答案:

答案 0 :(得分:2)

将您的代码更改为access the JFrame through the event dispatch thread,如下所示:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI();
    }
});

Oracle tutorial说:

  

Swing事件处理代码在称为事件的特殊线程上运行   派遣线程。大多数调用Swing方法的代码也会运行   这个帖子。这是必要的,因为大多数Swing对象方法都是   不是“线程安全”:从多个线程调用它们冒险线程   干扰或内存一致性错误。一些Swing组件   方法在API规范中标记为“线程安全”;这些可以   从任何线程安全地调用。所有其他Swing组件方法   必须从事件派发线程调用。忽略的程序   此规则可能在大多数情况下正常运行,但受制于   难以重现的不可预测的错误。

听起来就像你所看到的那样。

答案 1 :(得分:2)

您需要记得致电super.paint(g);。这显示了这幅画。

public void paint(Graphics g) {
    super.paint(g);
    g.setColor(new Color(255,255,255));
    g.drawRect(10, 10, 60, 50);
    g.drawLine(60, 50, 220, 20);
    g.drawString(symbols, 10, 150);
}
  • 此外,在JFrame这样的顶级容器上绘制并不是一个好主意,因为它们不是双缓冲的。而是在组件上绘制,主要是JPanel并覆盖其paintComponent方法。与paint一样,您需要致电super.paintComponentsuper.paintComponent(g)调用paintComponentJPanel类)的超类中的JComponent方法来清除当前在面板上绘制的内容。

以下是使用JPanel代替JFrame

的方式
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

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

public class psw extends JPanel {
    String symbols = "~ ! @ # $ % ^ & * ( ) _ = + : ; < , > . ? / | \\ '";

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame app = new JFrame();
                app.add(new psw());
                app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                app.pack();
                app.setVisible(true);

            }
        });
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(new Color(30, 144, 255));
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(new Color(255, 255, 255));
        g.drawRect(10, 10, 60, 50);
        g.drawLine(60, 50, 220, 20);
        g.drawString(symbols, 10, 150);
    }

    public Dimension getPreferredSize() {
        return new Dimension(600, 450);
    }
}