`
林风丝雨
  • 浏览: 26467 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【转】使用JInternalFrame实现MDI

阅读更多

使用JInternalFrame实现MDI
2008-08-13 15:20:42
标签:Java MDI GPF JInternalFrame
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://devbean.blog.51cto.com/448512/92426
声明:本文章中介绍的内容可以在GPF项目中找到相应的实现。
 
GPF计划使用MDI的处理模式,Java的JDesktopPane和JInternalFrame已经为我们实现了这样的功能。但是,在将JInternalFrame最大化的时候,JDesktopPane和我们熟知的其他软件,如Word等,具有不同的处理方式。此时可以通过这里介绍的内容弥补这一缺点,使Swing的程序更类似于本地实现。
 
首先先看一下怎么使用JDesktopPane和JInternalFrame实现MDI。其实实现的方式很简单,就是在一个窗口中添加JDesktopPane,然后使用JDesktopPane的add方法,添加JInternalFrame的实例即可。具体的代码片段如下所示:
 
//... 
final JDesktopPane desktopPane = new JDesktopPane(); 
//... 
Container content = getContentPane(); 
content.add(desktopPane, BorderLayout.CENTER); 
//... 
InnerFrame iFrame = new InnerFrame(); 
iFrame.setVisible(true); 
desktopPane.add(iFrame); 
//...
 
由此即可按照Java提供的方式添加MDI的实现。我们可以看到它的运行截图如下所示:
 
 
可以看到,当JInternalFrame最大化的时候,仅仅是充满了整个JDesktopPane,并不会像一般的MDI程序一样,将最大化最小化的按钮显示在菜单栏。这是因为JInternalFrame是一个轻量级组件,必须依附在容器之中,因此它的大小不可能超出JDesktopPane。为了获得我们想要的效果,我们对JInternalFrame的UI进行改写:
 
class InnerFrame extends JInternalFrame { 
   
  /** The is hidden. */ 
  boolean isHidden = false
   
  /** The old ui. */ 
  BasicInternalFrameUI oldUi = null
   
  /** 
   * Instantiates a new inner frame. 
   */
 
  public InnerFrame() { 
      oldUi = (BasicInternalFrameUI)getUI(); 
      setSize(200, 200); 
      maximizable = true
      closable = true
      addComponentListener(new ComponentAdapter() { 
         public void componentResized(ComponentEvent e) { 
            InnerFrame selectedFrame = (InnerFrame)e.getSource(); 
            if(selectedFrame.isMaximum()){ 
              selectedFrame.hideNorthPanel(); 
              opPane.setVisible(true); 
              try { 
                 selectedFrame.setMaximum(true); 
              } catch (PropertyVetoException ex) { 
                 ex.printStackTrace(); 
              } 
          } 
      } 
    }); 
  } 
   
  /** 
   * Hide north panel. 
   */
 
  public void hideNorthPanel(){ 
      ((BasicInternalFrameUI) this.getUI()).setNorthPane(null); 
      this.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE); 
      isHidden = true
  } 
   
  /** 
   * Show north panel. 
   */
 
  public void showNorthPanel() { 
      this.setUI(oldUi); 
      this.putClientProperty("JInternalFrame.isPalette", Boolean.FALSE); 
      isHidden = false
  } 
   
  /* (non-Javadoc) 
   * @see javax.swing.JInternalFrame#updateUI() 
   */
 
  public void updateUI() { 
      super.updateUI(); 
      if (isHidden) { 
        hideNorthPanel(); 
      } 
  } 
}
 
InnerFrame类继承自JInternalFrame,由于JInternalFrame没有对于窗口最大化事件的监听。所以,我们把它添加了一个ComponentListener。当组件大小改变时,调用componentResized方法,然后在这里判断如果组件大小是isMaximum()的,则将NorthPane隐藏掉。这里的JInternalFrame的NorthPane就是绘有关闭按钮的那一条面板。由于定义了hideNorthPane()和showNorthPane()这两个方法,是得我们对于InnerFrame的控制加强了。
 
修改后的完整代码如下所示:
 
import java.awt.BorderLayout; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.beans.PropertyVetoException; 

import javax.swing.JButton; 
import javax.swing.JDesktopPane; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.plaf.basic.BasicInternalFrameUI; 

/** 
* MDIFrame is a frame using JInternalFrame to implements MDI as Word on Windows. 
*  
* @author Cheng 
* @version 1.0.0 for GPF MDI test 
*/
 
@SuppressWarnings("serial"
public class MDIFrame extends JFrame { 
  
    /** The desktop pane. */ 
    final JDesktopPane desktopPane = new JDesktopPane(); 
  
    /** The operation pane with restore and close buttons. */ 
    final JPanel opPane = new JPanel(); 
  
    /** 
     * Instantiates a new mDI frame. 
     */
 
    public MDIFrame(){ 
      setTitle("MDI Frame"); 
      setSize(600, 550); 
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
   
      final JMenuBar bar = new JMenuBar(); 
      JMenuItem exit = new JMenuItem("Exit"); 
          exit.addActionListener(new ActionListener(){ 

              @Override 
              public void actionPerformed(ActionEvent e) { 
                   System.exit(0); 
              } 
    
      }); 
      bar.add(exit); 
      // operation pane with two button, set invisible at first 
      opPane.setLayout(new FlowLayout(FlowLayout.TRAILING)); 
      JButton restore = new JButton("#"); 
      restore.setMargin(new Insets(0, 0, 0, 0)); 
      restore.setPreferredSize(new Dimension(15, 15)); 
      restore.addActionListener(new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent e) { 
            InnerFrame i = (InnerFrame)desktopPane.getSelectedFrame(); 
            try { 
                // notice this method, when JInternalFrame set maximun false
                // this internal frame will be set as old size 
                i.setMaximum(false); 
            } catch (PropertyVetoException ex) { 
                ex.printStackTrace(); 
            } 
            i.showNorthPanel(); 
            opPane.setVisible(false); 
          } 
    
      }); 
      opPane.add(restore); 
      JButton close = new JButton("X"); 
      close.setMargin(new Insets(0, 0, 0, 0)); 
      close.setPreferredSize(new Dimension(15, 15)); 
      close.addActionListener(new ActionListener(){ 

          @Override 
          public void actionPerformed(ActionEvent e) { 
            JInternalFrame i = desktopPane.getSelectedFrame(); 
            i.dispose(); 
            opPane.setVisible(false); 
          } 
    
      }); 
      opPane.add(close); 
      bar.add(opPane); 
      opPane.setVisible(false); 
      setJMenuBar(bar); 
   
      Container content = getContentPane(); 
      content.add(desktopPane, BorderLayout.CENTER); 
      final JPanel ctrlPane = new JPanel(); 
      JButton add = new JButton("add"); 
      add.addActionListener(new ActionListener(){ 

          @Override 
          public void actionPerformed(ActionEvent e) { 
              InnerFrame iFrame = new InnerFrame(); 
              iFrame.setVisible(true); 
              desktopPane.add(iFrame); 
          } 
    
      }); 
      ctrlPane.add(add); 
      content.add(ctrlPane, BorderLayout.SOUTH); 
      setVisible(true); 
    } 
  
    /** 
     * The Class InnerFrame. 
     */
 
    class InnerFrame extends JInternalFrame { 
   
      /** The is hidden. */ 
      boolean isHidden = false
   
      /** The old ui. */ 
      BasicInternalFrameUI oldUi = null
   
      /** 
       * Instantiates a new inner frame. 
       */
 
      public InnerFrame() { 
          oldUi = (BasicInternalFrameUI)getUI(); 
          setSize(200, 200); 
          maximizable = true
          closable = true
          addComponentListener(new ComponentAdapter() { 
              public void componentResized(ComponentEvent e) { 
                  InnerFrame selectedFrame = (InnerFrame)e.getSource(); 
                  if(selectedFrame.isMaximum()){ 
                      selectedFrame.hideNorthPanel(); 
                      opPane.setVisible(true); 
                      try { 
                           selectedFrame.setMaximum(true); 
                      } catch (PropertyVetoException ex) { 
                           ex.printStackTrace(); 
                       } 
                   } 
               } 
          }); 
      } 
   
      /** 
       * Hide north panel. 
       */
 
      public void hideNorthPanel(){ 
          ((BasicInternalFrameUI) this.getUI()).setNorthPane(null); 
          this.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE); 
          isHidden = true
      } 
   
      /** 
       * Show north panel. 
       */
 
      public void showNorthPanel() { 
          this.setUI(oldUi); 
          this.putClientProperty("JInternalFrame.isPalette", Boolean.FALSE); 
          isHidden = false
      } 
   
      /* (non-Javadoc) 
       * @see javax.swing.JInternalFrame#updateUI() 
       */
 
      public void updateUI() { 
          super.updateUI(); 
          if (isHidden) { 
              hideNorthPanel(); 
          } 
       } 
    } 
  
    /** 
     * The main method. 
     *  
     * @param args the arguments 
     */
 
    public static void main(String[] args) { 
          SwingUtilities.invokeLater(new Runnable(){ 

              @Override 
              public void run() { 
                   new MDIFrame(); 
              } 
    
          }); 
     } 

 
修改之后的最大化可以是如图样子:
 
 
当然,按钮之类的很难看,不过修改那个的话就是很容易的了,在这里不再赘述。
 
本程序代码在Java 6 下编译通过。由于Java文件不允许上传,所以将后缀名改为txt,编译时请将文件名改为MDIFrame.java即可。

本文出自 “豆子空间” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/92426

 

分享到:
评论

相关推荐

    JInternalFrame

    JInternalFrame menu 子窗体浮动 子窗体透明 面板透明 swing

    java swing-JInternalFrame的使用

    JInternalFrame 是 Java Swing 库提供的一个用于创建内部窗口的组件,常用于在桌面应用程序中创建多文档界面(MDI)。

    swing透明切换

    java界面设计之,swing透明切换,使用户用起来更加舒服

    JAVA SWING

    Java 综合性例子 多方向界面设计 经典例题 详细代码

    疯狂JAVA讲义

    学生提问:使用组合关系来实现复用时,需要创建两个Animal对象,是不是意味着使用组合关系时系统开销更大? 159 5.9 初始化块 159 5.9.1 使用初始化块 160 5.9.2 初始化块和构造器 161 5.9.3 静态初始化块 162 ...

    JCS Desktop module:基于 Swing 的桌面模块-开源

    该模块提供了一个基于 Swing 的桌面,带有一个 MDI 界面和一个系统菜单,根据需要可能... MDI 接口是通过 JInternalFrame 实现的,而 SDI 接口总有一天会通过 JFrames 实现。 看一下该模块的API的当前版本,网址为:

    JInternalFrameDemo.java

    JInternalFrameDemo.java

    java实现点击按钮事件弹出子窗口

    主要为大家详细介绍了java实现点击按钮事件弹出子窗口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    Swing 窗口与面版的使用

    介绍Frame和Panel容器的使用方法和时机。针对JFrame,JInternalFrame,JLayeredPane,JPanel,JScrollBar,JSplitPane,JTabbedPane写有详细的可执行代码。

    Java_Swing_Designer.rar_DEMO_Java_Swing_Designer_Swing Designer_

    精通Java Swing程序设计的帮助文档,包括:版面管理器,事件处理,JInternalFrame的使用,复选框、选项按钮、列表方框、下拉式列表的使用,树(Tree)的使用主要侧重以demo的方式说明。

    Java_Swing窗体种类简介

    Java_Swing窗体种类简介,这是非常好的资料,我想信对于学习javase开发的学者很有帮助

    oracle jdk自带swing 代码示例swingset3

    包含swing入门组件完整示例, 几乎包含swing所有组件介绍 ,可以带你入门了解swing的各种UI效果和使用示例,让你对swing有个整体了解. 顶层容器:JFrame/JDialog/JWINDOW 容器:JTabbedPane/JScrollPane/JSplitPane/...

    Father_and_son_form.rar_Father_java father son

    Java 的swing 组件创建父子窗口的例子,使用的结构是JDesktopPane-JInternalFrame。JDesktopPane 相当于一个“父窗口”,可以拥有多个作为“子窗口”的JInternalFrame 对象。如运行截图所示,当选中Option 菜单下的...

    Java创建产生关联的主窗体与子窗体.rar

    Java创建产生关联的主窗体与子窗体,使用的结构是JDesktopPane-JInternalFrame。JDesktopPane 相当于一个“父窗口”,可以拥有多个作为“子窗口”的JInternalFrame 对象。如运行截图所示,当选中Option 菜单下的...

    SuperPaint:使用Swing API的Java绘画程序

    超级彩绘 使用Swing API的Java绘画程序。... 使用Swing组件,例如JFrame,JPanel,JInternalFrame等。 非API链表数据结构 面向对象的编程实践(继承,多态性,封装的使用) 单击查看正在运行的程序。

    (java swing毕业设计)图书管管理系统(视频+源码).zip

    import java.awt.BorderLayout;...import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JToolBar; import javax.swi

    bikr:java中的种族(BikeRun)操作

    static JInternalFrame frame ; public void createAndShowGui(JDesktopPane desk) throws SQLException { //Δημιουργία tabed pane και εισαγωγή φορμών με εικόνες ...

    Swing组件下载(常用组件)

    内部框架:JInternalFrame 分层窗格:JLayeredPane 标签:JLabel 按钮:JButton 开启/关闭按钮:JToggleButton 复选框:JCheckBox 单选按钮:JRadioButton 按钮组:ButtonGroup 组合框:JComboBox 列表:JList ...

    swing-desktopScrollPane:知道如何将滚动条添加到摆动的JDesktopPane组件的滚动窗格

    如果JInternalFrame离开视口,则不会添加任何滚动条,并且您将失去“到达” JInternalFrame的能力。 该组件旨在解决该问题。 您只需将其传递给JDesktopPane并将其添加到应用中即可,而不是添加JDesktopPane。 该...

    Java创建父子窗体

    Java 的swing 组件创建父子窗口的例子,使用的结构是JDesktopPane-JInternalFrame。JDesktopPane 相当于一个“父窗口”,可以拥有多个作为“子窗口”的JInternalFrame 对象。如运行截图所示,当选中Option 菜单下的...

Global site tag (gtag.js) - Google Analytics