如何向跨类创建的无命名JFrame动态添加JLabel?
问题描述
我需要通过按钮点击,向由其他类创建的无命名JFrame中添加JLabel,但遇到了问题。例如,我无法让按钮向指定的无命名JFrame添加标签,因为只能使用this.add,但由于不在JFrame的构造方法中,该方式无法生效。
具体场景:初始JFrame含通用信息和按钮,点击按钮会销毁当前JFrame并打开另一个类中的新JFrame,但无法在JFrame创建后向其添加标签,因为JFrame的引用不通用。
目标JFrame代码(GameWindow类构造方法)
GameWindow() { label.setText("Money: "+ userMoney); BButton = myButton("Balooga: 20$", 50, 50, 125, 50); BButton.addActionListener(this); CButton = myButton("Canca", 225, 50, 125, 50); CButton.addActionListener(this); this.getContentPane().setBackground(new Color(102,102,255)); this.setTitle("Gambling"); this.setResizable(false); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLayout(null); this.setSize(1920,1080); this.setVisible(true); this.add(BButton); this.add(CButton); this.add(label); this.add(caseQuestion); }
按钮事件处理代码
public void actionPerformed(ActionEvent e) { if(e.getSource()==BButton) { userMoney = userMoney - 20; label.setText("Money: "+ userMoney); JLabel itemLabel = BaloogaCase.bCase();//THIS IS THE LABEL I'M TRYING TO ADD VIA BUTTON TOUCH } else if(e.getSource()==CButton) { label.setText("Money: "+ userMoney); } }
解决方案
方法1:直接在事件方法中添加组件并刷新窗口
因为actionPerformed方法属于GameWindow类(该类实现了ActionListener),所以this依然指向当前GameWindow实例,直接调用getContentPane().add()即可,之后必须刷新窗口布局才能让新组件显示:
public void actionPerformed(ActionEvent e) { if(e.getSource()==BButton) { userMoney = userMoney - 20; label.setText("Money: "+ userMoney); JLabel itemLabel = BaloogaCase.bCase(); // 向窗口内容面板添加标签 this.getContentPane().add(itemLabel); // 因为用了null布局,必须手动设置组件位置和大小 itemLabel.setBounds(150, 150, 200, 30); // 替换为你需要的坐标和尺寸 // 刷新窗口布局和绘制 this.validate(); this.repaint(); } else if(e.getSource()==CButton) { label.setText("Money: "+ userMoney); } }
方法2:给GameWindow添加专用的组件添加方法
在GameWindow类中新增一个公开方法,封装组件添加和布局刷新的逻辑,让代码更清晰:
// 在GameWindow类中添加 public void addCustomComponent(Component comp, int x, int y, int width, int height) { comp.setBounds(x, y, width, height); this.getContentPane().add(comp); this.validate(); this.repaint(); }
然后在事件方法中调用:
if(e.getSource()==BButton) { userMoney = userMoney - 20; label.setText("Money: "+ userMoney); JLabel itemLabel = BaloogaCase.bCase(); addCustomComponent(itemLabel, 150, 150, 200, 30); }
方法3:保存全局实例实现跨类调用
如果需要从其他类向这个GameWindow添加组件,可以在GameWindow类中保存静态实例引用:
// 在GameWindow类中添加 private static GameWindow currentWindow; GameWindow() { currentWindow = this; // 构造时保存当前实例 // 原构造方法的其他代码... } // 提供静态方法获取实例 public static GameWindow getCurrentWindow() { return currentWindow; }
之后在任意类中都可以这样调用:
GameWindow.getCurrentWindow().addCustomComponent(itemLabel, 150, 150, 200, 30);
内容的提问来源于stack exchange,提问作者Owen Goodman
相关产品推荐
相关产品推荐

