2013-05-04 134 views
3

我正在設計一個包含多個組件的軟件 - 每個組件都有自己的actionlistener。 舉個例子,我有一個帶有cardlayout的JPanel,它擁有10張卡片 - 每個卡片都有它自己的JPanel和用途。如何暫停方法,直到按下按鈕?

一方面,有多個按鈕,I.E.登錄,註銷,設置等

當我點擊登錄,它會切換到卡使用Login()方法登錄JPanel對象,我希望它等待按鈕點擊I.E.登錄,新用戶或取消,然後繼續登錄()方法並設置當前用戶。

是否有方法暫停程序,直到點擊其中一個按鈕以從中檢索數據? (有點像如何JOptionPane.showInputMessage(NULL, 「輸入字符串」)等待你)

我的代碼如下: FRAME:

/** 
* Frame design 
*/ 


public class Frame extends JFrame{ 
JPanel LeftSide, UpperRightSide; 
EmployeeAdder employAdd; 
ArrayList<ServiceView> serviceViewers; 
ChartViewer viewChart; 
PayByView viewPayBy; 
SettingsViewer viewSettings; 
LoginViewer viewLogin; 
CategoryView viewCategory; 
ServiceAdder serviceAdd; 
Directory directory; 
Employee currentEmployee; 
ChargeViewer viewCharge; 
JButton Login, Logout, Settings; 
CardLayout LeftCard,RightCard; 
String currentCard,currentRightCard; 
ButtonListen listen; 
public static String CARDCAT = "Category View"; 
public static String CARDPAY = "Pay By"; 
public static String CARDCHART = "Chart View"; 
public static String CARDLOGIN = "Log-in View"; 
public static String CARDSERVICEADD = "Service Adder"; 

Frame(){ 
    listen = new ButtonListen(); 
    //-------Current Card-------------------- 
    currentCard = CARDCAT; 
    currentRightCard = "CHARGE"; 
    //-----First Find Directory Folder------- 
    startDirectory(); 
    //-----User Interface-------------------- 
    //-------Left Side----------------------- 
    LeftSide = new JPanel(); 
    LeftCard = new CardLayout(); 
     LeftSide.setLayout(LeftCard); 
     viewPayBy = new PayByView(); 
     viewLogin = new LoginViewer(); 
     viewChart = new ChartViewer(); 
     viewCategory = new CategoryView(); 
     employAdd = new EmployeeAdder(); 
     serviceAdd = new ServiceAdder(); 
     LeftSide.add(viewCategory,"CAT"); 
     LeftSide.add(viewChart, "CHA"); 
     LeftSide.add(viewLogin,"LOG"); 
     LeftSide.add(viewPayBy,"PAY"); 
     LeftSide.add(employAdd,"EMA"); 
     LeftSide.add(serviceAdd,"SEA"); 
     LeftCard.show(LeftSide, "CAT"); 
     viewCategory.setEnabled(false); 
     LeftSide.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK),currentCard)); 
     serviceViewers = new ArrayList<ServiceView>(); 

    //--------Right Side--------------------- 
    JPanel RightSide = new JPanel(); 
     RightSide.setLayout(new BorderLayout()); 
     UpperRightSide = new JPanel(); 
     RightCard = new CardLayout(); 
     UpperRightSide.setLayout(RightCard); 
      viewSettings = new SettingsViewer(); 
      viewCharge = new ChargeViewer(); 
      viewCharge.setEnabled(false); 
      UpperRightSide.add(viewCharge,"CHARGE"); 
      UpperRightSide.add(viewSettings,"SETTINGS"); 
      UpperRightSide.setPreferredSize(new Dimension(350,500)); 
     RightSide.add(UpperRightSide,BorderLayout.NORTH); 
     //--------Buttons at the bottom Panel--- 
     JPanel Buttons = new JPanel(); 
      Buttons.setLayout(new GridLayout(3,1)); 
      Login = new JButton("LOG-IN"); 
       Login.addActionListener(listen); 
      Logout = new JButton("LOG OUT"); 
       Logout.addActionListener(listen); 
      Settings = new JButton("Settings"); 
       Settings.addActionListener(listen); 
      Buttons.add(Login); 
      Buttons.add(Logout); 
      Buttons.add(Settings); 
      Buttons.setPreferredSize(new Dimension(350,150)); 
     RightSide.add(Buttons,BorderLayout.SOUTH); 
     RightSide.setSize(new Dimension(400,200)); 
    //------Other Stuff-------------------------- 

    //-----add Panels---------------------------- 
     setLayout(new BorderLayout()); 
     add(LeftSide,BorderLayout.WEST); 
     add(RightSide,BorderLayout.EAST); 
} 


private void Login(){ 
    LeftCard.show(LeftSide, "LOG"); 

    //----I WANT IT TO WAIT HERE FOR AN ACTION------- 
    int clicked = viewLogin.getClicked(); 
     if (clicked==LoginViewer.NEWUSER){ 
      NewUser(); 
     }else if (clicked==LoginViewer.LOGIN){ 
      if (viewLogin.checkPassword()){ 
       currentEmployee = directory.getEmployee(viewLogin.getSelectedName()); 
       viewCategory.setEnabled(true); 
       viewCharge.setEnabled(true); 
       viewCharge.refreshName(currentEmployee.getName()); 
       LeftCard.show(LeftSide, "CAT"); 
      } 
     }else if (clicked==LoginViewer.CANCEL){ 
      LeftCard.show(LeftSide, "CAT"); 
     } 


} 




