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

JInternalFrame监听器实现疑惑:为何需用ComponentAdapter而非InternalFrameAdapter?

解决方案:JInternalFrame创建时调整尺寸的两种实现方式

你的核心需求是点击「New IFrame>Open」创建内部窗体时,直接调整窗体及按钮的尺寸。当前代码使用ComponentAdapter只能监听窗体拖动 resize 的事件,和需求不匹配,以下是两种更贴合需求的实现方案:

方案1:创建时直接设置目标尺寸(最简实现)

不需要依赖监听器,在创建内部窗体和组件的代码里直接设置你想要的尺寸即可:

from javax.swing import JButton, JFrame, JPanel,JMenuBar,JMenu,JMenuItem,JInternalFrame,JDesktopPane,JScrollPane
from java.awt.event import ComponentListener,ComponentAdapter
from javax.swing.event import InternalFrameListener,InternalFrameAdapter

class TestApp(JFrame):
    def __init__(self):
        JFrame.__init__(self,'Main Window',size=(500, 500),defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
        self.createDesktop()
        self.createMenus()

    def createDesktop(self):
        self.desktop = JDesktopPane()
        self.contentPane.add(JScrollPane(self.desktop))

    def createMenus(self):
        bar = JMenuBar()
        self.setJMenuBar(bar)     
        f = JMenu("New IFrame")
        newfile = JMenuItem("Open",actionPerformed = self.createInternalFrame)
        f.add(newfile)
        bar.add(f)
 
    def createInternalFrame(self, event):
        # 创建时直接设置窗体目标尺寸
        iframe     = JInternalFrame('InternalFrame', 1, 1, 1, 1, size=(450, 450), visible=1)
        iframe.setLayout(None)
        c= JPanel()
        # 设置按钮容器的目标位置和尺寸
        c.setBounds(20,20,70,70)
        a = JButton("Report",actionPerformed=self.onClick)
        c.add(a)
        iframe.add(c)
        self.desktop.add(iframe)
        
    def onClick(self,widget):
        print 'Report'
        
if __name__ == '__main__':
    a = TestApp()
    a.setLocation(100, 100)
    a.show()

方案2:用InternalFrameAdapter监听窗体打开事件

如果需要在窗体完全初始化完成后再调整尺寸(比如依赖窗体的内部状态),可以使用InternalFrameAdapter的internalFrameOpened方法,这是内部窗体创建并打开时触发的专属事件:

from javax.swing import JButton, JFrame, JPanel,JMenuBar,JMenu,JMenuItem,JInternalFrame,JDesktopPane,JScrollPane
from java.awt.event import ComponentListener,ComponentAdapter
from javax.swing.event import InternalFrameListener,InternalFrameAdapter

class TestApp(JFrame):
    def __init__(self):
        JFrame.__init__(self,'Main Window',size=(500, 500),defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
        self.createDesktop()
        self.createMenus()

    def createDesktop(self):
        self.desktop = JDesktopPane()
        self.contentPane.add(JScrollPane(self.desktop))

    def createMenus(self):
        bar = JMenuBar()
        self.setJMenuBar(bar)     
        f = JMenu("New IFrame")
        newfile = JMenuItem("Open",actionPerformed = self.createInternalFrame)
        f.add(newfile)
        bar.add(f)
 
    def createInternalFrame(self, event):
        iframe     = JInternalFrame('InternalFrame', 1, 1, 1, 1, size=(400, 400), visible=1)
        iframe.setLayout(None)
        panel = JPanel()
        panel.setBounds(10,10,60,60)
        a = JButton("Report",actionPerformed=self.onClick)
        panel.add(a)
        iframe.add(panel)
        # 绑定内部窗体监听器
        iframe.addInternalFrameListener(IFrameListener(iframe, panel))
        self.desktop.add(iframe)
        
    def onClick(self,widget):
        print 'Report'
        
class IFrameListener(InternalFrameAdapter):
    def __init__(self, iframe, panel):
        self.iframe = iframe
        self.panel = panel
        
    def internalFrameOpened(self, e):
        # 窗体打开后调整尺寸
        self.iframe.setSize(450, 450)
        self.panel.setBounds(20,20,70,70)
        
if __name__ == '__main__':
    a = TestApp()
    a.setLocation(100, 100)
    a.show()

关于ComponentAdapter的补充说明

你当前使用的ComponentAdapter的componentResized方法,仅会在用户拖动窗体改变大小时触发。如果需要同时保留「拖动时同步调整组件」的功能,可以在创建监听器后手动调用一次componentResized方法,实现创建时的初始调整:

def createInternalFrame(self, event):
    iframe     = JInternalFrame('InternalFrame', 1, 1, 1, 1, size=(400, 400), visible=1)
    iframe.setLayout(None)
    c= JPanel()
    c.setBounds(10,10,60,60)
    a = JButton("Report",actionPerformed=self.onClick)
    c.add(a)
    iframe.add(c)
    # 创建监听器并传入需要调整的组件
    listener = ResizeListener(iframe, c)
    iframe.addComponentListener(listener)
    # 手动触发一次初始调整
    listener.componentResized(None)
    self.desktop.add(iframe)
    
# 修改监听器类,接收窗体和组件实例
class ResizeListener(ComponentAdapter):
    def __init__( self, iframe, panel ):
        self.iframe = iframe
        self.panel = panel
    def componentResized( self, ce):
        print "Resize event triggered!"
        self.iframe.setSize(450,450)
        self.panel.setBounds(20,20,70,70)

内容的提问来源于stack exchange,提问作者HydronicsEng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:47:55