3

我正在设计一个包含多个组件的软件——每个组件都有自己的 actionlistener。例如,我有一个 JPanel,其卡片布局可容纳 10 张卡片——每张卡片都有自己的 JPanel 和用途。

一侧有多个按钮,IE登录、注销、设置等。

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

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

我的代码如下:框架:

/**
 * 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;
        }

    }

}
}

还是只使用一个动作监听器来监听所有对象的按钮更容易?

有很多按钮...

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

4

2 回答 2

2

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

顺便说一句,您发布了很多代码,其中 95% 与您的问题无关,因此只会分散我们的注意力,并阻止我们阅读代码并了解您的问题的细节。将来,考虑创建和发布一个sscce,在其中将代码压缩成仍可编译的最小位,没有与您的问题无关的额外代码,但仍向我们展示您的问题。

于 2013-05-04T19:48:05.243 回答
0

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

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

但是:设计响应式 GUI 意味着您不会让用户在冻结的界面上等待 10 秒,直到您完成 10000 次计算和 1000 万次 SELECT 语句。因此,如果您的动作侦听器(或您拥有的任何特定侦听器)必须执行繁重的计算,请在单独Thread的 .

于 2013-05-04T19:38:00.540 回答