如何访问JMenu上的项目并与Action Listener一起使用?

时间:2018-10-26 12:23:44

标签: java swing

我的Java代码遇到了一个问题,其中动作监听器不起作用。我应该创建一个GUI,该GUI的菜单栏在单击这些按钮时执行一些操作。例如,如果用户在“餐食”菜单上选择一个选项,并在“宿舍”菜单上选择一个选项,则应计算每个项目已分配的值,然后将其输出到总成本JField。

enter image description here

enter image description here

这是我的代码的样子

private class MenuActionListener implements ActionListener {

//The user has chosen a new dorm or new meal plan
//Get the choices from the dormBox and mealBox and recalculate charges
//Display the new charges in the totalField

  public void actionPerformed(ActionEvent arg0) {
    //Get the choices from the dormBox and mealBox
    int totalCost;
    int dormIndex = menu.getComponentCount();
    int dormCost=dormCosts[dormIndex];
    int mealIndex=dorm.getComponentCount();
    int mealCost=mealCosts[mealIndex];
    //Calculate the charges
    totalCost=dormCost+mealCost;

    //Display the new charges 
    totalField.setText("$"+Integer.toString(totalCost));
  }
}

我应该如何使其正常工作??

2 个答案:

答案 0 :(得分:0)

恐怕这种方法行不通。您不能从ActionListener内部访问UI组件。

您可能想尝试向JMenuItems添加匿名侦听器,以更新类的属性以执行计算。

编辑:查看Holger的答案以找到一个不错的解决方案:)

这样,您可以访问外部组件或更好地将其委派给模型类。 看到这里:https://www.codejava.net/java-core/the-java-language/java-8-lambda-listener-example

答案 1 :(得分:0)

不要编写试图猜测要使用的正确值的侦听器。将侦听器注册到特定组件时,您已经知道它是哪个组件,因此您可以注册侦听器以针对该组件执行正确的操作。

在这种情况下,当成本存储在一个数组中时,还应该有一个用于构建菜单项的相应数组,从而可以构造菜单项和相应的侦听器。

例如

static String[] dorms  = { "Allen Hall", "Pike Hall", "Farthing Hall" };
static int[] dormCosts = {           10,          20,              40 };
static String[] meals  = { "7 / weak", "14 / week", "unlimited" };
static int[] mealCosts = {          5,           8,          15 };
JTextField totalField = new JTextField();
int dormCost = dormCosts[0];
int mealCost = mealCosts[0];

void updateTotalCosts() {
    int totalCost = dormCost + mealCost; // really plus not multiply?
    totalField.setText("$" + totalCost);
}

JMenuBar buildMenu() {
    final JMenuBar mb = new JMenuBar();
    JMenu menu = mb.add(new JMenu("Meals"));
    for(int ix = 0; ix < meals.length; ix++) {
        int currMealCosts = mealCosts[ix];
        menu.add(meals[ix]).addActionListener(ev -> {
            mealCost = currMealCosts;
            updateTotalCosts();
        });
    }
    menu = mb.add(new JMenu("Dorms"));
    for(int ix = 0; ix < dorms.length; ix++) {
        int currDormCosts = dormCosts[ix];
        menu.add(dorms[ix]).addActionListener(ev -> {
            dormCost = currDormCosts;
            updateTotalCosts();
        });
    }
    return mb;
}

在每个循环迭代中,我们都已经知道要创建的项目以及与之相关的费用,因此我们将使用这些费用来注册侦听器。

如果您不能使用lambda表达式,则Java 8之前版本的构造方法看起来像

JMenuBar buildMenu() {
    final JMenuBar mb = new JMenuBar();
    JMenu menu = mb.add(new JMenu("Meals"));
    for(int ix = 0; ix < meals.length; ix++) {
        final int currMealCosts = mealCosts[ix];
        menu.add(meals[ix]).addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ev) {
                mealCost = currMealCosts;
                updateTotalCosts();
            }
        });
    }
    menu = mb.add(new JMenu("Dorms"));
    for(int ix = 0; ix < dorms.length; ix++) {
        final int currDormCosts = dormCosts[ix];
        menu.add(dorms[ix]).addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ev) {
                dormCost = currDormCosts;
                updateTotalCosts();
            }
        });
    }
    return mb;
}