You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时创建新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); 
    } 
}

方法二:用成员变量保存当前窗口(更高效)

如果你的场景里始终只会有一个窗口打开,那可以在类里定义一个成员变量记录当前打开的窗口,这样不用遍历所有组件,直接检查这个变量即可,效率更高。

步骤如下:

  1. 在类的成员变量区域添加:
private JInternalFrame currentInternalFrame;
  1. 修改按钮事件代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:35:08