• ベストアンサー

クリックでGUI部品を追加する

java歴3ヶ月の初心者です。よろしくお願いします。 現在、Swingを用いたパズルを作成しているのですが、 パネル上にあるラベルをクリックすると、 ラベルを乗っけていたパネル全体がラベルとなるようにゲーム画面を作りたいのですが、 「クリックにより、GUI部品をはずし別の部品をつける」 という方法がわかりません。 できればクリックするごとに元の状態と交互に表示できるようにしたいです。 試した方法としてはmouseClicked内にremove()やsetVisible(boolean) で消したのですが、その後にラベルを加えることができませんでした。 ご回答よろしくお願いいたします。

noname#1600
noname#1600
  • Java
  • 回答数3
  • ありがとう数5

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

  • ベストアンサー
回答No.1

InUteroさんが書かれているように、mouseClicked()で、表示を消すクラスをremove()し、 表示するクラスをadd()する方法が一番よいと思います。 しかし、この処理をするときにはいろいろと気を配ることがあります。 ます、コントロールを乗せるPanelなどのクラスのレイアウトがどうなっているかです。 borderLayoutなどではadd()やremove()を実行するたびにレイアウト表示が変わりますので、 レイアウトをnullに設定して、自分でsetLocation()やsetSize()などを使い、 固定しておくのも一つの方法です。 とにもかくにも、場合場合によっていろいろと落とし穴がありますので、 こういう場合は、まずは失敗したプログラムを載せてもらえると 回答がしやすいです。

noname#1600
質問者

お礼

コンポーネントの描画について参考になりました。 ありがとうございました。

noname#1600
質問者

補足

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; } } }

その他の回答 (2)

  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.3

>「視覚上のコンポーネントの数とgetComponentの数が違う時はどのような原因が考えうるか」 とりあえず、Component#list(System.out)を使用して コンポーネントのリストを出力し、ボタンを押す前と後で どこが違うか調べてみたらどうでしょうか。

noname#1600
質問者

お礼

オブジェクトの状態から、他のメソッドからそのオブジェクトをいじっていたことがわかりました。 ありがとうございました。

  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.2

>デバッグをして症状をみたところremoveをした瞬間にはオブジェクト自体は >取り除かれている >けれども、視覚上は消えていないらしいことがわかりました。 とりあえず、removeを行った後にrepaintしてみたらどうでしょうか?

noname#1600
質問者

補足

ご指摘を基に更に色々調べてみたところ repaint、revalidateが有効であるらしい、というところまでいきました。ありがとうございます。 それにより大体の症状は改善されたのですがまだいくつかのエラーが残ったので アドバイスお願いいたします。 作成しているのはパズルの自動解答&作成ソフト(ナンバープレイス)です。 数値を入れ、自動解答ボタンにより答えを求めた後に複数のラベルを持つパネルを ダブルクリックすると大きなラベルにならずにダブルクリックしたラベルだけが消えてしまいます。 自動解答ボタンのイベントを行う前は、複数のラベルを持つパネルをダブルクリックすると大きな 一つのラベルになっていたのにプログラム上の別のイベントを起こした後になると できないという症状です。  自分なりにデバッグをしてみたところ、視覚上は1つのラベルなのにgetComponentCount をしてみると9と返されたりします。また、removeAllでパネル上全てのオブジェクトをはずし 1枚の大きなラベルをaddするとgetComponentCountは1になるのですが視覚上はremoveAllさ れただけの状態でラベルが表示されていません。 今までrepaint、revalidateで更新ができるできるようになった物はrepaint等ない時でもウィンドウ のサイズをマウスで変えたりすると更新されていましたが、今回のエラーではサイズを変えても 更新されません。 うまく説明できず、この説明ではわかりずらいと思われるので、核の部分だけに絞って質問させて いただきますと、 「視覚上のコンポーネントの数とgetComponentの数が違う時はどのような原因が考えうるか」 です。わかりにくくて申し訳ありませんがよろしくお願いいたします。 (ソースが込み入ってしまっている上、どこが原因かわからず、GUIを生成しているクラスが300行近い のでソースを示すのは避けます。)

