Java编译CalculatorKeypad提示找不到calculatorKeyPressed方法报错
CalculatorKeypad编译错误排查与修复
错误根因
该报错和Java版本兼容性无关,是自定义事件监听器的方法签名不匹配,外加代码存在一处隐藏的逻辑bug导致:
- 核心编译错误原因:代码中调用
ckl.calculatorKeyPressed(cke)时,传入参数为CalculatorKeypadEvent类型,但自定义的CalculatorKeypadListener接口中不存在签名完全匹配的方法——要么方法名拼写错误,要么入参类型不是CalculatorKeypadEvent,要么根本没有定义该方法,编译器无法找到匹配的方法引用就会抛出cannot find symbol错误。 - 隐藏逻辑bug:监听器列表
listeners = new Vector()被写在了遍历按钮的for循环内部,每创建一个按钮就会把监听器列表重置为空,后续注册的监听器会被覆盖,即使编译通过也无法正常响应按键事件。
最小改动修复方案(无需整体重写代码)
- 修正
CalculatorKeypadListener接口定义,确保方法签名和调用逻辑完全匹配,接口需继承Swing事件监听器的标准父类EventListener,代码放在同目录下的CalculatorKeypadListener.java文件中:
import java.util.EventListener; public interface CalculatorKeypadListener extends EventListener { // 方法名、入参类型必须和调用处完全一致 void calculatorKeyPressed(CalculatorKeypadEvent cke); }
如果已经编写过该接口,不需要重写,直接修改方法签名即可:保证方法名为
calculatorKeyPressed,仅接收一个CalculatorKeypadEvent类型的参数。
- 检查
CalculatorKeypadEvent自定义事件类,确保它继承自EventObject,构造方法匹配调用逻辑(两个入参:事件源Object、按键文本String),常量值和按钮标签一一对应,示例代码放在同目录下的CalculatorKeypadEvent.java文件中:
import java.util.EventObject; public class CalculatorKeypadEvent extends EventObject { // 常量值和按钮数组bLabels中的文本完全对应 public static final String MR = "MR"; public static final String MC = "MC"; public static final String MADD = "M+"; public static final String MSUBTRACT = "M-"; public static final String MS = "MS"; public static final String SQRT = "√"; public static final String C = "C"; public static final String AC = "AC"; public static final String POW = "x^y"; public static final String DIVIDE = "÷"; public static final String MULTIPLY = "×"; public static final String SUBTRACT = "-"; public static final String CK7 = "7"; public static final String CK8 = "8"; public static final String CK9 = "9"; public static final String SIGN = "+/-"; public static final String CK4 = "4"; public static final String CK5 = "5"; public static final String CK6 = "6"; public static final String ADD = "+"; public static final String CK1 = "1"; public static final String CK2 = "2"; public static final String CK3 = "3"; public static final String EQUALS = "="; public static final String CK0 = "0"; public static final String DECIMAL = "."; private final String keyText; public CalculatorKeypadEvent(Object source, String keyText) { super(source); this.keyText = keyText; } public String getKeyText() { return keyText; } }
- 修复
CalculatorKeypad类中的监听器列表初始化bug:- 把
listeners = new Vector()从for循环内部删除,移动到构造方法的最开头,保证监听器列表只初始化一次 - 为集合补上泛型避免类型转换异常:把成员变量声明
private Vector listeners;改为private Vector<CalculatorKeypadListener> listeners;,两个事件处理类中的迭代器改为Iterator<CalculatorKeypadListener> i = listeners.iterator();,删除遍历监听器时的强制类型转换代码
修复后的构造方法开头示例:
- 把
public CalculatorKeypad() { super(); // 构造方法初始化时就创建监听器列表,仅执行一次 listeners = new Vector<>(); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = gbc.weighty = 1.0; gbc.ipadx = gbc.ipady = 5; // ...... 其余原有布局、按钮创建代码不变 ...... for (int b = 0; b < buttons.length; b++) { buttons[b] = new JButton(bLabels[b]); // ...... 原有按钮布局约束、事件绑定代码不变 ...... add(buttons[b]); // 此处删除原来的 listeners = new Vector(); 代码 } }
完成以上修改后重新编译即可通过,原有业务逻辑不需要调整。
内容的提问来源于stack exchange,提问作者Robert Freeman
相关产品推荐
相关产品推荐

