Java:在等待另一个线程完成时更新 UI [英] Java: Updating UI while waiting for another thread to finish

查看:29
本文介绍了Java:在等待另一个线程完成时更新 UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 Java Swing 登录面板.当用户单击登录"按钮时,会发生广泛的 DB 通信.我有一个想法,将那个 db 通信放入另一个线程(该 db 通信用于填充一些哈希映射和单例).将该通信放入单独的线程后,db 繁重的工作会在用户键入它的 uname 和密码时发生.当用户点击登录"按钮时,代码将等待繁重"线程加入,然后继续.

I have some Java Swing login panel. When user click "login" button, extensive DB communication takes place. I got an idea to put that db communication into another thread (that db communication is used for filling some hash maps and singletons). After putting that communication into separate thread, db heavy lifting takes place while user is typing it's uname and password. When user clicks "login" button, than code will wait for "heavy lifting" thread to join, and then proceed.

问题是当我的代码在等待 db 线程加入时,似乎无法进行 UI 更新.我不认为我可以使用 SwingWorker 进行数据库通信,因为用户可以随时单击登录"按钮,甚至在 SW 完成之前我也没有办法加入 SwingWorker(数据库通信必须在实际登录之前进行).

The problem is that while my code is waiting for db thread to join, it seems that no UI updates can be done. I don't think i can use SwingWorker for db communication because user can click "login" button any time, even before SW would finish and i don't have a way to join SwingWorker (db communication has to take place BEFORE actual login).

有没有办法在等待另一个线程加入时启用 Swing ui 更新?我错过了什么吗?

Is there a way to enable Swing ui updates while waiting for another thread to join? Am i missing something?

推荐答案

简单地放两个标志,在两个操作(数据库通信和用户点击)结束时,调用相同的方法并在那里验证两个标志的状态.如果您想阻止用户输入,可以在模态对话框中显示进度条:

Simply put two flags and at the end of both operations (DB-communication and user click), call the same method and verify there the state of the two flags. Possibly show a progress bar in a modal dialog if you want to block user input:

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UnsupportedLookAndFeelException;

public class TestThreadJoin {

    private boolean dbWorkDone = false;
    private boolean credentialsProvided = false;
    private JTextField loginTF;
    private JTextField passwordTF;

    protected void initUI() {
        final JFrame frame = new JFrame(TestThreadJoin.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new GridBagLayout());
        JLabel login = new JLabel("Login: ");
        JLabel password = new JLabel("Password: ");
        loginTF = new JTextField(20);
        passwordTF = new JPasswordField(20);
        GridBagConstraints gbc = new GridBagConstraints();
        panel.add(login, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        panel.add(loginTF, gbc);
        gbc.gridwidth = 1;
        panel.add(password, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        panel.add(passwordTF, gbc);
        JButton loginButton = new JButton("Login");
        loginButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                credentialsProvided = true;
                proceed();
            }
        });
        frame.add(panel);
        frame.add(loginButton, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

            @Override
            protected Void doInBackground() throws Exception {
                Thread.sleep(10000);
                return null;
            }

            @Override
            protected void done() {
                super.done();
                dbWorkDone = true;
                proceed();
            }
        };
        worker.execute();
    }

    protected void proceed() {
        if (credentialsProvided && dbWorkDone) {
            System.err.println("Continuing ");
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestThreadJoin().initUI();
            }
        });
    }
}

这篇关于Java:在等待另一个线程完成时更新 UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