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
相关产品推荐
相关产品推荐

