加载子面板时,Swing Parent JFrame/JPanel无法使用/可单击 [英] Swing Parent JFrame/JPanel unusable/clickable while child panel is loaded
问题描述
当用户单击addUser
按钮时,我正在加载JFrame
AdminFrame
(上面有添加用户和addLocation
按钮),新的JFrame
addUser
会加载并获取用户信息.当信息提交到服务器时,需要花费一些时间(因为服务器是基于Web的),在这段时间内,我的两个面板都卡住了...我要使AdminFrame
clickable 和可用,以便用户可以添加新用户或添加位置...
这是我的AdminPanel
添加按钮的模板代码...不写原始代码,因为原始代码太乱了..
I am loading a JFrame
AdminFrame
(with add user and addLocation
button on it) when the user click's addUser
button the new JFrame
addUser
loads and takes user information. When the information is submitted to server it takes some time(because server is web-based) during that time both of my panels got stuck...what i want is to make AdminFrame
clickable and use-able so that user can add new user or can add location...
Here is my AdminPanel
s add button's template code...not writing original code because original code to is too messy..
public class AdminPanel extends JFrame{
public AdminPanel(){
Initalize();//Do Initalize Stuff
}
public void addBtnActionPerformed(){
//load Child Form
}
}//End of class
现在这是我的AddUser面板的adduser按钮Templete代码Orignal代码太混乱了..
Now here is my AddUser Panel's adduser button Templete code Orignal code to too messay..
public class AddUser extends JFrame{
public AddUser(){
Initalize();//Do Initalize Stuff
}
public void addUserBtnActionPerformed(){
/*
take user's form input values make a http request send to server
get response...now what i have to do here to make parent form clickable?
*/
}
}//End of class
推荐答案
您需要使用SwingWorker将繁重/冗长的操作分派到另一个线程中,以允许UI-Thread(EDT)响应事件.
You need to use a SwingWorker to dispatch your heavy/lengthy operations into another Thread, allowing the UI-Thread(EDT) to respond to events.
这是一个非常简单的代码,显示了如何使用SwingWorker(此处与服务器的连接由一堆Thread.sleep()
模拟):
Here is a very simple code showing how SwingWorker can be used (connection to a server is here emulated by a bunch of Thread.sleep()
):
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestJFrame implements ActionListener {
private JProgressBar progress;
private JButton startButton;
private JButton testButton;
private SwingWorker<Void, Integer> worker;
public void initUI() {
JFrame frame = new JFrame(TestJFrame.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progress = new JProgressBar(0, 100);
startButton = new JButton("Start work");
testButton = new JButton("Test me while work is in progress");
startButton.addActionListener(this);
testButton.addActionListener(this);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(startButton);
buttonPanel.add(testButton);
frame.add(buttonPanel, BorderLayout.NORTH);
frame.add(progress, BorderLayout.SOUTH);
frame.setSize(600, 400);
frame.setVisible(true);
}
private void showTestDialog() {
if (worker != null) {
JOptionPane.showMessageDialog(testButton, "You made a test. See how I still respond while heavy job is in progress?");
} else {
JOptionPane.showMessageDialog(testButton,
"You made a test, but no job is progress. Hit the \"Start work\" button and hit me again after.");
}
}
private void startWork() {
if (worker != null) {
return;
}
startButton.setEnabled(false);
worker = new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
// Outside EDT, we cannot modify the UI, but we can perform lengthy operations
// without blocking the UI
for (int i = 0; i < 10; i++) {
publish(i * 10);
Thread.sleep(1000);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
// Inside EDT, here we can modify the UI
super.process(chunks);
// We only care about the last one
progress.setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
// Inside EDT, he we can modify the UI
super.done();
progress.setValue(100);
startButton.setEnabled(true);
worker = null;
}
};
worker.execute();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
startWork();
} else if (e.getSource() == testButton) {
showTestDialog();
}
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestJFrame().initUI();
}
});
}
}
这篇关于加载子面板时,Swing Parent JFrame/JPanel无法使用/可单击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!