取消按钮永远不会启用

时间:2011-04-01 15:06:32

标签: java swing

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。单击搜索但也不显示。为什么呢?

2 个答案:

答案 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);
            }
        });
    }