如何在运行时创建新JInternalFrame时自动关闭旧窗口
问题
我通过JTextField获取JInternalFrame名称,在运行时创建其实例,目前每次输入不同窗口名称并点击按钮都会打开新的JInternalFrame。我希望打开新的JInternalFrame时,自动关闭之前已打开的旧窗口。我的按钮事件处理代码如下:
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) { String st = TextField.getText().toString(); // in TextField i enter the JInternal Frame Name String clazzname = "practice."+st; // practice is the package name try { JInternalFrame obj1 = (JInternalFrame) Class.forName( clazzname ).newInstance(); obj1.setVisible(true); jPanel1.add(obj1); // now in there i want that whenever i click the button , it check either is there any Jinternal frame is open already or not if yes then close the previously open JFrame } catch(Exception e) { System.out.println("error "+e); } }请问该如何实现这一需求?
解决方案
我给你两种实用的实现方式,你可以根据场景选择:
方法一:遍历容器关闭所有旧窗口
这种方式不需要额外的成员变量,直接在创建新窗口前,遍历jPanel1里的所有组件,找出已打开的JInternalFrame并关闭移除,确保每次只有新窗口存在。
修改后的代码如下:
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) { String st = TextField.getText().toString(); String clazzname = "practice."+st; // 先关闭并移除所有已打开的JInternalFrame Component[] components = jPanel1.getComponents(); for (Component comp : components) { if (comp instanceof JInternalFrame) { JInternalFrame oldFrame = (JInternalFrame) comp; oldFrame.dispose(); // 彻底关闭窗口释放资源 jPanel1.remove(oldFrame); // 从容器中移除组件 } } jPanel1.revalidate(); // 刷新容器布局 jPanel1.repaint(); // 重绘容器 try { JInternalFrame obj1 = (JInternalFrame) Class.forName(clazzname).newInstance(); obj1.setVisible(true); jPanel1.add(obj1); jPanel1.revalidate(); jPanel1.repaint(); } catch(Exception e) { System.out.println("error "+e); } }
方法二:用成员变量保存当前窗口(更高效)
如果你的场景里始终只会有一个窗口打开,那可以在类里定义一个成员变量记录当前打开的窗口,这样不用遍历所有组件,直接检查这个变量即可,效率更高。
步骤如下:
- 在类的成员变量区域添加:
private JInternalFrame currentInternalFrame;
- 修改按钮事件代码:
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) { String st = TextField.getText().toString(); String clazzname = "practice."+st; // 关闭当前已打开的窗口(如果存在) if (currentInternalFrame != null && !currentInternalFrame.isClosed()) { currentInternalFrame.dispose(); jPanel1.remove(currentInternalFrame); jPanel1.revalidate(); jPanel1.repaint(); } try { currentInternalFrame = (JInternalFrame) Class.forName(clazzname).newInstance(); currentInternalFrame.setVisible(true); jPanel1.add(currentInternalFrame); jPanel1.revalidate(); jPanel1.repaint(); } catch(Exception e) { System.out.println("error "+e); } }
关键注意点
- 每次添加或移除组件后,必须调用
revalidate()和repaint(),否则容器可能不会更新界面,导致旧窗口残留或者新窗口不显示。 - 使用
dispose()比单纯设置setVisible(false)更彻底,它会释放窗口占用的系统资源,避免内存浪费。
内容的提问来源于stack exchange,提问作者shaun Tait
相关产品推荐
相关产品推荐

