• ベストアンサー

doja5.0 指定した時刻までのカウントダウン

こんばんは。 私は現在作成しているiアプリに、設定した時刻まで自動でカウントダウンする機能を付けようとしています。たとえば、15:00までの残り時間を「あと○分」といった感じで表示するものです。 でも、本やインターネットで情報を探しても、見つかりませんでした…。 どなたかご存じの方いらっしゃいますか?わかりやすく教えていただけるとうれしいです!よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • zozy
  • ベストアンサー率60% (20/33)
回答No.1

DojaでもJavaのAPIは使えますので普通にjava.util.Calendarを使います。 import com.nttdocomo.ui.Canvas; import com.nttdocomo.ui.Display; import com.nttdocomo.ui.Graphics; import com.nttdocomo.ui.IApplication; import com.nttdocomo.ui.ShortTimer; import java.util.Calendar; public class Test extends IApplication{ public void start(){ Mycanvas m=new Mycanvas(); Display.setCurrent(m); } class Mycanvas extends Canvas{ //現在の時間を取得 Calendar c=Calendar.getInstance(); //hour=現在の"時" int hour=c.get(Calendar.HOUR); //minute=現在の"分" int minute=c.get(Calendar.MINUTE); //表示する文字列(あと○○分) String time; //ShortTimerのID //イベント時にIDを指定できるので //同時に複数のタイマーを処理できる final static int timerID=0; //ShortTimerの宣言 ShortTimer st; public Mycanvas(){ //ShortTimerの生成 st=ShortTimer.getShortTimer(this,timerID,100,true); if(hour<15){ time="あと".concat(String.valueOf((15-hour)*60+minute)).concat("分"); }else{ time="あと".concat(String.valueOf((39-hour)*60+minute)).concat("分"); } } public void paint(Graphics g){ //ダブルバッファ(画面のちらつき防止) g.lock(); //画面を背景色で塗りつぶす //これやらずrepaint()すると前の描画が残る g.clearRect(0,0,240,240); //timeの描画 g.drawString(time,100,100); //ダブルバッファの処理を終了 g.unlock(true); } //イベント処理 //type=イベントの種類,param=イベントキー public void processEvent(int type,int param){ if((type==Display.TIMER_EXPIRED_EVENT) && (param==timerID)){ if(hour<15){ time="あと".concat(String.valueOf((15-hour)*60+minute)).concat("分"); }else{ time="あと".concat(String.valueOf((39-hour)*60+minute)).concat("分"); } //再描画処理 repaint(); } } } }

pocomin
質問者

補足

こんばんは。早速わかりやすい回答ありがとうございます! zozyさんが教えてくださったのを参考にしながら、自分なりに色々と付け加えて、正常に起動させることができました☆あと、できれば1分進むごとに、カウントダウンの表示も1分減らして変化させていきたいのですが、それは可能でしょうか? それから残念ながら、私の力不足のせいで、PanelからCanvasに切り替えができません…。 調べてみたところ、 Display.setCurrent(); で切り替えができるとわかったのですが、実際に //カウントダウンのパネルを表示 if (source == anchorbutton && type == ComponentListener.BUTTON_PRESSED) Display.setCurrent(TestTimer); としても、「シンボルを解決できません。」というエラーメッセージがでてしまいます。TimerのCanvasと、Panelは別に分けて作りました。 上記のようなCanvasに切り替える部分以外で、Panelに切り替える部分はもちろん上手くいっています。 単なるDisplay.setCurrent();ではダメなのでしょうか? 何度も質問してしまい申し訳ございません。 ご存じでしたら、また教えていただけるとうれしいです!!

その他の回答 (1)

  • zozy
  • ベストアンサー率60% (20/33)
回答No.2

よくエラー確認をせず、回答してしまい申し訳ないです。。。 コンストラクタ内でstart()メソッドを書いても処理されないようなので、イベント処理内で書いたところうまく行きました。 Panel,Canvas間のページ遷移は可能ですが そもそもにpanelとcanvasは水と油のような関係なのでどちらかのみでアプリを作ることをオススメします。 例として、タイマーのイベントをとりあげると ・canvasではShortTimerのイベントのみ使える ・panelではTimerのイベントのみ使える 他にも ・canvasでは既存のコンポーネントを配置できない(コンポーネントは自作するしかない) ・panelではpaint()メソッドを使えない(描画処理ができない) ・canvasとpanelではイベント処理の書き方が違う というようにpanelとcanvasはそれぞれ独立した機能を持っています。 個人的にはpanelは使い物にならないと思っているのでCanvasだけ使うことがオススメです。 ただインスタンスを生成するだけではページ遷移はできません。 そもそも、IApplicationを継承したクラス(メインクラス)にはページの遷移、各サブクラスのオブジェクトを所持しておく役目があります。 ページ遷移を実現するためにはメインクラスとサブクラス(PanelやCanvas)を階層関係(クラス間のつながり)を持たせておく必要があります。 Main |----Panel |----Cnavas こうあるべき ですが、普通にインスタンス生成をするだけでは Main Panel Canvas というようになってしまい、階層関係にはなりません。 解決策としてはサブクラスのインスタンス生成時に自分自身のオブジェクトを渡します。 以下が自分の作った参考ソースになります import com.nttdocomo.ui.Display; import com.nttdocomo.ui.IApplication; public class Main extends IApplication{ //ページ遷移を行うか判定するためのフラグ private boolean canvasFlg,panelFlg=true; //まだ宣言だけ MyCanvas mc; MyPanel mp; public void start(){ //インスタンス生成時に自分自身(this)を引数に受け渡す //Mainがサブクラスを持った形になる mc=new MyCanvas(this); mp=new MyPanel(this); mp.setSoftLabel(mc.SOFT_KEY_1,"Canvasへ"); mc.setSoftLabel(mc.SOFT_KEY_1,"Panelへ"); mc.setSoftLabel(mc.SOFT_KEY_2,"カウントダウン開始"); //ページ遷移をする change(); } public void change(){ if(canvasFlg==true){ //ここでfalseにしないと無限ループになる setCanvasFlg(false); Display.setCurrent(mc); } if(panelFlg==true){ setPanelFlg(false); Display.setCurrent(mp); } } //フラグのセッターメソッド public void setCanvasFlg(boolean canvasFlg){ this.canvasFlg=canvasFlg; } public void setPanelFlg(boolean panelFlg){ this.panelFlg=panelFlg; } } import com.nttdocomo.ui.Button; import com.nttdocomo.ui.Component; import com.nttdocomo.ui.ComponentListener; import com.nttdocomo.ui.Display; import com.nttdocomo.ui.HTMLLayout; import com.nttdocomo.ui.Label; import com.nttdocomo.ui.Panel; import com.nttdocomo.ui.SoftKeyListener; import com.nttdocomo.util.Timer; import com.nttdocomo.util.TimerListener; import java.util.Calendar; public class MyPanel extends Panel implements ComponentListener,SoftKeyListener,TimerListener{ Main m; Calendar c; Timer t=new Timer(); Label l=new Label(); Button b=new Button("カウントダウン開始"); //Doja唯一のレイアウト HTMLLayout layout=new HTMLLayout(); //15時まで何分かを格納 private int time=0; //現在の"時"を格納 private int hour=0; //現在の"分"を格納 private int minute=0; //タイマースタートをロックするためのフラグ //Timerクラスでは1つのタイマーしか動作できない //Canvasで対応しているShortTimerならIDを変えることで //最大5つまで同時に動かせる private boolean timerFlg=false; public MyPanel(Main m){ //コンストラクタの引数としてMainのオブジェクトを受け取る this.m=m; //イベント間隔の設定 t.setTime(1000); //イベントを繰り返すかを設定 //trueは繰り返す,falseは一度きり t.setRepeat(true); //レイアウトの設定 setLayoutManager(layout); layout.begin(layout.CENTER); add(l); layout.br(); add(b); layout.end(); //イベントリスナの設定 setComponentListener(this); t.setListener(this); } public void componentAction(Component c,int type,int param){ //ボタンが押されるとタイマー開始 if(c==b&&type==BUTTON_PRESSED){ if(timerFlg==false){ t.start(); //同時に2個作動させないように timerFlg=true; } } } public void softKeyPressed(int softKey){} public void softKeyReleased(int softKey){ //ソフトキー1を押すとMyCanvasへページ遷移 if(softKey==Display.KEY_SOFT1){ m.setCanvasFlg(true); m.change(); } } public void timerExpired(Timer timer){ if(timer==t){ c=Calendar.getInstance(); hour=c.get(c.HOUR); minute=c.get(c.MINUTE); if(hour<15)time=(16-hour)*60+60-minute; else time=(40-hour)*60+60-minute; l.setText(String.valueOf(time)); } } } import com.nttdocomo.ui.Canvas; import com.nttdocomo.ui.Display; import com.nttdocomo.ui.Graphics; import com.nttdocomo.ui.ShortTimer; import java.util.Calendar; public class MyCanvas extends Canvas{ Main m; ShortTimer st; Calendar c; final static int timerID=0; private int time=0; private int hour=0; private int minute=0; private boolean startFlg=false; public MyCanvas(Main m){ this.m=m; //引数はそれぞれ,ショートタイマーを実装するCanvas //使うID,イベントの発生間隔,繰り返しの設定 st=ShortTimer.getShortTimer(this,timerID,1000,true); } public void paint(Graphics g){ g.lock(); g.clearRect(0,0,240,240); g.drawString(String.valueOf(time),100,100); g.unlock(true); } public void processEvent(int type,int param){ if(type==Display.TIMER_EXPIRED_EVENT&&param==timerID){ c=Calendar.getInstance(); hour=c.get(c.HOUR); minute=c.get(c.MINUTE); if(hour<15)time=(16-hour)*60+60-minute; else time=(40-hour)*60+60-minute; repaint(); } if(type==Display.KEY_RELEASED_EVENT&&param==Display.KEY_SOFT1){ m.setPanelFlg(true); m.change(); } if(type==Display.KEY_RELEASED_EVENT&&param==Display.KEY_SOFT2){ if(startFlg==false){ st.start(); startFlg=true; } } } }

pocomin
質問者

お礼

返信が遅れてしまい、大変失礼いたしました。 自分でもキャンバスとパネルの切り替えを色々と試してみたのですが、やはり難しく、なかなか上手くいきませんでした…。 でも、わかりやすく教えていただき、感謝しています。timer()の繰り返しはsetRepeat()メソッドなんですね!勉強になりました☆ zozyさんのご意見を参考に、今後も作成していこうと思います。本当に何度もありがとうございました!!

関連するQ&A