学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース

Javaプログラミング入門その33 CheckboxMenuItem, PopupMenu, サブメニューの利用

<<前  [TOP]  次>>


今回は、メニューのCheckboxMenuItem, PopupMenuの使用法と、サブメニューの作成を行います。

java.lang.Object
    +--java.awt.MenuComponent
        |
        +--java.awt.MenuBar
        +--java.awt.MenuItem
            |
            +--java.awt.CheckBoxMenuItem
            +--java.awt.Menu
                |
                +--java.awt.PopupMenu



まずは、以下のサンプルプログラムを作成してみましょう。


AwtMenuDraw2.java 直

/**
*メニューで図形や色などを指定して「Start」で描画。複数の色で背景をクリア可能。
*ポップアップメニューでも「Clear」
*/

import java.awt.*;
import java.awt.event.*;

public class AwtMenuDraw2 extends Canvas implements ActionListener, ItemListener, MouseListener {

	private final int OVAL = 0;
        private final int RECT = 1;

	private MenuBar menuBar;
        private MenuItem startItem, quitItem;
        private MenuItem ovalItem, rectItem;
        private MenuItem blueItem, redItem;
	private MenuItem whiteItem, blackItem;
	private CheckboxMenuItem fillItem;
	private PopupMenu popMenu;
	private MenuItem popItem;
        private boolean clearFlag;
        private int zukeiFlag;
        private Color color, backColor;

	/**コンストラクタ*/
	public AwtMenuDraw2() {

                setSize(400, 300);

		//背景色の設定
		backColor = Color.white;
		setBackground(backColor);

		//メニューバーの生成
		menuBar = new MenuBar();

		//メニューの生成
                Menu programMenu = new Menu("Program");

		//メニューアイテムの生成
		startItem = new MenuItem("Start");
                quitItem = new MenuItem("Quit");

		//[Clear]をサブメニューとして追加
		Menu clearMenu = new Menu("Clear");
		whiteItem = new MenuItem("White");
		blackItem = new MenuItem("Black");

		//メニューアイテムをClearMenuに配置
		clearMenu.add(whiteItem);
		clearMenu.add(blackItem);

		//メニュー/メニューアイテムをprogramMenuに配置
		programMenu.add(startItem);
                programMenu.add(clearMenu);
                programMenu.addSeparator();		//区切り線を入れる
                programMenu.add(quitItem);

		//paintMenuの作成
		Menu paintMenu = new Menu("Paint");

		fillItem = new CheckboxMenuItem("Fill");
		paintMenu.add(fillItem);

		//zukeiMenuの作成
		Menu zukeiMenu = new Menu("Zukei");

                ovalItem = new MenuItem("Oval");
                rectItem = new MenuItem("Rect");

                zukeiMenu.add(ovalItem);
                zukeiMenu.add(rectItem);

		//colorMenuの作成
		Menu colorMenu = new Menu("Color");

                blueItem = new MenuItem("Blue");
                redItem = new MenuItem("Red");

                colorMenu.add(blueItem);
                colorMenu.add(redItem);
		//helpMenuの作成
		Menu helpMenu = new Menu("Help");

                MenuItem helpItem = new MenuItem("Help!");

		helpMenu.add(helpItem);

		//メニューをメニューバーに配置
		menuBar.add(programMenu);
                menuBar.add(paintMenu);
                menuBar.add(zukeiMenu);
                menuBar.add(colorMenu);
                menuBar.setHelpMenu(helpMenu);

		//ポップアップメニューをキャンバスに配置
		popMenu = new PopupMenu("PopupMenu");
		popItem = new MenuItem("Clear");
		popMenu.add(popItem);
		add(popMenu);

		clearFlag = false;
                zukeiFlag = 0;
                color = Color.blue;

		//イベントの登録
		startItem.addActionListener(this);
                quitItem.addActionListener(this);
                ovalItem.addActionListener(this);
                rectItem.addActionListener(this);
                blueItem.addActionListener(this);
                redItem.addActionListener(this);
		whiteItem.addActionListener(this);		//背景色設定用
		blackItem.addActionListener(this);
		popItem.addActionListener(this);		//popItemのイベントを通知
		fillItem.addItemListener(this);		//ItemListenerに通知
		addMouseListener(this);			//MouseListenerに通知
        }

	/**再描写が必要な場合の処理*/
	public void update(Graphics g) {

                int x, y, width, height;

		//clearFlagがtrueなら設定色でクリア
                if (clearFlag) {

			g.setColor(backColor);
                        g.fillRect(0, 0, getSize().width, getSize().height);
                        clearFlag = false;
                        return;
                }

		//メニューで設定された色
		g.setColor(color);

		//乱数で図形の位置指定
                x = (int)(Math.random()*400);
                y = (int)(Math.random()*300);

                width = (int)(Math.random()*200)+10;
                height = (int)(Math.random()*150)+10;

		//zukeiFlagによって楕円か矩形かを指定
		//fillItemを調べて塗りつぶしか否かを指定
		if (zukeiFlag == OVAL) {

			if (fillItem.getState() == false ) {

				g.drawArc(x, y, width, height, 0, 360);
                        }

			else {

                                g.fillArc(x, y, width, height, 0, 360);
                        }

                }

		else if (zukeiFlag == RECT) {

			if (fillItem.getState() == false ) {

				g.drawRect(x, y, width, height);
                        }

                        else {

                                g.fillRect(x, y, width, height);
                        }
                }
        }

	/**プログラム起動時と絵の復活時の処理*/
	public void paint(Graphics g) {

		//paintが呼ばれたときは画面クリア
		g.setColor(Color.white);
                g.fillRect(0, 0, 400, 300);
        }

	/**メニューのイベントを処理*/
	public void actionPerformed(ActionEvent evt) {

                Object obj = evt.getSource();

                if (obj.equals(startItem)) {

                        repaint();	//グラフィックス描画
                }

		else if (obj.equals(quitItem)) {

                        System.exit(0);	//システムの終了
                }

		else if (obj.equals(ovalItem)) {

                        zukeiFlag = OVAL;

                }

                else if (obj.equals(rectItem)) {

                        zukeiFlag = RECT;
                }

                else if (obj.equals(blueItem)) {

                        color = Color.blue;
                }

                else if (obj.equals(redItem)) {

                        color = Color.red;
                }

		else if (obj.equals(whiteItem) || obj.equals(blackItem) || obj.equals(popItem)) {

			//アクションコマンドを取得して色設定
			String c = evt.getActionCommand();

			if(c.equals("White")) {

				backColor = Color.white;
			}

			else if (c.equals("Black")) {

				backColor = Color.black;
			}

			clearFlag = true;
			repaint();	//グラフィックス描画
		}
	}

	/**CheckboxMenuItemの状態が変更された場合のイベント処理*/
	public void itemStateChanged(ItemEvent evt) {

		repaint();	//グラフィックス描画
	}
	
	/**ポップアップメニューのためのマウス処理*/
	public void mouseClicked(MouseEvent evt) {
	
		popupShow(evt);
	}

	public void mousePressed(MouseEvent evt) {

		popupShow(evt);
	}

	public void mouseReleased(MouseEvent evt) {

		popupShow(evt);
	}

	/**ポップアップメニューを表示させるための動作があった場合のみ表示*/
	public void popupShow(MouseEvent evt) {

		//ポップアップメニューを表示させるためのマウス操作かを判断
		if (evt.isPopupTrigger()) {

			//ポップアップメニューを表示
			popMenu.show(this, evt.getX(), evt.getY());
		}
	}

	/**その他のマウス処理*/
	public void mouseEntered(MouseEvent evt) { }
	public void mouseExited(MouseEvent evt) { }

	/**main()*/
	public static void main(String[] args) {

                AwtMenuDraw2 draw = new AwtMenuDraw2();
                MyFrame frame = new MyFrame("MenuDraw2");

                frame.setMenuBar(draw.menuBar);		//メニューバーを配置
                frame.add(draw);
                frame.pack();
                frame.setVisible(true);
        }
}



「CheckboxMenuItem」は、選択(「オン」)か選択解除(「オフ」)ができるメニューアイテムです。
基本機能はMenuItemを継承します。
「オン」「オフ」の状態は「getState()」で取得することが出来ます(返値がtrue=オン、false=オフ)。
また、設定は「setState(boolean)」で設定します(booleanがtrue=オン、false=オフ)。
また、生成時に「オン」「オフ」を設定することも可能です。
指定無しでで生成した場合は「オフ」になります。

Menu menu = new Menu("メニュー");
CheckboxMenuItem item1 = new CheckboxMenuItem("アイテム1");    //オフで生成
CheckboxMenuItem item2 = new CheckboxMenuItem("アイテム2", true);

//menuにメニューアイテムを登録。上から順に並ぶ
menu.add(item1);
menu.add(item2);

item1.setState(true);    //オンに状態変更
boolean flag = item2.getState();    //item2の状態を取得

CheckboxMenuItemは「オン」「オフ」が選択されると、ItemEventがItemListenerに通知されます。
イベント処理は「itemStateChanged()」に記述します。

public class Test implements ItemListener {

    /**コンストラクタ*/
    public Test() {
        ・
        ・
        CheckboxMenuItem item = new CheckboxMenuItem("アイテム");
        item.addItemListener(this);    //イベント通知登録
             ・
            ・
    }

    /**CheckboxMenuitemの項目が選択されたときの処理*/
    public void itemStateChanged(ItemEvent evt) {
        //処理
     }
}



PopupMenu(ポップアップメニュー)は、コンポーネントの任意の位置に表示するメニューで、「show(Component, int 指定コンポーネント座標 x, int y)」メソッドを使用することで表示できます。
ポップアップメニューは通常コンポーネントに配置します。
もし、ポップアップメニューがメニューバーなどに配置された場合はメニューと同様に扱われ「show()」メソッドは使用できません。
ポップアップメニューの中の項目作成は、Menuと同様に行うことが可能です。
なお、生成したPopupMenuで指定されたラベルが表示されるかどうかはシステムに依存します。

