我的Java代码遇到了一个问题,其中动作监听器不起作用。我应该创建一个GUI,该GUI的菜单栏在单击这些按钮时执行一些操作。例如,如果用户在“餐食”菜单上选择一个选项,并在“宿舍”菜单上选择一个选项,则应计算每个项目已分配的值,然后将其输出到总成本JField。
这是我的代码的样子
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));
}
}
我应该如何使其正常工作??
答案 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;
}