時限タイマーを作ってみよう6

   2012/11/20

最初は「できない」とか「ボツ」と思っても、少し日にちが経つと
「こうすればできるかも」とうまく行く方法に気づいたりします。

毎度、管理人イガジーです。

という訳で、時限タイマーなのですが、メッセージを出す窓を
FrameからDialogにすることにします。
プロトタイピングの時には「Dialogだと親窓にひっぱられて
一緒に最小化されるからボツ」と判断したのですが、あらためて
試してみると大丈夫でした(^^;)

MsgBoxをモーダルなDialogにすると、メッセージ(MsgBox/TimeBox)が
出た状態では設定窓で操作できなくなるので、昨日の問題点のいくつかが
解消できます。
モーダル(modal)(なダイアログ)というのは、
親より手前(上)に表示されそのダイアログを消すまで、親の窓が
アクティブにならないという挙動です。

Dialogにするにはclass MsgBox extends Dialog {として、コンストラクタを

	public MsgBox(Frame own, String message) {
	super(own,"Information",true);

とします。
own が窓の親ですね。trueは、modal=trueの指定です。
MsgBoxを継承している TimeBox もコンストラクタを次のようにします。

	public TimeBox(Frame own, String message) {
		super(own, message);

new する際には

tmsg=new TimeBox(f,null);
alart=new MsgBox(f,"1以上の数字を入力してください");

になります。

次にキャンセル処理ですが、タイマーをスタートしたら[Start]ボタンを
[Cancel]ボタンに変更してしまうことにします。
Button の表示ラベルは、button.setLabel(“表示文字列”); で設定できます。
# JButtonの場合は、jbutton.setText(“表示文字列”); です。
ActionListenerは

startbtn.addActionListener(new ActionListener() {
	@Override
	public void actionPerformed(ActionEvent e) {
		int dt=0;
		try {
			dt=Integer.parseInt(delay.getText().trim());
		} catch (NumberFormatException e1) {
			dt=0;
		}
		if (dt<1) alart.visible();
		else {
			if (timer==null) {
				tmsg.lb.setText(msg.getText());
				if (unit.getSelectedIndex()==1) dt*=1000; // second
				else dt*=60000; // minute
				timer=new Timer();
				timer.schedule(new TimerProc(), dt);
				f.setExtendedState(Frame.ICONIFIED);
				startbtn.setLabel("Cancel");
			}else{
				timer.cancel();
				timer=null;
				startbtn.setLabel(" Start ");
			}
		}
	}
});

と、timer動作中の処理を追加します。

f.setExtendedState(Frame.ICONIFIED);は、設定窓を最小化する(タスクバーに入れる)処理です。
時間が来て、TimeBoxを表示したら
f.setExtendedState(Frame.NORMAL);で、元に戻します。
TimeBoxを表示した時や、キャンセルした時には
startbtn.setLabel(" Start ");として、startbtnの表示文字列(ラベル)を
“Start”に戻します。

ここまでの全コードは次のようになります。

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Point;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;

public class VTimer5 {
	Frame f;
	MsgBox alart;
	TimeBox tmsg;
	TextField msg,delay;
	Button startbtn;
	Choice unit;
	Timer timer=null;

	VTimer5(){
		f=new Frame("Set Timer 5");
		f.addWindowListener(new WindowAdapter(){
			@Override
			public void windowClosing(WindowEvent arg0) {
				System.exit(0);
			}
		});
		tmsg=new TimeBox(f,null);
		alart=new MsgBox(f,"1以上の数字を入力してください");

		f.setLayout(new GridLayout(2,1));
		Panel p0=new Panel();
		p0.add(new Label("表示文"));
		msg=new TextField("時間です",20);
		p0.add(msg);
		Panel p1=new Panel();
		delay=new TextField(" 3",3);
		p1.add(delay);
		unit=new Choice();
		unit.add("分後");
		unit.add("秒後");
		p1.add(unit);
		startbtn=new Button(" Start ");
		startbtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				int dt=0;
				try {
					dt=Integer.parseInt(delay.getText().trim());
				} catch (NumberFormatException e1) {
					dt=0;
				}
				if (dt<1) alart.visible();
				else {
					if (timer==null) {
						tmsg.lb.setText(msg.getText());
						if (unit.getSelectedIndex()==1) dt*=1000; // second
						else dt*=60000; // minute
						timer=new Timer();
						timer.schedule(new TimerProc(), dt);
						f.setExtendedState(Frame.ICONIFIED);
						startbtn.setLabel("Cancel");
					}else{
						timer.cancel();
						timer=null;
						startbtn.setLabel(" Start ");
					}
				}
			}
		});
		p1.add(startbtn);
		p1.add(new Label("   ")); // スペーサ
		Button btn_end=new Button("End");
		btn_end.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		p1.add(btn_end);
		f.add(p0);
		f.add(p1);
		f.setSize(280,120);
		f.setVisible(true);
	}

	class MsgBox extends Dialog {
		private static final long serialVersionUID = 1L;
		Label lb;
		Button btn;
		MsgBox md;
		public MsgBox(Frame own, String message) {
			super(own,"Information",true);
			md=this;
			this.addWindowListener(new WindowAdapter(){
				@Override
				public void windowClosing(WindowEvent arg0) {
					md.setVisible(false);
				}
			});
			lb=new Label(message); // for message
			lb.setFont(new Font(Font.DIALOG,Font.PLAIN,18));
			lb.setAlignment(Label.CENTER);
			this.add(lb,BorderLayout.CENTER);
			btn=new Button(" OK ");
			btn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					md.setVisible(false);
				}
			});
			Panel p2=new Panel();
			p2.add(btn);
			this.add(p2,BorderLayout.SOUTH);
			this.setSize(340,140);
		}
		Point scenter(Dimension fsz) {
			Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize();
			int x=(screensize.width-fsz.width)/2;
			int y=(screensize.height-fsz.height)/2;
			Point pos=new Point(x,y);
			return pos;
		}

		void visible() {
			Point cpos=scenter(md.getSize());
			cpos.y-=40;
			md.setLocation(cpos);
			md.setVisible(true);
		}
	}// MsgBox
	class TimeBox extends MsgBox {
		private static final long serialVersionUID = 1L;
		Label tm;

		public TimeBox(Frame own, String message) {
			super(own, message);
			this.setTitle("The Time");
			tm=new Label();
			tm.setFont(new Font(Font.MONOSPACED,Font.BOLD,24));
			tm.setForeground(Color.BLUE);
			tm.setAlignment(Label.CENTER);
			this.add(tm,BorderLayout.NORTH);
			btn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					f.setExtendedState(Frame.NORMAL);
				}
			});
		}
		void visibletime(){
			Calendar cc=new GregorianCalendar();
			int hh=cc.get(Calendar.HOUR_OF_DAY);
			int mm=cc.get(Calendar.MINUTE);
			tm.setText(String.format("%02d:%02d", hh,mm));
			visible();
		}
	}
	class TimerProc extends TimerTask {
		@Override
		public void run() {
			timer=null;
			startbtn.setLabel(" Start ");
			tmsg.visibletime();
		}
	}
	public static void main(String[] args) {
		new VTimer5();
	}
}

これで一応完成としても良いでしょうか?
ご意見等はメールフォームからお気軽にお寄せください。

この記事へのコメントはこちら

メールアドレスは公開されませんのでご安心ください。
また、* が付いている欄は必須項目となりますので、必ずご記入をお願いします。

内容に問題なければ、下記の「コメント送信」ボタンを押してください。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)