JWindow无法正确呈现

时间:2017-06-12 13:40:20

标签: java swing

我正在编写自己的通知类(不介意代码,它是由IntelliJ GUI Designer生成的)

public class NotificationWindow extends JWindow {

private JLabel icon;
private JTextArea message;
private JLabel title;
private JPanel mainPanel;
private Spacer spacer1;
private Spacer spacer2;

public NotificationWindow(String ttl, String msg) {

    mainPanel = new JPanel();
    mainPanel.setLayout(new GridLayoutManager(3, 3, new Insets(5, 5, 5, 5), -1, -1));

    icon = new JLabel();
    icon.setIcon(new ImageIcon(getClass().getResource("/resources/employee 64.png")));

    title = new JLabel(ttl);
    title.setFont(
            new Font(title.getFont().getName(), Font.BOLD, title.getFont().getSize()));


    message = new JTextArea(3, 44);
    message.setText(msg);
    message.setOpaque(false);
    message.setFont(message.getFont().deriveFont(12f));
    message.setLineWrap(true);
    message.setWrapStyleWord(true);

    spacer1 = new Spacer();
    spacer2 = new Spacer();

    this.pack();
    this.setSize(400, 80);
    this.setAlwaysOnTop(true);
    this.setVisible(true);

    this.getRootPane().setBorder(
            BorderFactory.createMatteBorder(1, 1, 1, 1, Color.DARK_GRAY));

    Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();

    Insets toolHeight = Toolkit.getDefaultToolkit()
            .getScreenInsets(this.getGraphicsConfiguration());

    this.setLocation(
        scrSize.width - this.getWidth() - 20, 
        scrSize.height - toolHeight.bottom - this.getHeight() - 20);

    this.initUI();
}

private void initUI() {

    mainPanel.add(icon, 
        new GridConstraints(0, 0, 3, 1,
                GridConstraints.ANCHOR_CENTER, 
                GridConstraints.FILL_NONE, 
                GridConstraints.SIZEPOLICY_FIXED,
                GridConstraints.SIZEPOLICY_FIXED,
                null, null, null, 0, false));

    mainPanel.add(title,
        new GridConstraints(0, 1, 1, 2,
                GridConstraints.ANCHOR_WEST, 
                GridConstraints.FILL_NONE, 
                GridConstraints.SIZEPOLICY_FIXED,
                GridConstraints.SIZEPOLICY_FIXED,
                null, null, null, 0, false));

    mainPanel.add(message, 
        new GridConstraints(1, 1, 1, 2,
                GridConstraints.ANCHOR_WEST, 
                GridConstraints.FILL_NONE,
                GridConstraints.SIZEPOLICY_FIXED,
                GridConstraints.SIZEPOLICY_FIXED,
                null, null, null, 0, false));

    mainPanel.add(spacer1, 
        new GridConstraints(2, 1, 1, 1,
                GridConstraints.ANCHOR_CENTER,
                GridConstraints.FILL_VERTICAL,
                1,
                GridConstraints.SIZEPOLICY_WANT_GROW,
                null, null, null, 0, false));

    mainPanel.add(spacer2, 
        new GridConstraints(2, 2, 1, 1,
                GridConstraints.ANCHOR_CENTER,
                GridConstraints.FILL_HORIZONTAL,
                GridConstraints.SIZEPOLICY_WANT_GROW,
                1, null, null, null, 0, false));


    this.setContentPane(mainPanel);
    this.repaint();

    // time after which notification will be disappeared
    new Thread(() -> {
        try {
            Thread.sleep(6000);
            dispose();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
}
    }

这个想法是程序会每小时显示一次通知,以提醒用户。为此,我使用ScheduledExecutorService类。我以这种方式调用通知(用于测试每20秒调用的通知):

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        ses.scheduleAtFixedRate(new Runnable() {
            private int i = 1;
            @Override
            public void run() {
                NotificationWindow notificationWindow = 
                    new NotificationWindow(
                        "blah blah", 
                        "Please, " + 
                        "specify the details of the task you're currently working on.");
            }
        }, 10, 20, TimeUnit.SECONDS);

问题是通知窗口有时无法正确呈现。有时它只是框架大小相同,通知窗口应该只有白色背景,没有任何元素。 我的错误在哪里?

1 个答案:

答案 0 :(得分:2)

  

有时它只是框架与通知窗口相同的尺寸应该只有白色背景而没有任何元素

Event Dispatch Thread (EDT)上没有执行代码时,可能会导致随机问题。

  

我正在使用ScheduledExecutorService类。

应在EDT上创建Swing组件。从ScheduledExecutorService调用的代码不会在EDT上运行。

相反,您应该使用Swing Timer来安排活动。

阅读Swing tutorial。有以下部分:

  1. Swing中的并发 - 解释有关EDT的更多信息
  2. 如何使用摇摆计时器