- ベストアンサー
クリックでGUI部品を追加する
java歴3ヶ月の初心者です。よろしくお願いします。 現在、Swingを用いたパズルを作成しているのですが、 パネル上にあるラベルをクリックすると、 ラベルを乗っけていたパネル全体がラベルとなるようにゲーム画面を作りたいのですが、 「クリックにより、GUI部品をはずし別の部品をつける」 という方法がわかりません。 できればクリックするごとに元の状態と交互に表示できるようにしたいです。 試した方法としてはmouseClicked内にremove()やsetVisible(boolean) で消したのですが、その後にラベルを加えることができませんでした。 ご回答よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
InUteroさんが書かれているように、mouseClicked()で、表示を消すクラスをremove()し、 表示するクラスをadd()する方法が一番よいと思います。 しかし、この処理をするときにはいろいろと気を配ることがあります。 ます、コントロールを乗せるPanelなどのクラスのレイアウトがどうなっているかです。 borderLayoutなどではadd()やremove()を実行するたびにレイアウト表示が変わりますので、 レイアウトをnullに設定して、自分でsetLocation()やsetSize()などを使い、 固定しておくのも一つの方法です。 とにもかくにも、場合場合によっていろいろと落とし穴がありますので、 こういう場合は、まずは失敗したプログラムを載せてもらえると 回答がしやすいです。
その他の回答 (2)
- akinori_s
- ベストアンサー率60% (21/35)
>「視覚上のコンポーネントの数とgetComponentの数が違う時はどのような原因が考えうるか」 とりあえず、Component#list(System.out)を使用して コンポーネントのリストを出力し、ボタンを押す前と後で どこが違うか調べてみたらどうでしょうか。
お礼
オブジェクトの状態から、他のメソッドからそのオブジェクトをいじっていたことがわかりました。 ありがとうございました。
- akinori_s
- ベストアンサー率60% (21/35)
>デバッグをして症状をみたところremoveをした瞬間にはオブジェクト自体は >取り除かれている >けれども、視覚上は消えていないらしいことがわかりました。 とりあえず、removeを行った後にrepaintしてみたらどうでしょうか?
補足
ご指摘を基に更に色々調べてみたところ repaint、revalidateが有効であるらしい、というところまでいきました。ありがとうございます。 それにより大体の症状は改善されたのですがまだいくつかのエラーが残ったので アドバイスお願いいたします。 作成しているのはパズルの自動解答&作成ソフト(ナンバープレイス)です。 数値を入れ、自動解答ボタンにより答えを求めた後に複数のラベルを持つパネルを ダブルクリックすると大きなラベルにならずにダブルクリックしたラベルだけが消えてしまいます。 自動解答ボタンのイベントを行う前は、複数のラベルを持つパネルをダブルクリックすると大きな 一つのラベルになっていたのにプログラム上の別のイベントを起こした後になると できないという症状です。 自分なりにデバッグをしてみたところ、視覚上は1つのラベルなのにgetComponentCount をしてみると9と返されたりします。また、removeAllでパネル上全てのオブジェクトをはずし 1枚の大きなラベルをaddするとgetComponentCountは1になるのですが視覚上はremoveAllさ れただけの状態でラベルが表示されていません。 今までrepaint、revalidateで更新ができるできるようになった物はrepaint等ない時でもウィンドウ のサイズをマウスで変えたりすると更新されていましたが、今回のエラーではサイズを変えても 更新されません。 うまく説明できず、この説明ではわかりずらいと思われるので、核の部分だけに絞って質問させて いただきますと、 「視覚上のコンポーネントの数とgetComponentの数が違う時はどのような原因が考えうるか」 です。わかりにくくて申し訳ありませんがよろしくお願いいたします。 (ソースが込み入ってしまっている上、どこが原因かわからず、GUIを生成しているクラスが300行近い のでソースを示すのは避けます。)
お礼
コンポーネントの描画について参考になりました。 ありがとうございました。
補足
Tanaka Shinyaさんご回答ありがとうございます。 アドバイスに注意しながら試してみたところPanelを消した後に同じ場所に ラベルを張ることができました。 しかし、しばらく実装を進めたところまたこのイベントで不明な点が出てきた 為、お手数ですが可能でしたらご回答お願いします。 私の作成したいプログラムは ・ダブルクリックした文字をそのパネル全体にjpn(JLabel) として表示する ・右クリックでsel(JLabel)に右と表示 ・左クリックでselに左と表示する です。 アドバイスにより近い物ができたのですが「落とし穴」にはまっているようで、 ダブルクリックしてもその時はパネルが消えず、同様のイベント処理を準備してある 別のパネルをクリック(もしくは右,ダブルクリック) をした瞬間になるとさっき消えるはずであったパネルが消えます。 つまりイベントの起こるタイミングがずれている状態です。 デバッグをして症状をみたところremoveをした瞬間にはオブジェクト自体は取り除かれている けれども、視覚上は消えていないらしいことがわかりました。 それ以上の原因は私の力では調べられませんでした。 長くなってしまいましたがご指摘通りソースを文末に載せたのでご回答していただければ幸いです。 よろしくお願いいたします。 public void mouseClicked(MouseEvent e){ if(e.getClickCount()==2){ inta=0,b=0; A: for(int i=0;i<9;i++) for(int j=0;j<9;j++) if((JLabel)e.getSource()==sel[i][j]){ block[i][j].remove(selPanel[i][j]); block[a/9][b/9].setVisible(true); break A; } JLabel jpn=new JLabel("D"); block[a/9][b/9].add(jpn); jpn.setVisible(true); } else if(e.getModifiers()==e.BUTTON1_MASK) ((JLabel)e.getSource()).setText("左"); else if(e.getModifiers()==e.BUTTON3_MASK){ L: for(int a=0;a<27;a++) for(int b=0;b<27;b++) if((JLabel)e.getSource()==sel[a][b]){ ((JLabel)e.getSource()).setText("右"); break L; } } }