MDI (Multiple Document Interface)型のアプリをJavaでも作ることができます。
MDI型、SDI型アプリとは
MDI型のアプリとは、今回のサンプルで作っているこんな画面のアプリのことです。
親画面の中に子画面が入っていて、親画面の範囲内で子画面を動かしたり、最大化したり、最小化したりできます。
これに対するのはSDI (Single Document Interface)型アプリ。
こちらのサイトで紹介している「ブログ記事作成支援アプリ」は、以前はSDI型でした。
普通にJFrameで作っていたらこのような形になります。
それぞれの画面が独立して動いているような感じです。
もちろん、MDIとSDIのどちらが優れているということはないです。
作るアプリ次第でどちらがいいかを選んだらよいです。
MDI型アプリを作ってみよう!
それではサンプルコードを見て行きましょう。
前半は起動のためのコードなので読み飛ばしてください。
大切なのは42行目からのinitialize()メソッドです。
package jp.beourselves.open.sample.jdesktop; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.SwingConstants; public class JDesktopPaneSample1 { private JFrame frmMdi; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { JDesktopPaneSample1 window = new JDesktopPaneSample1(); window.frmMdi.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the application. */ public JDesktopPaneSample1() { initialize(); } /** * Initialize the contents of the frame. */ private void initialize() { frmMdi = new JFrame(); frmMdi.setTitle("MDI型アプリ サンプル"); frmMdi.setBounds(100, 100, 450, 400); frmMdi.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JDesktopPane desktopPane = new JDesktopPane(); frmMdi.getContentPane().add(desktopPane, BorderLayout.CENTER); JInternalFrame frame1 = new JInternalFrame("Frame1"); frame1.setBounds(0, 0, 200, 300); desktopPane.add(frame1); JLabel lblHelloJdesktoppane = new JLabel("Hello, JDesktopPane!"); lblHelloJdesktoppane.setHorizontalAlignment(SwingConstants.CENTER); frame1.getContentPane().add(lblHelloJdesktoppane, BorderLayout.CENTER); JInternalFrame frame2 = new JInternalFrame("Frame2"); frame2.setBounds(200, 0, 200, 200); desktopPane.add(frame2); JLabel lblHelloJinternalframe = new JLabel("Hello, JInternalFrame"); lblHelloJinternalframe.setHorizontalAlignment(SwingConstants.CENTER); frame2.getContentPane().add(lblHelloJinternalframe, BorderLayout.CENTER); frame2.setVisible(true); frame1.setVisible(true); } }
このコードを実行するとこんな画面が出てきます。
タイトルバーに「MDI型アプリ サンプル」という親画面があり、その中に「Frame1」、「Frame2」という子画面が入っている、という感じです。
試しに「Frame1」や「Frame2」を移動させてみても、「MDI型アプリ サンプル」という親画面の外には出ることができません。
「MDI型アプリ サンプル」画面の中で完結しています。
JDesktopPaneとJInternalFrameを使って親子画面を作る
肝になるのはJDesktopPaneとJInternalFrameを使うことです。
イメージ的には、
- JDesktopPaneで親画面を作り (48〜49行目)
- JInternalFrameで子画面を作り(51〜52行目)
- 子画面を親画面に貼り付ける (53行目)
ような感じです。
JDesktopPaneで親画面を作る
まずは親画面を作るJDesktopPaneを見て行きましょう。
43〜49行目になります。
frmMdi = new JFrame(); frmMdi.setTitle("MDI型アプリ サンプル"); frmMdi.setBounds(100, 100, 450, 400); frmMdi.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JDesktopPane desktopPane = new JDesktopPane(); frmMdi.getContentPane().add(desktopPane, BorderLayout.CENTER);
最初の4行は親画面となるJFrameを作っています。
タイトルを設定し、サイズを設定し、閉じるときの処理を書いています。
最後の2行でJDesktopPaneを先に作ったJFrameに貼り付けています。
これで親画面の準備ができました。
JInternalFrameで子画面を作る
続いて子画面です。
「Frame1」を作っている51〜57行目を見てください。
JInternalFrame frame1 = new JInternalFrame("Frame1"); frame1.setBounds(0, 0, 200, 300); desktopPane.add(frame1); JLabel lblHelloJdesktoppane = new JLabel("Hello, JDesktopPane!"); lblHelloJdesktoppane.setHorizontalAlignment(SwingConstants.CENTER); frame1.getContentPane().add(lblHelloJdesktoppane, BorderLayout.CENTER);
最初の3行で子画面を作って、親画面に貼り付けています。
setBounds()で親画面内の表示位置とサイズを設定しています。
setBounds(x, y, dx, dy)
- x: 表示位置のx座標 (親ウインドウ内の座標)
- y: 表示位置のy座標 (親ウインドウ内の座標)
- dx: 子画面の横幅
- dy: 子画面の縦幅
最後の3行は作った子画面にラベルを貼り付けています。
59〜65行目は同じ処理なので省略しますね。
子画面を表示する
そして、66〜67行目で、貼り付けた子画面を表示しています。
frame2.setVisible(true); frame1.setVisible(true);
この処理を忘れると子画面がいないアプリになります。
必ずsetVisible(true)を設定しましょう。
JFrameの画面をJInternalFrameの画面に変換する
もうすでにJFrameで画面を作ったものがあったら、JFrameを継承する代わりにJInternalFrameを継承するようにしてください。
ほとんどそのまま子画面にすることができると思います。
改めて最初から子画面を作るよりは、こうして改造した方が早いでしょう。
ブログ記事作成支援ツールをMDI型にした時は、ほとんどそのまま変換できました。
おわりに
以上のように、JDesktopPaneとJInternalFrameを使うことでJavaでもMDI型のアプリが作れます。
ただ、これだけだと子画面の最大化、最小化、閉じるといった画面操作はできません。
その辺りはまた改めて作り方を紹介します。
元大手電機メーカのシステムエンジニア。
詳しくはこのサイトについての「サイト管理者について」をご覧ください。