JFrame在设置TextPane之前退出

时间:2016-03-31 04:27:04

标签: java swing jframe

这里有两个课程:

测试类:

public class test {
    private static JPanel contentPane;
    private static JFrame frame = new JFrame("Sleeping");
    private static JTextPane textPane;
    private static StyledDocument doc;
    private static Thread sleep;
    private static HandleMouse S = new HandleMouse();

public static void main(String[] args) {

    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    frame.setBounds(0, 0, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    frame.setContentPane(contentPane);
    frame.setLocationRelativeTo(null);

    JPanel panel = new JPanel();
    contentPane.add(panel, BorderLayout.CENTER);
    panel.setLayout(new BorderLayout(0, 0));

    textPane = new JTextPane();
    panel.add(textPane, BorderLayout.CENTER);

    doc = textPane.getStyledDocument();
    SimpleAttributeSet center = new SimpleAttributeSet();
    StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
    doc.setParagraphAttributes(doc.getLength() + 1, 1, center, false);

    textPane.setEditable(false);
    sleep = new Thread(() -> {
        try {
            textPane.setBackground(new Color(59, 82, 217));
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "Waiting for sleep, I drift from thoughts like these;\n", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "And where to-day was dream-like, build my dreams.\n", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "Across my brain, ghost of remembered chords\n ", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "Which still can make such radiance in my dream.\n", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "And count their faces; faces; sunlit faces.\n", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "Falling asleep ... the herons, and the hounds....\n", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "September in the darkness; and the world I've known\n", null);
            Thread.sleep(1200);
            doc.insertString(doc.getLength(), "all fading past me into peace. ", null);

        } catch (BadLocationException | InterruptedException e) {

        }
    });

    frame.setResizable(false);
    frame.setVisible(true);
    sleep.start();

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    textPane.addMouseMotionListener(S);
    frame.addMouseMotionListener(S);

}

}

以及处理鼠标移动的测试类中的另一个内部类:

public static class HandleMouse implements MouseMotionListener {

    @Override
    public synchronized void mouseDragged(MouseEvent e) {
        textPane.setText("Test");
        ifinterrupt();
    }

    @Override
    public synchronized void mouseMoved(MouseEvent e) {
        textPane.setText("Test");
        ifinterrupt();

    }

    private void ifinterrupt() {
        sleep.interrupt();
        textPane.removeMouseMotionListener(S);
        frame.removeMouseMotionListener(S);
        textPane.setBackground(Color.RED);
        try {
            Thread.sleep(1000);
            System.exit(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

但是,当我移动鼠标并触发mouseMoved方法时,JFrame会在执行此行之前退出(System.exit(0)):

textPane.setText("Test");

但理论上它应该在退出之前将文本设置为"Test",因为setText设置在ifinterrupt()行之前:

textPane.setText("Test");
ifinterrupt();

我的问题是,为什么在设置文本之前退出JFrame以及导致它的原因是什么?

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

如果您想在GUI上更改某些内容,则应使用EDT(事件调度线程)。 与任何UI / Swing组件的所有交互必须在EDT的上下文中完成

启动应用程序时,在尝试创建/与任何Swing组件交互之前,应确保在EDT中执行。

使用此代码。以下线程称为事件处理线程。在此线程中编写在UI中进行更改的代码,或者调用包含此线程中代码的方法。

EventQueue.invokeLater(new Runnable() {
    public void run() {
        // Now in the event dispatching thread
    }
});

EDT会在UI上对您的更改进行排队,并根据优先级运行。

答案 1 :(得分:1)

如果你想等待1秒钟才能看到重新渲染的GUI,请不要阻止EDT,而是创建一个新的计时器并在此计时器内关闭你的帧

        Thread r = new Thread() {
            public void run() {
                try {
                    sleep(1000);
                    System.exit(0);
                } catch (InterruptedException e) {
                }
            };
        };
        r.start();