普通に仕事しながら趣味でソフト開発する37歳いろいろメモ -3ページ目

[Java] JInternalFrameに画像を表示させてみる(3)

前回記事:[Java] JInternalFrameに画像を表示させてみる(2)


前回の記事で小難しいことをやっていましたが、実はもっと簡単な方法がありました。JInternalFrameのメソッドにpack()というものがあり、JInternalFrameのサブコンポーネントが望ましいサイズで勝手に配置してくれます。


使い方は簡単。

画像をフレームに追加したあと、

this.pack();

とやればよし。


このメソッドはJFrameにもあります。(JFrameの場合はWindowクラスからの継承)


前回いろいろ悩んだのがムダになりました。

ヤホーやゴーグルで検索しても引っかかってこなかった・・・。


[Java] JInternalFrameに画像を表示させてみる(2)

前回記事: [Java] JInternalFrameに画像を表示させてみる(1)


前回は画像がフレームに治まりきらずに切れてしまう問題がありました。

これはJInternalFrameのサイズを設定する際に下記のようなコードだったからです。


this.setSize(img.getIconWidth(), img.getIconHeight());


    【解説】
普通に仕事しながら趣味でソフト開発する37歳いろいろメモ-innerFrame03.jpg

これでは、フレームの上下左右の余白部分と、上部のタイトルバーの分を加味されていません。解決方法として下図のようなコードを組む必要があります。


普通に仕事しながら趣味でソフト開発する37歳いろいろメモ-innerFrame04.jpg

Containerのサイズを取得するのには

this.getContentPane().getSize().width

this.getContentPane().getSize().height

です。

余白を取得するためには、

this.getInsets().left + this.getInsets().right

this.getInsets().bottom + this.getInsets().top

です。

ちなみにJFrameの場合、this.getInsets().topにタイトルバーの高さが含まれますのでContainerのサイズを取得する必要はありません。

JInternalFrameには何故かタイトルバーの高さが含まれていません。


あと、注意することとして、コンストラクタ内でContainerのサイズを取得しないでください。コンストラクタ内ではまだContainerのサイズがゼロの状態だからです。

とりあえず適当なサイズで設定して置いてください。

下記のようにメソッドで設定し、フレームを表示させた後に呼び出しましょう。


public void reSize(){
_____this.setSize(img.getIconWidth() + this.getInsets().left + this.getInsets().right +

__________img.getIconWidth() - this.getContentPane().getSize().width,
__________img.getIconHeight() + this.getInsets().bottom + this.getInsets().top +
__________img.getIconHeight() - this.getContentPane().getSize().height);
}



後日談

小難しいこと考えなくてもメソッドが用意されていました。

下記をご覧ください。たった12文字で解決。

[Java] JInternalFrameに画像を表示させてみる(3)


[Java] JInternalFrameに画像を表示させてみる(1)


先日作成したインナーフレームに画像を表示させてみます。

JFileChooserで画像を選択したいところですが、まずは単純に画像のファイルパスを渡し、それを表示させる簡単なプログラムを組んでみました。


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


class TestMDI2 extends JFrame{
_____protected JDesktopPane desktop;
_____protected Container pane;
_____protected JMenuBar mainMenu;
_____protected JMenu FileMenu;
_____protected JMenuItem OpenMenuItem;


_____TestMDI2(){
__________super();
__________setTitle("MDIテスト");
__________setSize(600,400);
__________pane = getContentPane();

__________createMenu();
__________desktop = new JDesktopPane();
__________pane.add(desktop,BorderLayout.CENTER);
_____}


_____void createMenu(){
__________mainMenu = new JMenuBar();
__________setJMenuBar(mainMenu);

__________FileMenu = new JMenu("File");
__________mainMenu.add(FileMenu);
__________OpenMenuItem = new JMenuItem("Open");
__________FileMenu.add(OpenMenuItem);
__________OpenMenuItem.addActionListener( new OpenAction() );
_____}


_____class OpenAction implements ActionListener{
__________public void actionPerformed(ActionEvent e){
_______________InnerFrame frame = new InnerFrame("C:\\....\\test.jpg");
_______________desktop.add(frame);
_______________frame.setVisible(true);
_______________desktop.getDesktopManager().activateFrame(frame);

__________}
_____}


_____public static void main(String[] args){
__________TestMDI2 d = new TestMDI2();
__________d.setVisible(true);
__________d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
_____}
}


