MDI型のJavaアプリを作る JDesktopPaneとJInternalFrameがキモ

MDI (Multiple Document Interface)型のアプリをJavaでも作ることができます。

MDI型、SDI型アプリとは

MDI型のアプリとは、今回のサンプルで作っているこんな画面のアプリのことです。

MDI型アプリ

親画面の中に子画面が入っていて、親画面の範囲内で子画面を動かしたり、最大化したり、最小化したりできます。

これに対するのはSDI (Single Document Interface)型アプリ。

こちらのサイトで紹介している「ブログ記事作成支援アプリ」は、以前はSDI型でした。

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);
	}
}

このコードを実行するとこんな画面が出てきます。

Sean 2013121817060101

タイトルバーに「MDI型アプリ サンプル」という親画面があり、その中に「Frame1」、「Frame2」という子画面が入っている、という感じです。

試しに「Frame1」や「Frame2」を移動させてみても、「MDI型アプリ サンプル」という親画面の外には出ることができません。

「MDI型アプリ サンプル」画面の中で完結しています。

JDesktopPaneとJInternalFrameを使って親子画面を作る

肝になるのはJDesktopPaneJInternalFrameを使うことです。

イメージ的には、

  • 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型にした時は、ほとんどそのまま変換できました。

おわりに

以上のように、JDesktopPaneJInternalFrameを使うことでJavaでもMDI型のアプリが作れます。

ただ、これだけだと子画面の最大化、最小化、閉じるといった画面操作はできません。
その辺りはまた改めて作り方を紹介します。

無料メールセミナー