java - 在一个线程的 JDialog 中显示一个不确定的进度条,并同时在另一个线程中运行一个任务

标签 java multithreading swing concurrency runnable

当用户单击按钮时,将运行大约 10 秒的长任务。在此期间我想向用户显示一个进度条。但是主线程必须等待工作线程完成,因为工作线程将设置主线程将使用的变量。如果我不等待工作线程,我将在使用变量时得到一个 NullPointerException。所以工作线程结束后,我也会关闭进度条对话框。

当我使用 join() 等待工作线程时,进度条对话框显示(有趣的是没有进度条)并卡在那里。

Thread runnable = new Thread() {

    public void run() {
        try {
            System.out.println("thread basladi");
            threadAddSlaveReturnMessage = request.addSlave(
                ipField.getText(), passField.getText(), 
                nicknameField.getText());
            System.out.println("thread bitti");

        } catch (LMCTagNotFoundException e) {
            e.printStackTrace();
        }

    }
};

Thread runnable_progress = new Thread() {

    public void run() {

        JTextArea msgLabel;
        JDialog dialog;
        JProgressBar progressBar;
        final int MAXIMUM = 100;
        JPanel panel;

        progressBar = new JProgressBar(0, MAXIMUM);
        progressBar.setIndeterminate(true);
        msgLabel = new JTextArea("deneme");
        msgLabel.setEditable(false);


        panel = new JPanel(new BorderLayout(5, 5));
        panel.add(msgLabel, BorderLayout.PAGE_START);
        panel.add(progressBar, BorderLayout.CENTER);
        panel.setBorder(BorderFactory.createEmptyBorder(11, 11, 11, 11));

        dialog = new JDialog(Frame.getFrames()[0], "baslik", true);
        dialog.getContentPane().add(panel);
        dialog.setResizable(false);
        dialog.pack();
        dialog.setSize(500, dialog.getHeight());
        dialog.setLocationRelativeTo(null);
        dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        dialog.setAlwaysOnTop(false);
        dialog.setVisible(true);
        msgLabel.setBackground(panel.getBackground());
    }
};

runnable.start();
System.out.println("runnable start");
runnable_progress.start();
System.out.println("progress start");
runnable.join();
System.out.println("runnable join");
runnable_progress.join();
System.out.println("progress join");


if (threadAddSlaveReturnMessage.equalsIgnoreCase("OK")) {
    fillInventoryTable(inventoryTable);
    JOptionPane.showMessageDialog(this, messages.getString("centrum.addslavepanel.SUCCESS"), null, JOptionPane.INFORMATION_MESSAGE);
}

"progress join"

不打印。

最佳答案

您可以使用 SwingWorker这里。一个简短的例子:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.godel.nio;

import java.awt.BorderLayout;
import java.util.List;
import javax.swing.*;

/**
 *
 * @author internet_2
 */
public class Test {

    public static void main(String[] args) {
        new Test().doJob();
    }

    public void doJob() {

        JTextArea msgLabel;
        JProgressBar progressBar;
        final int MAXIMUM = 100;
        JPanel panel;

        progressBar = new JProgressBar(0, MAXIMUM);
        progressBar.setIndeterminate(true);
        msgLabel = new JTextArea("deneme");
        msgLabel.setEditable(false);

        panel = new JPanel(new BorderLayout(5, 5));
        panel.add(msgLabel, BorderLayout.PAGE_START);
        panel.add(progressBar, BorderLayout.CENTER);
        panel.setBorder(BorderFactory.createEmptyBorder(11, 11, 11, 11));

        final JDialog dialog = new JDialog();
        dialog.getContentPane().add(panel);
        dialog.setResizable(false);
        dialog.pack();
        dialog.setSize(500, dialog.getHeight());
        dialog.setLocationRelativeTo(null);
        dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        dialog.setAlwaysOnTop(false);
        dialog.setVisible(true);
        msgLabel.setBackground(panel.getBackground());

        SwingWorker worker = new SwingWorker() {

            @Override
            protected void done() {
                // Close the dialog
                dialog.dispose();
            }

            @Override
            protected void process(List chunks) {
                // Here you can process the result of "doInBackGround()"
                // Set a variable in the dialog or etc.
            }

            @Override
            protected Object doInBackground() throws Exception {
                // Do the long running task here
                // Call "publish()" to pass the data to "process()"
                // return something meaningful
                return null;
            }
        };

        worker.execute();

    }
}

编辑:“publish( )”应该在“doInBackground()”中调用以将数据传递给“process()”。

关于java - 在一个线程的 JDialog 中显示一个不确定的进度条,并同时在另一个线程中运行一个任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12105182/

相关文章:

java - JPA 中的多对多查询

java - 如何清理我的代码

java - 在 Maven 中仅编译选定的文件

java - 在背景框架上使用 Java KeyListener

java - 在两个 JPanel 上设置组件

java - 不可写属性异常 : Bean property 'dataSource' is not writable or has an invalid setter method

java - 正确使用ProgressMonitorDialog的取消按钮、中断线程、显示进度

java - System.nanoTime 与 System.currentTimeMillis

java - android服务中的onResume

java - JInternalFrames 中的 JScrollPanes 用于从右到左组件方向 - Java bug?