関連するQ&A

  • ボタンクリックでパネル表示方法?(JBuilder)

    ボタンをクリックしたタイミングで、パネルを生成しそれを表示したいのですが表示されません。下記のロジックに問題または、足りないものがありますか? void btnA_mouseClicked(MouseEvent e) { Panel1 pnlSub = new Panel1(); pnlSub.setVisible(true); } ちなみにパネルはSwingのJPanelではなくAWTのPanelを生成しております。

    • ベストアンサー
    • Java
  • 現在JAVA+SWINGでGUIアプリケーションを作成しています。

    現在JAVA+SWINGでGUIアプリケーションを作成しています。 JPanelのレイアウトマネージャーCardLayoutで10枚程度のページを作成し、パネル上のボタンをクリックすると次のページにジャンプする機能を実装中です。 いまのところパネル上のボタンをクリックし、パネル遷移をさせる方法として、一つのメインclassにパネルのすべてのパラメーターを記述しています(要はそのアプリはいまのところ、一つのjavaファイル) 希望としてはオブジェクト指向らしく、複数のクラスの組み合わせでつくりたい(それぞれのパネルは独立したclassでメインclassはパネルclassの呼び出しだけ)のですが、ページの切替Actionを独立したクラスにどのように記述すればよいのかわからない状態です。 構成 mainFrame mainPanel(CardLayout) subPanel01 button01(ボタンをクリックするとmainPanel上のsubPanel02へ切り替わる) subPanel02 button02(ボタンをクリックするとmainPanel上のsubPanel01へ切り替わる) やりたいこと subPanel01とbutton01を別のjavaファイル(class)として分け、mainPanelにはclassの呼び出しただけで、構成管理を簡略化したい 上記のことを実装しようとすると。子classのActionイベントで親のパネルに指示を出せないとパネルが切り替わらないとおもうのですが、このような実装は可能でしょうか? 初心者で申し訳ございませんが、宜しくお願いします。

    • ベストアンサー
    • Java
  • ラベルをプログレスバーのように伸び縮みさせるには?(Jbuilder)

    都合により、Swingのコンポーネントが使えない為AWTのコンポーネントでプログレスバーのようなものを作りたいのです。 パネルの上にラベルを置いて、そのラベルをドラッグして長さを調節するといいかなと思いましたがどのようにすればよいのかまったくわかりません・・・ 作りたいのは、ラベルをクリックして任意の長さまで伸び縮みさせられるようなコンポーネントです。

    • ベストアンサー
    • Java
  • フレーム内のラベルやテキストフィールドなどを真っ直ぐ揃えたいのですが

    つい最近JAVAのSWINGクラスとよばれるGUIプログラムを勉強したばかりの人です。 現在ラベル3つとテキストフィールド3つを交互に並び、 フレームの中の下段に中央にボタンが2つあるようなフレームを作成したいです。そして、ボタンを押したらラベル4が表示されるようにするのが目標です。 ↓こんな感じです。 ----------------------------------- ラベル1   テキストフィールド1 ラベル2   テキストフィールド2 ラベル3   テキストフィールド3      (ラベル4(ボタン押したら表示)) ボタン1  ボタン2 ------------------------------------- 単純にJLabelとJTextFieldを交互にソースに書いて getContentPane().add(p, BorderLayout.CENTER);と中央揃えに設定しても、ずれてしまいます。その上、仮にラベル1とラベル2の行の位置が上の場合でも、ラベル1または2の文字数でずれ込みます。 分からないことだらけですが、上のようにまっすぐ揃う方法をお教え下さい。

    • ベストアンサー
    • Java
  • Netbeans6 swingでの画面切替について

    Netbeans6 swingでGUIアプリを作成しようとしています。 swingは初心者です。 簡単な画面切替ができず、理解に困っています。 画面構成 ・画面1 ・画面2 目的:画面1のボタンを押されると画面2を表示したい。 構成 ・MainFlame.java ⇒ フレームと画面1(パネルを定義) ・Panel01.java ⇒ 画面2(パネル) 今後、ログイン⇒メニュー⇒入力画面(複数)といった具合にしたいので、1画面1クラスで行いたいです。 こういった場合どうすれば画面がきりかわるのでしょうか? よろしくお願いします。 ボタンクリック時のイベント部分にはこう書いてますが動きません。 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: remove(jPanel1); Panel01 panel = new Panel01(); add(panel); validate(); }

    • ベストアンサー
    • Java
  • ボタンクリック後パネルを再描画repaintしたい

    ボタンをクリック後にstaticで保持していた値にプラス1して その値をパネルに再描画したいと思っています。 下記のプログラムだとボタンをクリックすると (<1<2<3<4)となって画像と数字が増えてしまいます 行いたいのは数字の部分だけが再描画されて カウントされて<3と表示されるだけになってもらいたい クラス1つ目 import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.event.MouseEvent; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Sample extends JFrame{ static int value=1; JPanel work = new JPanel(); public static void main(String[] args) { Sample frame = new Sample(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100, 200, 200, 100); frame.add(frame.createPanel(), BorderLayout.LINE_END); frame.setVisible(true); } public JPanel createPanel() { ImageIcon icon = new ImageIcon("./img/left.gif"); JLabel label = new JLabel(); Cursor c = new Cursor(Cursor.HAND_CURSOR); label.setCursor(c); label.setIcon(icon); JLabel strLabel = new JLabel(); String str = Integer.toString(value); strLabel.setText(str); work.add(label); work.add(strLabel); label.addMouseListener(new myListener()); return work; } class myListener extends MouseAdapter{ public void mouseClicked(MouseEvent e){ System.out.print(Sample.value++); createPanel().repaint(); setVisible(true); } } } クラス2つ目 import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class MouseAdapter implements MouseListener{ public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} }

    • ベストアンサー
    • Java
  • C++でGUIアプリケーションを作成するには?

    C++でGUIアプリケーションを開発しようとしていますが、どのように作成すればよいのかわからなかったため、質問させて頂きました。 アプリケーションのイメージとしては、ボタン・背景などはすべてこちらの用意した画像で表示し、Windowsっぽいテイストは一切出さないアプリケーションです。ボタンを押すと画面全体が切り替わるイメージです(例えばプリクラみたいな) 現在JavaのSwingでアプリを作成しており、全体が切り替わる機能としてはJPanelのCardLayoutを使用しています。 ボタンはJButton等で完全に画像onlyのアプリを実現しています。 ただ、JavaはWEBカメラからの画像取得が640*480が限界であり、カメラの限界性能(1600*1200等)が使用できるopencv(c++)で画像キャプチャのところだけ作成しました。 このままアプリ全体はJavaで作成し、画像キャプチャ時はc++のexeを裏で実行させるという方法もあるのですが、言語を統一したほうがいいのではないか?と思ったので現在c++でGUIアプリの作成方法を調べています。 参考になるページもご紹介いただけるとありがたいです。

  • system.exit(0)について

    GUIを使ってフレームにパネルのっけて、ボタンを押すとそのフレームが開くようにしました。 で消すときにsystem.exit(0)を実行するとそのプログラム自体が終了してしまうじゃないですか?そうではなくて、そのフレームだけが閉じるようにするメソッドはないのですか?単に、setVisible(false)にするしか方法はないのですか?教えて

  • Swingで作ったウィンドウの最小化と復元

    ウィンドウを最小化時にタスクトレイに入れ,タスクトレイのアイコンを ダブルクリックすることで元に戻るようなプログラムを考えています。 GUIはSwingで実装するつもりです。 タスクトレイにアイコンを表示し,最小化時にイベントリスナーから setVisible()を呼ぶことでウィンドウをタスクトレイに入れるところまでは できましたが,アイコンをダブルクリックした時に再びsetVisible()を呼んでも 最小化された状態で表示され,元の場所・サイズに戻して表示することができません。 解決法としては ・プログラム側からウィンドウの最小化を解除,元に戻す ・最小化ボタンを押された時に最小化しないようにする の 2 つを考えましたが,どちらも実装法がわかりません。 また,これら以外に方法はあるのでしょうか。 よろしくお願いします。

  • JAVA+SWING+WEBカメラを使用して、WEBカメラの動画を表示

    JAVA+SWING+WEBカメラを使用して、WEBカメラの動画を表示させるGUIアプリーションを開発しています。 JFrame上に「player.getVisualComponent()」をaddするとフレーム全体に画像が表示されますが、以下のソースコードの様に「player.getVisualComponent()」をJPanel上にaddするとPanelのサイズ一杯に動画が表示されるのではなく、WEBカメラのデフォルトサイズで必ず表示されてしまいます。 JPanel上で任意の大きさでWEBカメラからの動画を表示させることは可能なのでしょうか? ちなみにWEBカメラの動画表示アプリのソースコードは以下の通りです。 import javax.media.*; import javax.swing.*; public class ImageView { public static void main(String args[]) throws Exception { JFrame frame = new JFrame("ImageView"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Player player = Manager.createRealizedPlayer(new MediaLocator("vfw://0")); JPanel panel = new JPanel(); panel.add(player.getVisualComponent()); frame.setBounds(100, 100, 640, 480); frame.getContentPane().add(panel); frame.setVisible(true); player.start(); } } 宜しくお願いいたします。

    • ベストアンサー
    • Java