JFrame在设置TextPane之前退出



这里有两个类:

测试等级:

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 chordsn ", 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 knownn", 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在设置文本之前退出,是什么原因导致的?

感谢您的帮助。

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

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

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

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

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

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

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

最新更新