简体   繁体   English

Swing:无法让JButton更新 - repaint()无效

[英]Swing: Can't get JButton to update - repaint() not working

I'm using Swing for the first time to create a simple GUI. 我第一次使用Swing来创建一个简单的GUI。 It consists of a JFrame upon which I have placed a single JButton which, when clicked, calls some other code which takes approx. 它由一个JFrame组成,我在其上放置了一个JButton ,当点击它时,调用一些其他代码需要大约。 3 seconds to return. 3秒钟返回。

Just before the call to this code, in actionPerformed() , I want to update the text on the button to inform the user that processing is occuring. 就在调用此代码之前,在actionPerformed() ,我想更新按钮上的文本以通知用户正在进行处理。 My problem is that the text on the button does not update until after the 3-second call has returned. 我的问题是,直到3秒钟的呼叫返回后,按钮上的文字才会更新。 I want the updated text to be present during the call, then I'll change it back afterwards. 我希望在通话过程中出现更新的文本,然后我会将其更改回来。

Calling repaint() on the JButton doesn't do anything and calling it on the JFrame results in " Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException " being thrown when I click the button. JButton上调用repaint()不会做任何事情并且在JFrame上调用它会导致“ Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException中的Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException ”在我单击按钮时被抛出。

What's happening is that the 3-second code is executing in the GUI thread, so the button doesn't have a chance to update until it's done. 发生的事情是3秒代码在GUI线程中执行,因此按钮在完成之前没有机会更新。

To solve this, start a SwingWorker to do the long-running operation; 要解决此问题,请启动SwingWorker以执行长时间运行操作; then you'll still be free to do things in the GUI while you're waiting for it. 那么在你等待的时候,你仍然可以自由地在GUI中做事。

Here are a couple of tutorials on the subject, and the SwingWorker Javadocs referenced above have some code also. 这里有几个关于这个主题的教程 ,上面引用的SwingWorker Javadoc也有一些代码。

Sample code 示例代码

public void actionPerformed(ActionEvent e) {
    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
        @Override
        public Void doInBackground() {
            // Call complicated code here
            return null;
            // If you want to return something other than null, change
            // the generic type to something other than Void.
            // This method's return value will be available via get() once the
            // operation has completed.
        }

        @Override
        protected void done() {
            // get() would be available here if you want to use it
            myButton.setText("Done working");
        }
    };
    myButton.setText("Working...");
    worker.execute();
}

The problem here is that your long running task is blocking the thread that would normally paint the GUI. 这里的问题是你的长时间运行任务阻塞了通常会绘制GUI的线程。

The usual way around this is to throw the longer running task off into another thread. 通常的做法是将更长时间运行的任务抛到另一个线程中。

This can be done fairly easily using a SwingWorker . 使用SwingWorker可以相当容易地完成此操作。

This question may provide some helpful information as well. 这个问题也可能提供一些有用的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM