【Swing】JPanel クラス外からのremoveについて

このQ&Aのポイント
  • _tonnuraと申します。どうぞよろしくお願いします。
  • 現在、初期画面(Menu.java)、イベント(ButtonClicked.java)、パネル設定(Mondai.java)の3つを使用して、画面を切り替えようとしています。
  • 内部で「add」「remove」する分には問題ないのですが、一旦外にでてしまうと、配列でしか「remove」できない状態です。画面によってはループを考えていますので、必要な部分だけ追記したいのです。配列での指定ですと応用が辛いので・・。ソースが無駄に長いため概念的な部分だけ抜き出しています。
回答を見る
  • ベストアンサー

【Swing】JPanel クラス外からのremoveについて

_tonnuraと申します。どうぞよろしくお願いします。 現在、 ・初期画面(Menu.java) ・イベント(ButtonClicked.java) ・パネル設定(Mondai.java) の3つを使用して、画面を切り替えようとしています。(パネルを載せていく形です) 「Class Mondai」にて定義したパネル(p10)の部品を、フレームに載せる前にいじりたいと思っていますが、「☆」の部分で困っています。 内部で「add」「remove」する分には問題ないのですが、一旦外にでてしまうと、配列でしか「remove」できない状態です。 上記の挙動から、戻り値的には「ButtonClicked」上でコンテナ(p10)が見えていると思うのですが、配列以外(名前やID等、処理のたびに変動しないもの)で指定することはできないのでしょうか。 画面によってはループを考えていますので、必要な部分だけ追記したいのです。配列での指定ですと応用が辛いので・・。 尚、ソースが無駄に長いため 概念的な部分だけ抜き出しています。 「そもそも」な部分が多々あると思いますが、なにとぞよろしくお願いします。 ■Class Menu package test; //フレームの定義 public class Menu extends JFrame{     public static void main(String[] args) {         Menu frame_m = new Menu();         frame_m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         frame_m.setTitle("画面遷移テスト");         frame_m.setBounds(10, 10, 750, 570);         frame_m.setVisible(true);         frame_m.setResizable(false);     }     Menu() {     ~(省略)初期画面のパネル・部品・レイアウトに関する宣言~     panel_menu.add(t_label);     getContentPane().add(panel_menu);     validate();     } ■Class ButtonClicked package test; Class ButtonClicked implemments ActionListener{     //フレームを格納 パネル作成時の設置先として使用      public Menu owner;     //パネルを格納  前パネルの削除先として使用(getContentPane)     public Container subowner;     public void actionPerformed(ActionEvent ae) {             String cmd = ae.getActionCommand();             if (cmd.equals("btn_01")) {             //遷移画面の描写(パネルを被せる)                 Mondai obj = new Mondai();                 Container p10 = obj.drawPanel(owner);     //Class Mondaiにて定義したパネル上のコンポーネントJButton3)を削除したい     ☆問題の部分です(ERROR:「JButton3を解決できません」) //               p10.remove(JButton3);     ☆こっちだとOK (varidate後、表示されていない)                 p10.remove(3);//owner.list(System.out)参照                 owner.add(p10);                 owner.validate();             } else if (cmd.equals("btn_b02")) {             //別の処理hogehoge             } } ■Class Mondai package test; public Container drawPanel(Menu frame)throws Exception {     JPanel p10 = new JPanel();     ~(省略)遷移画面のパネル・部品・レイアウトに関する宣言~     p10.add(JButton1);     p10.add(JButton2);     p10.add(JButton3);     return p10; }

  • Java
  • 回答数1
  • ありがとう数3

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

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

