import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.Thread;
public class Lthread extends JPanel{
private JTextField acctTF;
private JTextField pinTF;
private JButton cancelB;
private JLabel balanceL;
private JButton searchB;
public Lthread() {
buildGUI();
hookupEvents();
}
private void buildGUI() {
JLabel acctL=new JLabel("Account Number:");
JLabel pinL=new JLabel("PIN:");
acctTF=new JTextField(12);
pinTF=new JTextField(4);
JPanel dataEntryP=new JPanel();
dataEntryP.setLayout(new FlowLayout(FlowLayout.CENTER));
dataEntryP.add(acctL);
dataEntryP.add(acctTF);
dataEntryP.add(pinL);
dataEntryP.add(pinTF);
searchB=new JButton("Search");
cancelB=new JButton("Cancel Search");
cancelB.setEnabled(false);
JPanel innerButtonP=new JPanel();
innerButtonP.setLayout(new GridLayout(1,-1,5,5));
innerButtonP.add(searchB);
innerButtonP.add(cancelB);
JPanel buttonP=new JPanel();
buttonP.setLayout(new FlowLayout(FlowLayout.CENTER));
buttonP.add(innerButtonP);
JLabel balancePrefixL=new JLabel("Account Balance: ");
balanceL=new JLabel("BALANCE UNKNOWN");
JPanel balanceP=new JPanel();
balanceP.setLayout(new FlowLayout(FlowLayout.CENTER));
balanceP.add(balanceL);
JPanel northP=new JPanel();
northP.setLayout(new GridLayout(-1,1,5,5));
northP.add(dataEntryP);
northP.add(buttonP);
northP.add(balanceP);
setLayout(new BorderLayout());
add(northP,BorderLayout.NORTH);
}
private void hookupEvents() {
searchB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
search(ae);
}
});
cancelB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
cancelSearch(ae);
}
});
}
private void search(ActionEvent ae) {
searchB.setEnabled(false);
cancelB.setEnabled(true);
balanceL.setText("SEARCHING...");
String acct=acctTF.getText();
String pin=pinTF.getText();
String bal=lookupBalance(acct,pin);
setBalance(bal);
}
private String lookupBalance(String acct,String pin) {
try {
Thread.sleep(5000);
return "1,234.56";
} catch(Exception exc) {
return "search cancelled";
}
}
private void setBalance(String newBalance) {
balanceL.setText(newBalance);
cancelB.setEnabled(false);
searchB.setEnabled(true);
}
private void cancelSearch(ActionEvent ae) {
System.out.println("in cancelSearch");
}
public static void main(String args[]) {
Lthread Lt=new Lthread();
JFrame f=new JFrame("Balance Lookup-Can't cancel");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setContentPane(Lt);
f.setSize(400,150);
f.setVisible(true);
}
}
一旦我们点击搜索,取消就应该启用,但它没有启用,为什么?
另一件事是标签balanceL
应显示SEARCHING。单击搜索但也不显示。为什么呢?
答案 0 :(得分:7)
你正在UI线程中完成所有工作(好吧,睡觉)。这将阻止UI的所有其余部分更新,处理事件等。
您应该将工作(搜索/休眠)卸载到后台线程,使用SwingWorker
将任何UI调用编组回UI线程。 (您无法从非UI线程触摸UI组件。)
如果您需要更多信息,搜索“swing threads”会为教程等提供加载命中。特别是,您可能希望阅读Swing中的Java Tutorial trail线程。
答案 1 :(得分:1)
因为在search()函数中阻止了eventdispatcher线程。它永远不应该被阻止。使用SwingUtilities.invokeLater()
。
您的问题将搜索方法更改为
private void search(ActionEvent ae) {
searchB.setEnabled(false);
cancelB.setEnabled(true);
balanceL.setText("SEARCHING...");
final String acct=acctTF.getText();
final String pin=pinTF.getText();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String bal=lookupBalance(acct,pin);
setBalance(bal);
}
});
}