public class ButtonListen implements ActionListener{ 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (!viewLogin.isWaiting()){ 
     if (e.getSource()==Login){ 
      if (currentCard.equals(CARDLOGIN)){ 
       LeftCard.show(LeftSide,"CAT"); 
       currentCard = CARDCAT; 

      }else{ 
       Login(); 
       currentCard = CARDLOGIN; 
      } 
     }else{ 
      //Don't change the screen 
     } 
     } 

    } 

} 

} 

我對LoginViewer代碼:

public class LoginViewer extends JPanel{ 
JComboBox User; 
JPasswordField passField; 
JButton NewUser, Login, Cancel; 
Hashtable<String,String> namespass; //names and password 
private int clicked = -1; 
ButtonListen listen; 
public static int NEWUSER = 1; 
public static int LOGIN = 0; 
public static int CANCEL = 2; 
boolean waiting; 

LoginViewer(){ 
    waiting = false; 
    //--------------------------------------- 
    setPreferredSize(new Dimension(100,100)); 
    listen = new ButtonListen(); 
    namespass = new Hashtable<String,String>(); 
    //----------Panel Design------------------- 
    JPanel Center = new JPanel(); 
     Center.setLayout(new GridLayout(3,3)); 
    User = new JComboBox(); 
    passField = new JPasswordField(); 
    NewUser = new JButton("New User"); 
     NewUser.addActionListener(listen); 
    Login = new JButton("Login"); 
     Login.addActionListener(listen); 
    Cancel = new JButton("Cancel"); 
     Cancel.addActionListener(listen); 
    Center.add(new JLabel("Choose User")); 
    Center.add(User); 
    Center.add(new JLabel("")); 
    Center.add(new JLabel("Type Password")); 
    Center.add(passField); 
    Center.add(new JLabel("")); 
    Center.add(Login); 
    Center.add(NewUser); 
    Center.add(Cancel); 
    Center.setPreferredSize(new Dimension(300,300)); 
    Center.setMaximumSize(new Dimension(100,100)); 
    Center.setAlignmentX(CENTER_ALIGNMENT); 
    setAlignmentX(CENTER_ALIGNMENT); 
    setLayout(new BoxLayout(this,BoxLayout.X_AXIS)); 
    add(Box.createHorizontalGlue()); 
    add(Center); 
    add(Box.createHorizontalGlue()); 
} 


public void uploadUserNames(Hashtable<String,String> names){ 
    namespass.clear(); 
    namespass.putAll(names); 
    User.removeAllItems(); 
    Enumeration<String> name = names.keys(); 
    while (name.hasMoreElements()){ 
     User.addItem(name.nextElement()); 
    } 
} 

public boolean checkPassword(){ 
    boolean value = false; 
    String key = User.getSelectedItem().toString(); 
    if (passField.getPassword().length==4){ 
     if (namespass.get(key).equals(String.valueOf(passField.getPassword()))){ 
      value = true; 
     } 
    } 
    return value; 
} 

public String getSelectedName(){ 
    return User.getSelectedItem().toString(); 
} 

public boolean isWaiting(){ 
    return waiting; 
} 

public int getClicked(){ 
    waiting = true; 
    return clicked; 
} 

public class ButtonListen implements ActionListener{ 
    @Override 
    public void actionPerformed(ActionEvent e) { 

     waiting = false; 
     if (e.getSource()==NewUser){ 
      clicked = 1; 
     }else if (e.getSource()==Login){ 
      clicked = 0; 
     }else if (e.getSource()==Cancel){ 
      clicked = 2; 
     } 

    } 

} 
} 

或者僅僅使用actionlistener來聽取所有對象的按鈕更容易?

有按鈕的很多...

注意:有些方法是不完整的或測試方法,直到我知道如何使它工作...

回答

0

了Swing框架的工作方式是您已經「等待」所有事情發生,並且只有當用戶觸發與您的監聽器相對應的操作時纔會發生。

所以是的,基本上你只需要等待按鈕被點擊。

然而: 設計響應式圖形用戶界面意味着您不會讓用戶在凍結的界面上等待10秒,直到您執行10000次計算和1000萬次SELECT語句。因此,如果您的動作監聽器(或您擁有的任何特定監聽器)必須執行重型計算,請在單獨的Thread上執行這些計算,並通知用戶任務是否以某種方式完成。

2

您不想在Swing GUI中使用線性控制檯類型的代碼。相反,使用事件驅動的GUI程序,您將希望用戶交互改變程序的狀態,然後讓程序的行爲取決於狀態。例如,不要讓登錄方法暫停,讓它做一些內務處理 - 更改程序的狀態以準備接受登錄嘗試 - 然後在計劃「等待」的位置,退出登錄方法。然後讓登錄代碼的其餘部分駐留在登錄按鈕的ActionListener中。

順便說一下,您已經發布了很多的代碼,其中95%與您的問題無關,因此僅作爲分散注意力,妨礙我們閱讀代碼並理解問題的具體細節。在將來,請考慮創建併發布sscce,將您的代碼壓縮到仍然編譯的最小位,並且沒有額外的代碼與您的問題無關,但仍然可以爲您解決問題。

相關問題