remove()で削除するには、Container内のindex値かComponent自身のインスタンスを指定する必要がありますね。質問のコードでは、JButton3(どこかで宣言した変数でしょうか?)が、何か不明だということで、エラーになっているようです。このコードの流れで解決しようとするなら、p10のComponent群を検索して、removeしたいComponent(JButton3)のインスタンスを探し出す方法が考えられます。(getComponents()でComponentの配列を取得し、各 Component の Class や label値、name 値などを使って、対象を特定すれば良いでしょう。) ただ、一度作ったパネルから、後から部品を取り除いて体裁を整えるというのは、いかにも不自然ですよね。 おそらく私なら、Mondai.drawPanel() に一つ引数を追加して、Panelの生成時に必要な部品のみを配置するようにすると思います。(フラグの意味付けとしては、各Buttonの有無を直接指定する方法と、パネルの種類とそれぞれに必要なButtonの種類の対応表を間に挟む方法があると思います。Java的な発想に従うなら、引数でスイッチするより、それぞれのPanelの種類ごとにdrawPanelXXXX(Menu frame)のような形でメソッドを分けるのがよいかもしれません。) ...  (~)  if (cmd.equals("btn_01")) {   Mondai obj = new Mondai();   Container p10 = obj.drawPanel(owner, (Mondai.BUTTON1 | Mondai.BUTTON2));   owner.add(p10);   owner.validate();   (~) ... public class Mondai { public static final int BUTTON1 = 1; public static final int BUTTON2 = 2; public static final int BUTTON3 = 4; ... public Container drawPanel(Menu frame, int buttons) throws Exception {  (~)  JPanel p10 = new JPanel();  (~)  if ((buttons & BUTTON1) != 0) {   p10.add(JButton1);  }  if ((buttons & BUTTON2) != 0) {   p10.add(JButton2);  }  if ((buttons & BUTTON3) != 0) {   p10.add(JButton3);  }  return p10; }

_tonnura
質問者

お礼

soramame99 様 回答していただきありがとうございます。 既存画面における、既存部品に対しての属性の変更(イベント)を行う目的でしたが、どうやって指定すればいいのか・・と悩んでいました。 ※1・2個の部品のためにパネルの無し張りなおしはやりすぎかな?と >(getComponents()でComponentの配列を取得し、各 Component の >Class や label値、name 値などを使って、対象を特定すれば良いでしょ >う。) 説明いただいた部分の「name値」という記述のおかげで 問題を解決することができました。 ※恥ずかしながら、setNameという概念がそもそもありませんでした。部品の定義時(new)にて、自動で付いているものだと・・・ 具体的には配列を取得し、For文にて回しながら「name値」を元に判定をさせることで、コンポーネントを特定することができました。 ※「コンテナ.remove(コンポーネント情報「何か」);」 の1行で指定ができるものと勘違いしていました お忙しい中、ソースまで書いていただきありがとうございます。 考え方として勉強になりました。トータルのボタン数が多いのでメソッド分けを検討しようと思います。 どうもありがとうございました!

関連するQ&A

  • JPanelの切り替えと再描画

    ContainerにJPanelをaddし、ボタンを押すことで現在addされているJPanelとは違うJPanelを生成し、再描画させようとしているのですが、うまくいかないため、質問致しました。 -- src --- public class Test extends JFrame implements ActionListener {   Container container;   JPanel panel;   JButton btn;      public Test() {     container = getContentPane();     container.setLayout(new BorderLayout());     // ボタン用パネル     JPanel btnp = new JPanel();     btnp.setLayout(new FlowLayout());     container.add(btnp, BorderLayout.NORTH);          btn = new JButton("aaa");     btn.addActionListener(this);     btnp.add(btn);          // 対象のパネル     panel = new JPanel();       (略)panelの設定     container.add(panel, BorderLayout.CENTER);     setVisible(true);     setBounds(50, 50, 300, 300);     setDefaultCloseOperation(EXIT_ON_CLOSE);   }      public void actionPerformed(ActionEvent e) {     if (e.getSource() == btn) {       container.remove(1);       panel = new JPanel();  // 本来はJPanelを継承したクラスをnewしています       container .add(panel);       repaint();       // ※     }   }      public static void main(String args[]) {     Test t = new Test();   } } ※の箇所をcontainer.repaint() にしたり、paintImmediaely() にしたり出来そうな事を色々試したつもりではいるのですが、うまくいきません… ボタン押下後に、ウィンドウの枠をクリックすると描画されるのですが、いまいちよくわかりません… なにか分かる方いらっしゃいましたらご教授願います。

  • JavaでのSwingを使った簡易電卓作成

    Javaについて勉強中の学生です。 よろしくお願いします。 CGIによるプログラムは一通り勉強しました。 次にGUIによるプログラムを勉強中です。 そこで電卓を作ってみようと思いましたが、よくわからないところがあります。 ご教示いただければ幸いです。 一応外見だけは作ることができましたが、イベントを登録するときに電卓のボタンをbtn1,btn2,btn3…とすればイベントを登録することはできるのですが、それだとボタンの分だけ作成しなければならず修正を加えるのが大変になってしまいます。 例)btn1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent ae){ hyozi.setText(hyozi.getText() + "1"); } } そこで「btn」に統一しボタンに表示されている文字列を使い簡潔にプログラムをまとめたいのですがどのようにすればよいのかわかりません。以下のプログラムに追加できるようなものを教えていただけないでしょうか? import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Dentaku{ private JFrame frame; private JPanel panel_fun,panel_ten; private JTextField hyozi; private JButton btn; public Dentaku(){ //フレームの作成してレイアウトをセット frame = new JFrame("簡易電卓プログラム"); frame.setLayout(new BorderLayout()); //パネルを作成してレイアウトをセット panel_fun = new JPanel(); panel_fun.setLayout(new GridLayout(2,3)); panel_ten = new JPanel(); panel_ten.setLayout(new GridLayout(4,3)); //表示用テキストボックスを作成 hyozi = new JTextField(); //電卓のボタンを作成 panel_fun.add(btn = new JButton("CA")); panel_fun.add(btn = new JButton("+")); panel_fun.add(btn = new JButton("-")); panel_fun.add(btn = new JButton("*")); panel_fun.add(btn = new JButton("/")); panel_fun.add(btn = new JButton("=")); panel_ten.add(btn = new JButton("1")); panel_ten.add(btn = new JButton("2")); panel_ten.add(btn = new JButton("3")); panel_ten.add(btn = new JButton("4")); panel_ten.add(btn = new JButton("5")); panel_ten.add(btn = new JButton("6")); panel_ten.add(btn = new JButton("7")); panel_ten.add(btn = new JButton("8")); panel_ten.add(btn = new JButton("9")); panel_ten.add(btn = new JButton("0")); //フレームに表示用テキストボックスをセット(BorderLayoutの北側) frame.add(hyozi,BorderLayout.NORTH); //フレームにパネルをセット(BorderLayoutの中央,南側) frame.add(panel_fun,BorderLayout.CENTER); frame.add(panel_ten,BorderLayout.SOUTH); //フレームの詳細設定 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300,250); frame.setVisible(true); } //mainメソッドの定義 public static void main(String[] args){ Dentaku application = new Dentaku(); } }

    • ベストアンサー
    • Java
  • Swing自作コンポーネントをadd出来るように、

    JTextFieldやJButtonなどを一つにまとめたコンポーネントを自作し、それをadd()出来るようにしたいです。frame.add(自作のクラスのインスタンス)を可能にしたいです。 調べて、paintComponent()を使えば良いということはわかったのですが、Graphicsのインスタンス(?)に線を描いたり、円を描いたりする方法はわかりましたが、JButtonやJTextFieldなどをGraphicsのインスタンス(?)に追加する方法はわからず、paintComponent()を使うやり方はできませんでした。 paintComponent()も使わずに、自分のできる方法で、組んだものを一応載せます。 import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; public class MyComponentTest{ public static void main(String[] args){ JFrame frame = new JFrame("タイトル"); frame.setSize(400, 300); frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); // 2つのテキストフィールドと一つのボタンを4つ追加する frame.add(new TwoTextFieldsAndOneButton().getContent()); frame.add(new TwoTextFieldsAndOneButton().getContent()); frame.add(new TwoTextFieldsAndOneButton().getContent()); frame.add(new TwoTextFieldsAndOneButton().getContent()); frame.setVisible(true); } } //2つのテキストフィールドと一つのボタンを一つの部品にしたい class TwoTextFieldsAndOneButton{ JTextField textField1 = new JTextField("テキストフィールド1"); JTextField textField2 = new JTextField("テキストフィールド2"); JButton button = new JButton("ボタン"); // こんなメソッドを使わずに、再現したい JPanel getContent(){ JPanel panel = new JPanel(); panel.add(textField1); panel.add(textField2); panel.add(button); return panel; } }

    • ベストアンサー
    • Java
  • 【swing】ボタンクリックにより、パネルごとの差し替えを行う

    javaをはじめて2週間の_tonnuraと申します。 swingを用いて1枚のフレームに対し、ボタンクリックにより 画面遷移を行っていくアプリを作成しています。 最初の画面での画面遷移は成功するのですが、 その画面からの遷移のために、別のパネルを加えると画面が更新されません。初期画面→2枚目の画面→×3枚目の画面(2枚目のまま) 「getContentPane().list(System.out)」で確認したところ、物はあるようなので、「validate()」をかけているのですが変化なしです。 過去の質問に解決方法があると思い、検索で「QNo.196900 クリックでGUI部品を追加する」を見つけたのですが、コンポーネントに対するremoveAll後のvalidate()だけでは対処できませんでした。 以下にソースを記載します。 汚くて申し訳ありませんが、ご解答いただければ嬉しく思います。 ※actionPerformedにて、「KihonCore kihonC」に飛ばしていますが 処理として「各部品の定義・配置・新たに定義したパネルへのセット後 パネルをコンポーネントへ配置」を行っています。 ※画面遷移の順序としては 初期画面表示→//■2枚目の画面を貼り付け→//■初期画面を貼り付け(初期メニュー画面を描写)となっています。 ------------------------------------------------------------ package test; import java.awt.*; import javax.swing.*; import test.KihonCore.myListener; public class Menu extends JFrame implements ActionListener { public static void main(String[] args) { Menu frame_m = new Menu(); frame_m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame_m.setTitle("画面遷移テスト"); frame_m.setBounds(10, 10, 750, 570); frame_m.setVisible(true); frame_m.setResizable(false); } Menu() { SpringLayout layout = new SpringLayout(); JPanel panel_menu = new JPanel(); panel_menu.setLayout(layout); JButton btn_gozen = new JButton();         tn_gozen.addActionListener(this); btn_gozen.setActionCommand("btn_gozen");         btn_gozen.setPreferredSize(new Dimension(118, 45)); ImageIcon icon_gozen = new ImageIcon("./image/btn_gozen.png"); btn_gozen.setIcon(icon_gozen); panel_menu.add(btn_gozen); getContentPane().add(panel_menu); validate(); addWindowListener(new myListener(0)); System.out.println("起動直後の画面状態"); getContentPane().list(System.out); } public void actionPerformed(ActionEvent ae) { String cmd = ae.getActionCommand(); try { if (cmd.equals("btn_gozen")) { //■2枚目の画面を貼り付け getContentPane().removeAll(); KihonCore kihonC = new KihonCore(); kihonC.btnClk_MenuAm(getContentPane()); validate(); System.out.println("2画面目遷移後の画面状態"); getContentPane().list(System.out); } else if (cmd.equals("btn_b01")) { System.out.println("2画面目の1が押されました。"); } else if (cmd.equals("btn_b02")) { System.out.println("2画面目の2が押されました。。");// } else if (cmd.equals("btn_seiseki")) { System.out.println("メニューボタン4が押下されました。"); } else if (cmd.equals("btn_syuuryou")) { System.out.println("終了ボタンが押下されました。"); int option = JOptionPane.showConfirmDialog(null, "終了しますか?", "終了確認", JOptionPane.YES_NO_OPTION); if (option == JOptionPane.YES_OPTION) { System.out.println("はいを選択:終了"); System.exit(0); } else if (option == JOptionPane.NO_OPTION) { System.out.println("いいえを選択:終了しない"); return; } } else if (cmd.equals("btn_return")) { System.out.println("戻るボタンが押下されました。"); //■初期画面を貼り付け(初期メニュー画面を描写 getContentPane().removeAll(); KihonCore kihonC = new KihonCore(); kihonC.btnClk_Rtn(getContentPane()); validate(); System.out.println("2画面目にて戻るを押した直後の画面状態"); getContentPane().list(System.out); } } catch (Exception e) { System.out.println("エラーが発生しました"); e.printStackTrace(); } } }

    • ベストアンサー
    • 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
  • JavaのSwingのレイアウト

    Swingを学習中ですが、うまくレイアウトできません。 添付した画像のようなレイアウトにしたいです。 作ってみたものは以下です。 import java.awt.BorderLayout; import java.awt.Color; import javax.swing.*; public class LayoutTest { public static void main(String[] args) { JFrame frame = new JFrame(); JPanel panel = new JPanel(); JTextField searchFiled = new JTextField("テキスト"); String[] comboboxString = {"C", "C++", "Java"}; JComboBox comboBox = new JComboBox(comboboxString); JButton button = new JButton("ボタン"); panel.add(comboBox, BorderLayout.EAST); panel.add(searchFiled, BorderLayout.CENTER); panel.add(button, BorderLayout.WEST); frame.add(panel, BorderLayout.PAGE_START); JPanel redPanel = new JPanel(); redPanel.setBackground(Color.RED); frame.add(redPanel); frame.setSize(700, 500); frame.setLocationRelativeTo(null); frame.setVisible(true); } }

    • ベストアンサー
    • Java
  • swingのJframeについて

    JFrameについて質問があるのですが import javax.swing.*; public class JFrameTest extends JFrame{ public static void main(String[] args){ JFrameTest frame = new JFrameTest(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 300, 200); frame.setTitle("タイトル"); frame.setVisible(true); } JFrameTest(){ JPanel p = new JPanel();   Container contentPane = getContentPane(); ContentPane.add(p);   pack(); } } このプログラムと import javax.swing.*; public class JFrameTest{ public static void main(String[] args){ JFrame frame = new JFrame("フレームのタイトル"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds( 10, 10, 300, 200); frame.setVisible(true); JPanel p = new JPanel();   Container contentPane = frame.getContentPane(); frame.ContentPane.add(p);   frame.pack(); } } このプログラムは何が違うのでしょう? やってることはまったく一緒だと思ってたのですが、全然違うみたいです。 上のプログラムの JFrameTest(){ はコンストラクタと呼ばれるものなのでしょうか? しょぼい質問で申し訳ないのですが誰か教えていただけないでしょうか。

    • ベストアンサー
    • Java
  • JavaのSwingで別のフォームを閉じる方法

    こんにちは。 JavaのSwingにおいて,以下のようなプログラムがあるとします。 その場合,A.javaでボタンを押すと,B.javaのフォームが閉じるようにしたいのですがどのようにしたらいいのでしょうか?よろしくお願いします。 ****A.java**** import ☆省略☆; public class A extends JFrame implements ActionListener{ //ボタン JButton end; public A(){ //フレームの設定 setVisible(true); setTitle("テスト"); //コンテナの設定 con = getContentPane(); //ボタン end = new JButton(" 終了 "); end.addActionListener(this); end.setActionCommand("end"); con.add(end); pack(); } public void actionPerformed(ActionEvent e){ String m = e.getActionCommand(); if(m == "end"){ ※ここに書くべき処理 } } } ****B.java**** import ☆省略☆; public class B extends JFrame{ //コンテナ Container con; public Answer(){ //フレームの設定 setVisible(true); setTitle("B"); //コンテナに関わる設定 con = getContentPane(); } }

  • java swing での質問です。

    javaのプログラミングをeclipseでしているのですが swingで行き詰ってしまいました。 タブペインを使いタブパネルを作り、その中にボタンを配置したのですが、 ボタンの位置をsetBoundsで動かすことができませんでした。 他の命令を使わなければならないのでしょうか? プログラミング自体が初心者のため、説明に不備があると思いますが 助けていただけると幸いです。 ひどいプログラミングかと思いますが張らせていただきました package gui; import java.awt.*; import javax.swing.*; public class ReisyokuMenu extends JFrame{ /*serialVersionUID*/ private static final long serialVersionUID=1L; /*コンポーネント作成*/ JButton syokuzaiBtn = new JButton("食材一覧"); JButton syoumiBtn = new JButton("賞味期限順"); JButton bunruiBtn = new JButton("分類"); JButton returnBtn=new JButton("Topへ"); JPanel tabPanel1 = new JPanel(); JPanel tabPanel2 = new JPanel(); JTabbedPane tabbedpane = new JTabbedPane(); public ReisyokuMenu(){ /*Closeボタンでアプリケーションが終了しないように設定*/ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); /*フレームサイズを変更できないように設定*/ setResizable(false); /*フレームコンテナのインスタンスを生成*/ Container cPane = getContentPane(); /*レイアウトマネジャを利用しない(座標を指定する)*/ cPane.setLayout(null); setLocationRelativeTo(null); setSize(400, 380);//setBoundsはy、x、幅、高さを指定するのでsetLocationRelativeToで位置指定をする為に使用。 setTitle("一人暮らし支援ツール");//アプリケーションタイトルを入れる tabbedpane.addTab("食材を見る", tabPanel1); tabbedpane.addTab("食材を探す", tabPanel2); tabPanel1.add(syokuzaiBtn); tabPanel1.add(syoumiBtn); tabPanel1.add(bunruiBtn); syokuzaiBtn.setLocation(50, 80);//「選択」ボタン syoumiBtn.setBounds(10,10,325,120); bunruiBtn.setBounds(10,270,90,40); tabPanel2.add(new JLabel("食材名:")); tabPanel2.add(new JTextField("", 10)); setContentPane(tabbedpane); } public void setVisible(boolean isVisible){ if(isVisible){ /*フレームの表示位置を指定(x,y)*/ setLocation(200,200); } /*フレームを表示*/ super.setVisible(isVisible); } }

  • JFrameとJPanelの最大化について

    swingでアプリケーションを作成しています。 1つのフレーム上に複数のパネルを描画する(画面遷移)アプリです。 たとえば、ログイン用のパネル、メニュー用のパネルと言ったように用意しています。 ここで問題が発生しました。 フレームの最大化ボタンを押しても、パネルが最大化されず、パネル内に配置しているボタンなども位置の調整が行われません。 フレームにレイアウトマネージャーを指定しても、パネルは最大化されないのでしょうか? フレーム自体にボタンを配置すると調整はされるのですが・・・ 今のところクラス構成としては、 フレームクラス ログインパネルクラス メニューパネルクラス データ表示パネルクラス となっています。 ログインパネルのボタンを押されたら、ログインパネルを破棄し、メニューパネルを表示するといった作りにしています。 どのパネルを表示しているときにも、フレームの最大化ボタンが押された場合にパネルの最大化も行いたいのです。 どなたかご教授願えませんでしょうか?

    • ベストアンサー
    • Java