如何在按下按钮之前暂停方法?

时间:2013-05-04 19:33:26

标签: java swing actionlistener

我正在设计一个包含多个组件的软件 - 每个组件都有自己的actionlistener。 举个例子,我有一个带有cardlayout的JPanel,可以容纳10张卡片 - 每张卡片都有自己的JPanel和用途。

一方面,有多个按钮,I.E。登录,退出,设置等

当我点击Login时,它将使用Login()方法切换到卡片到Login JPanel对象,我希望它等待按钮点击I.E.在继续Login()方法并设置当前用户之前登录,新用户或取消。

是否有方法暂停程序,直到单击其中一个按钮从中检索数据? (有点像JOptionPane.showInputMessage(null,“INPUT STRING”)如何等待你)

我的代码如下: 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来收听所有对象的按钮更容易吗?

有很多按钮......

注意:在我知道如何使其工作之前,有些方法是不完整的或测试方法......

2 个答案:

答案 0 :(得分:2)

您不希望在Swing GUI中使用线性控制台类型代码。相反,使用事件驱动的GUI程序,您将希望让用户交互更改程序的状态,然后让程序的行为取决于状态。例如,不要让登录方法暂停,让它做一些内务处理 - 更改程序的状态以准备接受登录尝试 - 然后在您计划“等待”的地方,退出登录方法。然后让登录的其余代码驻留在登录按钮的ActionListener中。

顺便说一下,你发布了 lot 代码,其中95%与你的问题无关,因此只会让我们分心,阻止我们阅读代码并理解你的问题的具体细节。将来,请考虑创建并发布sscce,您可以将代码压缩到仍然编译的最小位,没有与您的问题无关的额外代码,但仍然可以向我们展示您的问题。

答案 1 :(得分:0)

Swing框架的工作方式是您已经“等待”所有事情发生,并且只有在用户触发与您的侦听器相对应的操作后才会发生。

所以是的,基本上你只需要等待点击按钮。

但是: 设计响应式GUI意味着在执行10000次计算和1000万次SELECT语句之前,不要让用户在冻结的接口上等待10秒。因此,如果您的动作侦听器(或您所拥有的任何特定侦听器)必须执行重载计算,请在单独的Thread上执行,并告知用户任务是以某种方式完成的。