2017-06-12 79 views
-1

我在写我自己的类通知(不介意的代码,它是由GUI的IntelliJ设计器生成)的的JWindow不正确渲染

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); 

的问题是,通知窗口有时不能正常显示。有时它只是与通知窗口大小一样,只能在没有任何元素的情况下使用白色背景。 我的错误在哪里?

+0

哪里GridLayoutManager从何而来?这是一个Android布局管理器,不是Swing。你在使用另一个图书馆吗?我个人只使用Swing布局管理器,从来没有与他们有任何问题。 – markbernard

+0

@markbernard,GridLayoutManager是默认的IntelliJ IDEA GUI Designer布局。我没有改变任何东西。 – whyiamhere

+0

这意味着它依赖于Swing的外部库。这不是标准的LayoutManager。我个人对使用非标准布局犹豫不决,因为有太多的选择。 – markbernard

回答

2

有时,它只是帧通知窗口应与白色背景只有相同大小没有任何元素时,在Event Dispatch Thread (EDT)不执行代码会导致

随机问题。

我正在使用ScheduledExecutorService类。

摆动部件应在EDT上创建。从ScheduledExecutorService调用的代码不会在EDT上运行。您可以使用Swing Timer来安排活动。

阅读Swing tutorial。上有几个部分:

  1. 并发在Swing - 讲解更多关于EDT
  2. 如何使用Swing计时器
+0

这不完全准确。您不必在EDT上创建您的GUI。他们的活动随后由EDT控制(绘画,事件派发等)。 – markbernard

+0

@markbernard曾经是这样,但不再是。请参阅https://stackoverflow.com/questions/491323/is-it-safe-to-construct-swing-awt-widgets-not-on-the-event-dispatch-thread。 – VGR

+0

@VGR谢谢你。我不知道这个变化。 – markbernard