在Java Swing中使用线程

时间:2014-03-25 06:03:46

标签: java multithreading swing netbeans

我正在使用Java的swing库构建用户界面,我遇到了一个问题。

在使用long方法更新文本区域时,方法运行时会暂停,然后文本区域会立即更新,而不是一次更新。

我设法使用新线程以下列方式解决问题:

private void jButtonActionPerformed(java.awt.event.ActionEvent evt) {
    Thread x = new Thread() {public void run() {
    // do things that update a text area
    }}; x.start();
}

这非常适合将文本区域更新为小块,而不是一次性更新。

但是,唯一的问题是此方法只能调用一次或Java崩溃。我读到这只与能够一次创建线程有关。如何修改代码以保持所需的功能?

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

好吧,我怀疑你因为Thread创建而导致代码崩溃,因为每次调用该方法时,你都会创建一个新的Thread(你不能重启一个已经启动的Thread的现有实例(即使它已完成或未完成)),可能的原因是您获得并发修改异常,因为Swing不是Thread安全的..

最简单的解决方案可能是使用SwingWorker,这将允许您在后台执行长时间运行的任务,但提供易于使用的功能,通过publish安全地更新用户界面,processdone方法。

为防止可能出现的问题,您可能还会考虑在加载操作完成之前禁用该按钮,这会阻止人们将按钮混合,从而产生多个后台进程......

答案 1 :(得分:0)

你可以创建Thread的新对象并覆盖所有方法意味着runnable。

new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("Executed..*****");
            }
        }).start();

试试这个。

答案 2 :(得分:-1)

为了便于比较,以下是使用SwingUtilities.invokeLater的示例。我回应了MadProgrammer的建议,从长远来看,了解SwingWorker 更有益,并提供更好的变量处理。

newGame.addActionListener(new ActionListener() {
    @Override
        public void actionPerformed(final ActionEvent arg0) {
            panelList.get("newGame").setEnabled(false);     
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    // this is where the heavy processing occurs
                    newGameButton();
                    // re-enables the button afterwards
                    panelList.get("newGame").setEnabled(true);
                }
            });             
        }
});

此外,一旦您的代码工作得更好,您可以研究优化更新速度的方法(即使在处理Swing对象时)。上面的电话过去常常挂了一秒左右,但我已经延迟到大约50 - 100ms左右,并对模型进行了进一步的处理:)