43

簡単に言うと、いくつかのコンポーネントを含む JFrame で構成される単純な Java swing アプリがあります。コンポーネントの 1 つは JPanel であり、ユーザーのアクションで別の JPanel に置き換えられることを意図しています。

それで、そのようなことをする正しい方法は何ですか?私はもう試した

panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();

しかし、これはうまくいきません。何を提案しますか?

4

14 に答える 14

52

あなたのユースケースは、CardLayoutに最適です。

カード レイアウトでは、同じ場所に複数のパネルを追加できますが、一度に 1 つのパネルを表示または非表示にできます。

于 2008-10-20T14:00:58.233 に答える
28

1) 最初のパネルの設定:

JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());

2) パネルの交換:

frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());

また、 SwingUtilities.invokeLaterまたはSwingWorkerを確実に使用するには、イベントのスレッドでこれを行う必要があることに注意してください。

于 2008-10-20T13:10:03.343 に答える
22
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.

Javaは「値による参照のコピー」引数の受け渡しを使用することを忘れないでください。したがって、変数を変更しても、他のメソッドに渡される参照のコピーは変更されません。

JFrameまた、使いやすさという名目で非常に紛らわしいことに注意してください。コンポーネントの追加またはレイアウトの設定(通常)は、コンテンツペインで操作を実行します。奇妙なことに、レイアウトを取得すると、フレームのレイアウトマネージャーが実際に得られます。

于 2008-10-20T12:31:26.590 に答える
7

このコードが、JFrame 内の jPanels を変更するアイデアを提供してくれることを願っています。

public class PanelTest extends JFrame {

        Container contentPane;

        public PanelTest()  {
           super("Changing JPanel inside a JFrame");
           contentPane=getContentPane();
        }

        public void createChangePanel() {
           contentPane.removeAll();
           JPanel newPanel=new JPanel();
           contentPane.add(newPanel);
           System.out.println("new panel created");//for debugging purposes
           validate();
           setVisible(true);
        }
}
于 2009-05-22T05:16:23.143 に答える
5

ユーザーの処置について:

//あなたはの線に沿って何かをしなければなりません

myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()

myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()

次に、必要に応じてウィンドウのサイズを変更できます。

于 2008-10-21T15:12:16.017 に答える
3

それはすべて、その使用方法に依存します。これら 2 つのパネルを切り替えたい場合は、CardLayout を使用します。最初から2番目に1回だけ切り替えて(そして戻らない)場合は、telcontarの提案を使用して、それを置き換えるだけです。ただし、JPanel がフレーム内の唯一のものではない場合は 、removeAll の代わりにremove(java.awt.Component)を使用します。

これら 2 つのケースの中間にいる場合は、基本的に時空間のトレードオフです。CardLayout は時間を節約しますが、この他のパネル全体を常にメモリに保持する必要があるため、より多くのメモリを消費します。しかし、必要に応じてパネルを交換し、オンデマンドで構築するだけでは、そのメモリを保持する必要はありませんが、切り替えに時間がかかります.

また、代わりに JTabbedPane を試してタブを使用することもできます (表示/非表示を自動的に処理するため、CardLayout よりも簡単です)。

于 2008-10-20T15:06:37.807 に答える
1

私はまったく同じ問題を抱えていました!! 信じられない!私が見つけた解決策は次のとおりです。

  1. すべてのコンポーネント(JPanels)をコンテナーに追加します。
  2. それらすべてにsetVisible(false)メソッドを使用します。
  3. ユーザーアクションで、表示したいパネルにsetVisible(true)を設定します。
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
      component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);

revalidate()、validate()、CardLayoutは必要ありません。

于 2011-05-20T07:47:56.717 に答える
1

layout.replace() の回答は、GroupLayout Manager でのみ存在/機能します。

他の LayoutManagers (CardLayout、BoxLayout など) はこの機能をサポートしていませんが、最初に RemoveLayoutComponent( を実行し、次に AddLayoutComponent( を再度実行する必要があります。:-) [記録をまっすぐに設定する]

于 2015-09-11T02:59:12.137 に答える
1

他の個人は質問に答えました。コンテンツを置き換える代わりに、JTabbedPane を使用することをお勧めします。原則として、アプリケーションの視覚要素が消えたり、他のコンテンツに置き換えられたりすることは良くありません。確かにすべての規則には例外があり、あなたとあなたのユーザー コミュニティだけが最善のアプローチを決定できます。

于 2008-10-20T13:11:19.893 に答える
1

問題: コンポーネントをコンテナに追加した後、コンポーネントが表示されません。

コンポーネントを追加した後、コンポーネントがコンテナに表示される前に、 revalidateを呼び出して再描画 する必要があります。

ソース: http://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html

于 2012-04-23T10:11:57.413 に答える
0

フレームの作成時に両方のパネルを追加し、両方で setVisible(true/false) を呼び出して表示パネルを変更することをお勧めします。setVisible を呼び出すと、親は通知を受け、自分自身を再描画するよう求められます。

于 2008-10-20T13:09:15.873 に答える
0
class Frame1 extends javax.swing.JFrame {

    remove(previouspanel); //or getContentPane().removeAll();

    add(newpanel); //or setContentPane(newpanel);

    invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();

    repaint(); //DO NOT FORGET REPAINT

}

再検証を使用せずに作業を実行できる場合もあれば、再描画を使用せずに作業を実行できる場合もあります。両方を使用することをお勧めします。

于 2012-02-26T15:54:26.270 に答える
0

次のように, ( 、多分古い)を設定した後、メソッドpack()を呼び出すだけです:ContentPanejava 1.7

JFrame frame = new JFrame();  
JPanel panel1 = new JPanel(); 
JPanel panel2 = new JPanel(); 
....
frame.setContentPane(panel1);
frame.pack();
...

frame.setContentPane(panel2);
frame.pack();
...
于 2012-08-09T04:27:00.923 に答える