Java Swing开发中如何实现变量的全局可访问?
现有代码核心问题
- 方法内的局部变量不允许加
public修饰符,语法错误 ActionListener的actionPerformed方法签名唯一,仅可接收ActionEvent类型单个参数,你为o按钮写的监听器方法属于自定义重载,不会被Swing事件体系触发,完全不生效- 监听器内部定义的
newText形参和外部变量重名,你修改的是局部形参,根本不会作用到外部变量 - 变量检查代码
if (!newText.equals(""))执行时机早于用户点击按钮的操作,永远拿不到用户选择后的值 - 匿名内部类修改外部局部变量要求变量为有效final,普通String类型变量无法被内部类修改
修复方案
可以用长度为1的数组包装String变量,利用数组引用不可变但元素可变的特性绕过匿名内部类的变量限制,同时修正所有语法和时序问题,修复后代码如下:
// 把newText用数组包装,定义在main方法里,去掉非法的public修饰 final String[] newText = {""}; // 假设a是你之前已经实例化的按钮 a.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { JFrame popup = new JFrame("Choose..."); popup.setSize(250,250); popup.setLayout(null); JButton o=new JButton("o"); o.setBounds(25,75,100,100); popup.add(o); o.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent ae) { // 修改数组的第一个元素,作用到外部变量 newText[0] = "O"; // 点击后直接修改a的文本,不用等到下次触发 a.setText(newText[0]); // 点击后关闭选择窗口 popup.dispose(); } }); JButton x=new JButton("x"); x.setBounds(125,75,100,100); popup.add(x); x.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent ae) { newText[0] = "X"; a.setText(newText[0]); popup.dispose(); } }); // 窗口最后再显示,避免组件渲染不全 popup.setVisible(true); } });
补充优化点
- 建议不要用
null布局,改用GridLayout等布局管理器适配不同分辨率 - 选择弹窗建议用
JDialog而不是JFrame,更符合模态弹窗的使用场景 - 所有重写的接口方法建议加
@Override注解,避免出现签名写错的低级错误
内容的提问来源于stack exchange,提问作者Allan Mauro
相关产品推荐
相关产品推荐

