
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() にしたり出来そうな事を色々試したつもりではいるのですが、うまくいきません…
ボタン押下後に、ウィンドウの枠をクリックすると描画されるのですが、いまいちよくわかりません…
なにか分かる方いらっしゃいましたらご教授願います。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
ページ遷移とやりかたとして2つの方法があります。
・ページ遷移の際に次のページを追加して、今のページを削除する
常に一枚のパネルしか乗っていないので処理が軽いです。
その代わり、遷移の速度が遅くなります。
なので、パネルの枚数が多いときに向いていますね。
・あらかじめ全てのページを追加しておいてページ遷移の際に切り替える
パネルの遷移速度が速いです。
ですが、乗っているパネルの枚数から当然前者よりは重くなります。
パネルが少なければ気にならない程度ですが、多くなりすぎるとアプリケーション自体が重くなることもあります。
パネル総数が少ないときに実装するとより効率的になります。
今回のプログラムはパネルが2枚と少ないので後者のほうがよいといえます。
rancoさんの言うとおり作るものに適した実装のしかたをしましょう。
まずはレイアウトの種類と特徴,AWTとSwingの違いなどを勉強なさると良いでしょう。
他にも、類似的な機能の一長一短といったことも把握した上で考えるといい設計ができると思いますよ。
zozyさん、再度ご回答ありがとうございます。
なるほどです。
おっしゃっていただいたことを今後GUIプログラムを組むときに参考にさせていただこうと思います!
AWTとSwingの違いというところも今まであまり意識したことが無かったので、ちょっと調べようかと思います…
ありがとうございました。
No.3
- 回答日時:
z...さんも言うように、アプリケーションレベルの要求を具体的に説明すべきです。
いちいちremove - new - addするのが、その要求の最適の実装ならば、JFrameのcontentPaneはデフォルトではJPanelなので、JPanelにキャストできます。そしてJPanelに限らず、Swingのコンテナは、なにかがaddされたあと、invalidate/validateではなく、単純にrevalidateだけをコールします。
参考URL:http://homepage1.nifty.com/algafield/JavaGUIFaq1 …
_ranco_さん、ご回答ありがとうございます。
何をするアプリケーションを作りたいのか?ということを説明すべきということですよね…失礼致しました。
「どれがいいか」というよりも、最適なものを選んで実装するということですね。
revalidate() は試してみたところ、すぐに再描画することができました。
ありがとうございました。
No.2
- 回答日時:
逆に質問があるのですが、なんのためにパネルを新しく生成するのですか?
この場合はボーダーレイアウトではなく、カードレイアウトを適応するのが上策と適切だと思います。
いちいち生成して前のパネルを削除していくのでは効率が悪いです。
カードレイアウトとはあらかじめコンテナにパネルを追加しておき、必要に応じてパネルを表示するレイアウトです。
コンテナまたはフレームがプレイヤー,パネルがカードでプレイヤーがカードを選択するのをイメージしてもらえるとわかりやすいでしょう。
サンプルとして、ページ切り替えのたびpanelのバックカラーを変更するものを作りましたので参考にしていただけると幸いです。
//インポートを1つずつ宣言しているのはメモリ節約のため
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Test2 extends JFrame{
//カードレイアウトの宣言
CardLayout layout=new CardLayout();
JPanel panel=new JPanel();
JPanel btnp=new JPanel();
JButton btn=new JButton("再描画");
JButton back=new JButton("戻る");
//乱数の宣言
Random r=new Random();
//panelのバックカラー
int red,green,blue;
public Test2(){
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//親フレームをカードレイアウトに設定
getContentPane().setLayout(layout);
//btnにリスナを追加し、カプセル化してます。
//明示的にリスナを区別するため、バグが発生しにくくなる
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
btnPush(evt);
}
});
back.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
backPush(evt);
}
});
//btnpのレイアウトをグループレイアウトに設定
//グループレイアウトとはコンポーネントを自由配置できるレイアウトです
//階層型のため複雑になるので注意
GroupLayout btnpLayout=new GroupLayout(btnp);
btnp.setLayout(btnpLayout);
//水平方向の配置を設定してます
btnpLayout.setHorizontalGroup(
//左上からコンポーネントを配置します
btnpLayout.createParallelGroup()
//引数はそれぞれ,配置するコンポーネント,最小サイズ,実際のサイズ,最大サイズ
.addComponent(btn,0,300,300)
);
//垂直方向の配置を設定してます
btnpLayout.setVerticalGroup(
btnpLayout.createParallelGroup()
.addGroup(btnpLayout.createSequentialGroup()
.addGap(250,250,250)
.addComponent(btn))
);
//addの2個目の引数はカード名といい、ページ切り替えの際指定する文字列です
getContentPane().add(btnp,"btnp");
GroupLayout panelLayout=new GroupLayout(panel);
panel.setLayout(panelLayout);
panelLayout.setHorizontalGroup(
panelLayout.createParallelGroup()
.addComponent(back,0,300,300)
);
panelLayout.setVerticalGroup(
panelLayout.createParallelGroup()
.addGroup(panelLayout.createSequentialGroup()
.addGap(250,250,250)
.addComponent(back))
);
getContentPane().add(panel,"panel");
//追加したコンポーネントをみてウィンドウを推奨サイズに設定してくれます
pack();
}
private void btnPush(java.awt.event.ActionEvent evt){
red=r.nextInt(256);
green=r.nextInt(256);
blue=r.nextInt(256);
panel.setBackground(new Color(red,green,blue));
layout.show(getContentPane(),"panel");
}
private void backPush(java.awt.event.ActionEvent evt){
layout.show(getContentPane(),"btnp");
}
public static void main(String args[]) {
new Test2().setVisible(true);
}
}
zozyさん、ご回答ありがとうございます。
カードレイアウトを一度試したのですがうまくいかなかったので今のような手段をとってしまったのですが…(恐らく私のコードがどっか間違っていたのでしょうが…)
やはりカードレイアウトの方が効率がいいのでしょうか…?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
JPanelの切り替えと再描画
-
JPanelの重ね方/OverlayLayout他
-
ボタンクリック後パネルを再描...
-
javaで文字数制限するには?
-
パソコンキーボードで時分秒を...
-
IF関数でEmpty値を設定する方法。
-
java プログラミングについて
-
0dの意味を教えてください
-
C言語の変数(LSB)の合わせ込...
-
ループ処理の際、最後だけ","を...
-
複数のテキストボックスに同じ...
-
doubleとintの違い
-
JAVAでSJISのコード変換
-
system.out.printが出力されない
-
C言語のポインターに関する警告
-
n番目に大きな値を探索する
-
BOOL値を逆にしたい
-
この警告はどうすれば?
-
1~100までの数字を表示し、か...
-
javaの演算子の部分ですが 4行...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
java junit list同士の比較方法
-
javaで文字数制限するには?
-
JPanelの重ね方/OverlayLayout他
-
ArrayListの使い方について(初...
-
TextAreaでの文字の色
-
JPanelの切り替えと再描画
-
setPrefferedSizeとsetSize
-
JFrameとJPanelの最大化について
-
【Swing】JPanel クラス外から...
-
フレームを閉じれない
-
Buttonを押すと画像が表示され...
-
JDialogを閉じた時の処理
-
BMI測定を作ろうとしている...
-
Java-Swing TextAreaにスクロー...
-
ボールが勝手に動き困ってます。
-
Javaについて
-
エラーで式の開始が不正ですと...
-
KeyListenerの使い方について
-
Enterキーでボタンを押すにはど...
-
4択クイズでのランダム出題の...
おすすめ情報