質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

13802閲覧

JFrameでのJPanelの切り替えについて

Hinantius246

総合スコア17

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/05/10 23:15

編集2017/05/11 09:35

###前提・実現したいこと
(例)Java(UIはJFrame)でゲームを作っているのですが、JPanelの切り替えをJFrameで行おうとしています。
しかし、JPanelの切り替えがうまくいきません。

なお、切り替えにはこのサイトのような切り替え方法を使っています。

###発生している問題

切り替え自体はどうやら成功しているようだが、パネルのボタンの表示がされない

###該当のソースコード
※作成中のゲームのため、一部関数を改変し、コメントはすべて除去した

Java

1package panels; 2 3import java.awt.BorderLayout; 4import java.awt.Container; 5import java.awt.event.WindowAdapter; 6import java.awt.event.WindowEvent; 7 8import javax.swing.JFrame; 9import javax.swing.JOptionPane; 10import javax.swing.JPanel; 11 12public class MainFrame extends JFrame{ 13 public String[] PanelNames = {"First","Second","Third"}; 14 FirstPanel fp = new FirstPanel(PanelNames[0]); 15 SecondPanel sp = new SecondPanel(PanelNames[1]); 16 ThirdPanel tp = new ThirdPanel(PanelNames[2]); 17 public JPanel[] jps = {fp,sp,tp}; 18 19 int i; 20 21 private static final int VERTICAL = 768; 22 private static final int HORIZONTAL = 1024; 23 24 public MainFrame(){ 25 super("Test"); 26 27 this.add(fp);fp.setVisible(true); 28 this.add(sp);sp.setVisible(false); 29 this.add(tp);tp.setVisible(false); 30 31 setBounds(100, 100, 300, 250); 32 33 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 34 addWindowListener(new WindowClosing()); 35 36 setSize(HORIZONTAL,VERTICAL); 37 38 setResizable(false); 39 40 Container contentPane = getContentPane(); 41 contentPane.add(jps[i], BorderLayout.CENTER); 42 43 setVisible(true); 44 } 45 46 class WindowClosing extends WindowAdapter{ 47 public void windowClosing(WindowEvent e) { 48 int ans = JOptionPane.showConfirmDialog 49 (MainFrame.this, "本当に終了しますか?"); 50 if(ans == JOptionPane.YES_OPTION) { 51 System.exit(0); 52 } 53 } 54 } 55 56 public void changeKey(JPanel jp, String str){ 57 System.out.println(jp.getName()); 58 String name = jp.getName(); 59 if (name==PanelNames[0]){ 60 fp = (FirstPanel)jp; 61 fp.setVisible(false); 62 System.out.println("〇"); 63 } else if (name==PanelNames[1]){ 64 sp = (SecondPanel)jp; 65 sp.setVisible(false); 66 System.out.println("●"); 67 } else if (name==PanelNames[2]){ 68 tp = (ThirdPanel)jp; 69 tp.setVisible(false); 70 System.out.println("◎"); 71 } else { 72 System.out.println("huh?"); 73 } 74 75 76 if (str==PanelNames[0]){ 77 fp.setVisible(true); 78 //iで切り替え! 79 i = 0; 80 System.out.println("△"); 81 } else if (str==PanelNames[1]){ 82 sp.setVisible(true); 83 i = 1; 84 System.out.println("▼"); 85 } else if (str==PanelNames[2]){ 86 tp.setVisible(true); 87 i = 2; 88 System.out.println("▲"); 89 } else { 90 System.out.println("huh?"); 91 } 92 } 93} 94 95package panels; 96 97import java.awt.event.ActionEvent; 98import java.awt.event.ActionListener; 99 100import javax.swing.JButton; 101import javax.swing.JPanel; 102 103package panels; 104 105import java.awt.Font; 106import java.awt.event.ActionEvent; 107import java.awt.event.ActionListener; 108 109import javax.swing.JButton; 110import javax.swing.JLabel; 111import javax.swing.JPanel; 112 113public class FirstPanel extends JPanel implements ActionListener{ 114 String str; 115 116 public FirstPanel(String s){ 117 str = s; 118 this.setName("First"); 119 //setLocationRelativeTo(null); 120 setLayout(null); 121 122 JLabel titleLabel = new JLabel("FirstPanel"); 123 124 titleLabel.setBounds(270, 100, 512, 100); 125 126 titleLabel.setFont(new Font("MS ゴシック", Font.BOLD, 64)); 127 titleLabel.setHorizontalTextPosition(JLabel.CENTER); 128 129 JButton buttonOne = new JButton("One"); 130 buttonOne.setBounds(256, 350, 512, 50); 131 buttonOne.addActionListener(this); 132 buttonOne.setActionCommand("One"); 133 134 JButton buttonTwo = new JButton("Two"); 135 buttonTwo.setBounds(256, 400, 512, 50); 136 buttonTwo.addActionListener(this); 137 buttonTwo.setActionCommand("Two"); 138 139 JButton buttonThree = new JButton("Three"); 140 buttonThree.setBounds(256, 4050, 512, 50); 141 buttonThree.addActionListener(this); 142 buttonThree.setActionCommand("Three"); 143 144 JButton buttonFour = new JButton("Four"); 145 buttonFour.setBounds(256, 500, 512, 50); 146 buttonFour.addActionListener(this); 147 buttonFour.setActionCommand("Four"); 148 149 JButton buttonFive = new JButton("Five"); 150 buttonFive.setBounds(256, 550, 512, 50); 151 buttonFive.addActionListener(this); 152 buttonFive.setActionCommand("Five"); 153 154 add(titleLabel); 155 add(buttonOne); 156 add(buttonTwo); 157 add(buttonThree); 158 add(buttonFour); 159 add(buttonFive); 160 161 } 162 163 164 @Override 165 public void actionPerformed(ActionEvent e) { 166 String cmd = e.getActionCommand(); 167 System.out.println(cmd); 168 169 switch(cmd){ 170 171 case "One": 172 break; 173 case "Two": 174 break; 175 case "Three": 176 break; 177 case "Four": 178 break; 179 case "Five": 180 System.exit(0); 181 break; 182 183 default: 184 //何もない場合はreturnで切る 185 return; 186 } 187 188 } 189} 190SecondPanelThirdPanelはこれと同じなので省略 191

###試したこと

  • SecondPanelのみをMainにして起動→動作する
  • MainFrameのFirstPanelをfalseにしてSecondPanelをtrueにする→動作しない(ThirdPanelでも動作しない)
  • 切り替え時にコンソール上に文字を表記→切り替え時の文字は表記される
  • FirstPanelからFirstPanelに転送→表示される

###補足情報(言語/FW/ツール等のバージョンなど)
Java8(Eclipse)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umyu

2017/05/11 00:49

多分、行いたいことはゲームのシーン遷移だと思いますがー。。質問文のコードではコンパイルエラーになります! 1,FirstPanelのコンストラクタが一致してません。2,MainFrameコンストラクタのsuper(Main.title);3,同コンストラクタdp.setVisible(false);
guest

回答1

0

ベストアンサー

JPanelの切り替えにCardLayoutを使用。

MainFrame クラス

Java

1package panels; 2 3import java.awt.Container; 4import java.awt.event.WindowAdapter; 5 6import java.awt.CardLayout; 7import java.awt.event.WindowEvent; 8 9import javax.swing.JFrame; 10import javax.swing.JOptionPane; 11import javax.swing.JPanel; 12 13import java.util.Arrays; 14 15public class MainFrame extends JFrame { 16 public String[] PanelNames = { "First", "Second", "Third" }; 17 JPanel fp = new FirstPanel(this, PanelNames[0]); 18 JPanel sp = new SecondPanel(this, PanelNames[1]); 19 JPanel tp = new ThirdPanel(this, PanelNames[2]); 20 public JPanel[] jps = { fp, sp, tp }; 21 private final CardLayout layout = new CardLayout();//カードレイアウト 22 23 private static final int VERTICAL = 768; 24 private static final int HORIZONTAL = 1024; 25 26 public MainFrame() { 27 super("Test"); 28 setBounds(100, 100, 300, 250); 29 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 30 addWindowListener(new WindowClosing()); 31 setSize(HORIZONTAL, VERTICAL); 32 // CardLayoutを使用。 33 Container contentPane = getContentPane(); 34 JPanel mainPanel = new JPanel(); 35 mainPanel.setLayout(layout); 36 for (JPanel panel : jps){ 37 mainPanel.add(panel, panel.getName()); 38 } 39 contentPane.add(mainPanel); 40 41 setResizable(false); 42 setVisible(true); 43 } 44 45 class WindowClosing extends WindowAdapter { 46 public void windowClosing(WindowEvent e) { 47 int ans = JOptionPane.showConfirmDialog(MainFrame.this, "本当に終了しますか?"); 48 if (ans == JOptionPane.YES_OPTION) { 49 System.exit(0); 50 } 51 } 52 } 53 54 // changeKey=>changePanelにメソッド名を変更して、引数を1個に 55 public void changePanel(String str) { 56 int index = Arrays.asList(PanelNames).indexOf(str); 57 layout.show(jps[index].getParent(), jps[index].getName()); 58 } 59}

FirstPanelクラス

Java

1package panels; 2 3import java.awt.Font; 4import java.awt.event.ActionEvent; 5import java.awt.event.ActionListener; 6 7import javax.swing.JButton; 8import javax.swing.JLabel; 9import javax.swing.JPanel; 10 11public class FirstPanel extends JPanel implements ActionListener{ 12 private final String str; 13 private final MainFrame frame; // インスタンス変数でMainFrameの参照を保持 14 public FirstPanel(MainFrame f, String s){ 15 str = s; 16 frame = f; 17 this.setName(s);//固定文字列ではなく、コンストラクタで渡された文字列に変更 18 //setLocationRelativeTo(null); 19 setLayout(null); 20 21 JLabel titleLabel = new JLabel(s);//固定文字列ではなく、コンストラクタで渡された文字列に変更 22 23 titleLabel.setBounds(270, 100, 512, 100); 24 25 titleLabel.setFont(new Font("MS ゴシック", Font.BOLD, 64)); 26 titleLabel.setHorizontalTextPosition(JLabel.CENTER); 27 28 JButton buttonOne = new JButton("One"); 29 buttonOne.setBounds(256, 350, 512, 50); 30 buttonOne.addActionListener(this); 31 buttonOne.setActionCommand("One"); 32 33 JButton buttonTwo = new JButton("Two"); 34 buttonTwo.setBounds(256, 400, 512, 50); 35 buttonTwo.addActionListener(this); 36 buttonTwo.setActionCommand("Two"); 37 38 JButton buttonThree = new JButton("Three"); 39 // setBounds の引数y 4050=> 450 40 buttonThree.setBounds(256, 450, 512, 50); 41 buttonThree.addActionListener(this); 42 buttonThree.setActionCommand("Three"); 43 44 JButton buttonFour = new JButton("Four"); 45 buttonFour.setBounds(256, 500, 512, 50); 46 buttonFour.addActionListener(this); 47 buttonFour.setActionCommand("Four"); 48 49 JButton buttonFive = new JButton("Five"); 50 buttonFive.setBounds(256, 550, 512, 50); 51 buttonFive.addActionListener(this); 52 buttonFive.setActionCommand("Five"); 53 54 add(titleLabel); 55 add(buttonOne); 56 add(buttonTwo); 57 add(buttonThree); 58 add(buttonFour); 59 add(buttonFive); 60 61 } 62 63 64 @Override 65 public void actionPerformed(ActionEvent e) { 66 String cmd = e.getActionCommand(); 67 System.out.println(cmd); 68 69 switch(cmd){ 70 71 case "One": 72 //MainFrame#changePanelを呼び出す。 73 frame.changePanel("First"); 74 break; 75 case "Two": 76 frame.changePanel("Second"); 77 break; 78 case "Three": 79 break; 80 case "Four": 81 frame.changePanel("Third"); 82 break; 83 case "Five": 84 System.exit(0); 85 break; 86 87 default: 88 //何もない場合はreturnで切る 89 return; 90 } 91 92 } 93}

MainFrame#changeKeyメソッドでFirstPanelをsetVisible(false);にすると親のcontentPaneが表示されて遷移したように見えるだけなのです。

Swingのコンポーネントのデバックをする時は、
JFrameをクリックしてフォーカスを当てた状態でCTRL+Shit+F1キーを押下すると、コンソールにSwingのコンポーネントツリーが出力されます。


画面遷移の管理について
0. 遷移を管理するためのシーンクラスを作成(シングルトン)
0. 画面の遷移元と遷移先をツリー構造で管理する。

JFrameを継承したクラスにいろいろな処理を書くのは個人的に好きではないのでこれがベターだと思います。

投稿2017/05/11 15:15

編集2017/05/11 20:00
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hinantius246

2017/05/12 00:27

ありがとうございました。これで動くようになりました。CardLayoutも一度は考えたのですが難しくてやめてしまいましたが、これでできるようになりました。これからも頑張りたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問