//PopupMenu("ラベル");で、「ラベル」が表示されるかはシステム依存
PopupMenu popup = new PopupMenu("ラベル");
MenuItem item = new MenuItem("アイテム");

//メニューアイテムをポップアップメニューに配置
popup.add(item);

//ポップアップメニューキャンバスに配置
Canvas canvas = new Canvas();
canvas.add(popup); 



ポップアップメニューが表示される一般的な状況はコンポーネントでマウス操作されたときです(イベントはMouseEvent。通知リスナはjava.awt.event.MouseListener。実装するメソッドは5種類)。
ただし、ポップアップメニューが表示される標準的な動作は、マウスの一番右のボタンを押すことです。
この処理のために、「MouseEvent.isPopup Trigger()」を利用することをお勧めします。
isPopupTrigger()はそのシステムでポップアップに適したマウスボタンの操作を関知してくれるものです。
しかし、どのタイミングでisPopupTrigger()が発生するかは、システムによって異なるので、MouseListenerで実装するメソッドのうち、「mousePressed()」「mouseReleased()」「mouseClicked()」には全て、isPopupTrigger()の判定を入れておいた方がよいです。


表示には「Popup.show()」を使用します。
下記の例では、「popup.show(canvas, evt.getX(), evt.getY());」となっています。
第一引数は、そのコンポーネント上に表示させるかを示します。
第2・第3引数は表示させるポップアップメニューの左上のx,y座標で、指定コンポーネント(キャンバス)の指定位置に表示します。
この場合、マウスカーソルの位置をもとに表示させます。

Canvas canvas = new Canvas();

 //マウスのイベント通知のために登録
canvas.addMouseListener(this);

 /**マウスイベントが発生したときの処理*/
public void mousePressed(MouseEvent evt) {
    popupShow(evt);    //内容は共通なのでメソッド化して、それを呼び出す。
}

public void mouseReleased(MouseEvent evt) {
    popupShow(evt);
 }

 public void mouseClicked(MouseEvent evt) {
    popupShow(evt);
 }

 /**その他のマウスイベント*/
public void mouseEntered(MouseEvent evt){ }
 public void mouseExited(MouseEvent evt){ }

 /**ポップアップメニューを表示させるのに適切な動作があった場合のみ表示*/
public void popupShow(MouseEvent evt) {
    if(evt.isPopupTrigger()) {
        //popupは生成されたPopupMenu
        popup.show(canvas, evt.getX(), evt.getY());
    }
}



メニューの中にさらにメニュー項目を持つ場合も、MenuItemなどと同様の処理で行えます。

Menu menu = new Menu("メニュー");
Menu subMenu = new Menu("サブメニュー");
MenuItem item1 = new MenuItem("アイテム1");
MenuItem item2 = new MenuItem("アイテム2");

//subMenuにメニューアイテムを登録
subMenu.add(item1);
 subMenu.add(item2);

//menuにsubMenuを登録
menu.add(subMenu);

スレッドを用いると、複数の処理を並行して行うことが可能です。
場合によってスレッドの優先度を指定するにはsetPriority()メソッドを使用します。
引数にはintの1〜10までを指定(優先度が高いのは10)しますが、一般的には、「MIN_PRIORITY」(1)、「NORM_PRIORITY」(5)、「MAX_PRIORITY」(10)を使用します。
ただし、必ずこの優先度で実行されるわけではありませんので、多少注意が必要です。

public class ThreadTest1 extends Thread {
    private String mes;

    ThreadTest1(String str) {
        mes = str;
    }

    public void run() {
        for(int i=0; i<10; i++) {
            System.out.println(mes += "=" +i);
        }
    }

    public static void main(String[] args) {
        ThreadTest1 t1 = new ThreadTest1("t1");
        ThreadTest1 t2 = new ThreadTest1("t2");
        ThreadTest1 t3 = new ThreadTest1("t3");

        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);
        t3.setPriority(Thread.NORM_PRIORITY);

        t1.start();
        t2.start();
        t3.start();
    }
}



スレッドの終了時に値を表示したい場合などは、スレッドが終わるまで待機する必要があります。
このときは、join()メソッドを利用します。

public class ThreadTest2 extends Thread {
    private int num;

    ThreadTest2() {
        num = 0;
    }

    public void run() {
        for (int i=0; i<100; i++) {
            num++;
        }
    }

    public static void main(String[] args) {
        ThreadTest2 t = new ThreadTest2();

        t.start();

        try {
            t.join();
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        System.out.println("t"= + t.num);
    }
}



ではサンプルプログラムを実行してみましょう。
前回作成したMyFrame.java 直を利用していますのでクローズボタンを使って終了できます。


メニューで図形や色などを指定して「Start」で描画します。
複数の色で背景をクリア可能です。
右クリックすると、ポップアップメニューが表示されます。
ポップアップメニューの「Clear」でも画面クリアが出来ます。








<<前  [TOP]  次>>