- PR -

Click frame のClickの生成と表示がないと次の画面出ませんか?

投稿者投稿内容
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2001-09-29 18:39
ではでは、間違いやコメントを書きますね。


  • importの文
    コード:

    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import java.awt.GridLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.Border;
    import javax.swing.border.EmptyBorder;
    import javax.swing.border.TitledBorder;
    import javax.swing.border.EtchedBorder;
    import javax.swing.border.CompoundBorder;
    import java.awt.event.*;


    1行 〜 11行目ですが、import文をずらずら並べるよりも * を使って全部インポートした方が楽チンです。*を使うとパッケージ内のすべてのクラスが使えるようになります。*を使うと以下のように省略できます。
    コード:

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


  • フィールド
    すでにjavax.swing.JPanel(5行目)をインポートしているので106行目のprivate javax.swing.JPanel pane1_5;にあるjavax.swing.JPanelはいりません。private JPanel pane1_5;で十分です。またフィールド変数は最初の方に書きましょう。

  • 定数
    「20」や「"事故"」といった数字や文字列の使い方は止めましょう。Magic Numberなどといわれよくありません。finalを使って、定数として宣言してください。たとえば、"事故"という文字列を使う場合には
    コード:

    ...
    final JIKO = "事故";
    ...
    object.function(JIKO);
    ...


    という使い方をしてください。数字でもただ「20」と書いてあると後々、「あれ?これなんの20だっけ・・・、20ピクセルだったかな。20円だったかな???」という状態になりにくくなります。20の代りに、「CHOCO_NEDAN」と書いてあればチョコの値段のことだと分かりますし、「TOP_PIXEL」とあれば上からの高さだと分かりやすくなります。私のコードを見てください。フィールドの上に定数として宣言してあります。

  • 似たような変数は配列に入れる
    63行から69行には似た変数7つありますね。これらは配列に入れてください。コード自体がすっきりします。私のコードで25行目ではメニューのタイトルを配列に格納しました。この配列をつかい、forループにて全部のパネルを一気に初期化・設定ができます。(私のコード118行から126行を参照してください)

    pane1_1というのはパネル1の1番目のパネルという意味だと思いますがあっていますか?悪くないネーミングですが、ちょっと分かりづらいかもしれません。できれば具体的な名前の方がいいですよ。

  • 似たようなコードの繰り返しはさける
    63行から85行目まで繰り返しのコードが多いですね。こういうのはforループと配列を使うなどして避けてください。またオブジェクト生成直後にボーダーの設定をしていますがこれはコンストラクタに入れてもいいと思います。その方がすっきりします。

  • Clickがうまくいった理由
    52行目で、JFrameでは何も反応がなくClickがうまくいった理由ですが偶然です。
    Click.classがJPanelTest8.classと同じフォルダにありませんでしたか?Click.javaで実装したマウスイベントを行なっているだけです。そのためにパネル全体にマウスがのると反応があるわけです。各パネルに反応しているわけではなく、Clickオブジェクトであるwindow上でのマウスの動きに反応しているのです。

  • JFrameでうまく反応しない理由
    106行目にフィールド変数でpane1_5 を宣言してますね。さらにmain()メソッド内で、ローカル変数としてpane1_5を宣言してます。(67行目、JPanel panel_5 = new JPanel();です)これらフィールド変数とグローバル変数は違うものです。ですから、main()でpane1に置いたpae1_5にはMouseListenerがついていません。さらにJPanelオブジェクトを生成する必要はありません。JPanelTest8オブジェクトを作らないといけません。そのためのコンストラクターです。
    正しくは
    コード:

    01: public JPanelTest8()
    02: {
    03: super();
    04: this.addMouseListener(this);
    05: }
    06:
    07: ...
    08:
    09: public static void main(String[] args)
    10: {
    11: ...
    12: JPanelTest8 pane1_1 = new JPanelTest8();
    13: JPanelTest8 pane1_2 = new JPanelTest8();
    14: ...
    15: }


    です。12 行目で"new"を呼ぶことで、JPanelTest8オブジェクトのコンストラクタを呼びます。コンストラクタは01行目から05行目に定義されています。このオブジェクトはJPanelにextendsしていますのでJPanelと同じ属性を持っているため、super()を呼んでJPanelとしての属性を初期化します(03行目)。さらに生成しているこのオブジェクトにマウスリスナーを付加します(04行目)。これにより、pane1_1とpane1_2は別々のオブジェクトとしてマウスリスナーを持つことになります。

    私のコードは配列を使ったので見た目が少し違いますが似たような事をしています。

  • 最後に
    多少問題がありますが、すぐになれますよ。どれも初歩的なことですし、私自身も他の方からいっぱい注意されました。慣れればどうってことなくなります。がんばってくださいね。あと、オブジェクト指向の部分はどうしても理解した方がいいです。これはJavaの心です。Javaプログラミングの前提知識:オブジェクト指向とクラスについて理解するを参考にしてください。教科書にも載っているはずです。


レイアウトの部分はうまくできてますね。ああゆうボーダーができるって知りませんでしたよ。勉強になりました。(今持ってる教科書にSwingが載っていないので・・・)

長くなっちゃいましたが参考になったらよいと思います。


[ メッセージ編集済み 編集者: H2 編集日時 2001-09-29 19:14 ]
miki3
常連さん
会議室デビュー日: 2001/09/23
投稿数: 25
投稿日時: 2001-09-29 20:51
別の画面を出す事が出来ました。ただ パネルに応じて 違った画面を出したいので name と if を使った例を 挙げて頂けませんか。よろしくお願いします。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2001-09-30 09:37
文字列を比べる場合、整数(int)と違い == を使えません。文字列はStringというオブジェクトなのでequals()メソッドを使います。使い方は、Stringオブジェクト.equals(Stringオブジェクト)でtrueかfalseを返します。if...else if...else文は教科書を読んでください。絶対に載っているはずです。ちなみに、このメソッドはアルファベットの大文字小文字を別物とします。

"HI".equals("HI") はtrueですが
"hi".equals("HI") はfalseになります。
大文字小文字を区別しないメソッドもあります。java.lang.String内のメソッドをAPI Documentで見てみてください。

なお、例ですがこんな感じに使えます。
コード:
public void mouseClicked(MouseEvent e)
{
   if(name.equals("HOGE"))
   {
        System.out.println("HOGEHOGE");
   }
    else if(name.equals("hoge"))
    {
        System.out.println("hogehoge");
    }
    else
        System.out.prinln("その他");
}


マウスイベントハンドラ内でnameを調べます。if...else if...else文でnameによって違うイベントハンドルをすることができます。

なお、もっとスマートな手ではフィールド変数にpublic int panelID;を付け加え、コンストラクタを呼ぶときにパラメータとしてpanelIDを渡します。nameを使って各パネルを区別するよりもintでの区別の方がしやすいですよ。
miki3
常連さん
会議室デビュー日: 2001/09/23
投稿数: 25
投稿日時: 2001-09-30 12:08
public int PanelID;のやり方も教えて下さい。変数の定義も合わせてお願いします。よろしくお願いします。
miki3
常連さん
会議室デビュー日: 2001/09/23
投稿数: 25
投稿日時: 2001-09-30 13:25
nameは java.awt.Componentで privateアクセスされます
if(name.equals("pane1_1"))の nameに印
よろしくお願いします。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2001-09-30 13:25
ひとまず自分で試しにやってみてください。自分でトライしてみるのも大事ですよ。

ヒントですが、変更・改造箇所は

  • フィールド変数、
  • コンストラクタのパラメータと内部、
  • MY_JPanelオブジェクト生成のさいのパラメータ
  • mouseClicked()メソッドの内部、

です。上記のリスト順にひとつひとつゆっくりとやっていけばいいと思います。教科書をよく読んでちょっとずつ変えてみてください。(何か変更したらコンパイルして文法間違いがないか確認すること)

ではではがんばってくださいね
miki3
常連さん
会議室デビュー日: 2001/09/23
投稿数: 25
投稿日時: 2001-09-30 19:24
name = e.getJPanel();というのを考えたというか 真似して作ったのですが クリックされたパネル名をnameに受け取らす表現を 教えて下さい。または ヒントになる書名でもいいです。よろしくお願いします。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2001-09-30 19:57
nameはパネルオブジェクトを生成した段階ですでに各パネルが受け取っています。nameにアクセスする場合はオブジェクト名.nameでアクセスできます。

コード:
00:  public static void main(String[] args)
01:  {
02:      MY_JPanel panel_1 = new MY_JPanel("パネ1", 20, 40, 10, 20);
03:      System.out.println(panel_1.name);
04:      ...
05:      panel_1.name = "パネパネ";
06:      System.out.println(panel_1.name);
07:  }


02行目でpanel_1を生成した際に"パネ1"という名前を渡したわけです。その後、05行目でpanel_1オブジェクトのnameにアクセスしてコンソールに表示します。その後、05行目でpanel_1のnameを"パネパネ"に変えて06行目にてコンソールに出力します。
実行した際は
コード:
 パネ1
 パネパネ

とでるはずです。

mouseClicked() などのメソッド内でアクセスする場合は name だけでオッケーなはずです。
コード:
public void mouseClicked(MouseEvent e)
{
   if(name.equals("HOGE"))
   {
        System.out.println("HOGEHOGE");
   }
    else if(name.equals("hoge"))
    {
        System.out.println("hogehoge");
    }
    else
        System.out.prinln("その他");
} 

で参考になりませんか?

スキルアップ/キャリアアップ(JOB@IT)