class InnerFrame extends JInternalFrame {
_____private String filename;
_____private JLabel base;
_____private ImageIcon img;

_____public InnerFrame(String f){
__________img = new ImageIcon(f);
__________base = new JLabel();
__________base.setIcon(img);

__________this.add(base, BorderLayout.CENTER);

__________this.setClosable(true);
__________this.setResizable(true);
__________this.setIconifiable(true);
__________this.setMaximizable(true);

__________//フレームの大きさを画像サイズと同じにする
__________this.setSize(img.getIconWidth(), img.getIconHeight());
_____}

}

さてこれを実行するとどうなるでしょう。下記をご覧ください。


普通に仕事しながら趣味でソフト開発する37歳いろいろメモ-innerFrame02.jpg

見てのとおり画像の右と下がフレームに治まりきらずに切れてしまっています。

これはフレームサイズをsetSize()で画像サイズで設定したのですが、これでは周辺の枠とタイトルバーを含めたサイズを指定したことになりますので当然こうなります。


次回は画像がすべて表示できるようにインナーフレームの大きさを調整する方法を紹介します。

[Java] 親ウィンドウから子ウィンドウを操作するには

親ウィンドウから子ウィンドウを操作するには、JDesktopPaneのgetSelectedFrameメソッドを使います。子ウィンドウは複数生成している可能性があるので、アクティブになっている子ウィンドウを選択的に操作できるようにする必要があります。


JDesktopPane desktopで宣言しているとして、また子ウィンドウのクラス名をMyInnerFrameとした場合、次のようになります。


MyInnerFrame f = (MyInnerFrame) desktop.getSelectedFrame();


単にdesktop.getSelectedFrame()だけだと、JDesktopPaneのメソッドしか使用できませんので、MyInnerFrameにキャストしてあげる必要があります。

上記コードだと、MyInnerFrameクラス内のメソッドを使うことができます。

[Java] 子ウィンドウ(JInternalFrame)を使うには

アプリケーションシフトによくある子ウィンドウ(MDI=Multi Document Interface)をJavaで実現するには、MDIを生成するコンテナJDesktopPaneと、子ウィンドウ本体のJInternalFrameを使います。


【簡単なプログラム例】

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class TestMDI extends JFrame{
_____protected JDesktopPane desktop;
_____protected Container pane;
_____protected JMenuBar mainMenu;
_____protected JMenu FileMenu;
_____protected JMenuItem OpenMenuItem;

_____TestMDI(){
__________super();
__________setTitle("MDIテスト");
__________setSize(600,400);
__________pane = getContentPane();

__________createMenu();
__________desktop = new JDesktopPane();
__________pane.add(desktop, BorderLayout.CENTER);
_____}


_____void createMenu(){
__________mainMenu = new JMenuBar();
__________setJMenuBar(mainMenu);

__________FileMenu = new JMenu("File");
__________mainMenu.add(FileMenu);
__________OpenMenuItem = new JMenuItem("Open");
__________FileMenu.add(OpenMenuItem);
__________OpenMenuItem.addActionListener( new OpenAction() );
_____}


_____//Openボタンを押したら子ウィンドウを追加する

_____class OpenAction implements ActionListener{
__________public void actionPerformed(ActionEvent e){
_______________InnerFrame frame = new InnerFrame();
_______________desktop.add(frame);
_______________frame.setVisible(true);
_______________desktop.getDesktopManager().activateFrame(frame);
__________}
_____}


_____public static void main(String[] args){
__________TestMDI d = new TestMDI();
__________d.setVisible(true);
__________d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
_____}
}


//子ウィンドウ本体
class InnerFrame extends JInternalFrame {
_____public InnerFrame(){
__________this.setSize( new Dimension(200,150) );
__________this.setClosable(true);
__________this.setResizable(true);
__________this.setIconifiable(true);
__________this.setMaximizable(true);

__________this.add(new JLabel("InnerFrame"));
_____}
}


普通に仕事しながら趣味でソフト開発する37歳いろいろメモ-innerFrame01.jpg