JFrame内のJPanelをその場で変更するにはどうすればよいですか?
-
03-07-2019 - |
質問
簡単に言うと、いくつかのコンポーネントを含むJFrameで構成される単純なjava swingアプリがあります。コンポーネントの1つは、ユーザーアクションで別のJPanelに置き換えられることを意図したJPanelです。
それで、そのようなことをする正しい方法は何ですか?試しました
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
しかし、これは機能しません。あなたは何を提案しますか?
解決
あなたのユースケースは、 CardLayout に最適です。
カードレイアウトでは、同じ場所に複数のパネルを追加できますが、一度に1つのパネルを表示または非表示にできます。
他のヒント
1)最初のパネルの設定:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)パネルの交換:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
Javaは「値による参照のコピー」引数の受け渡しを使用します。したがって、変数を変更しても、他のメソッドに渡される参照のコピーは変更されません。
また、 JFrame
はユーザビリティの名において非常に紛らわしいことに注意してください。コンポーネントの追加またはレイアウトの設定(通常)は、コンテンツペインで操作を実行します。奇妙なことに、レイアウトを取得すると、実際にフレームのレイアウトマネージャーが表示されます。
このコードは、JFrame内でjPanelを変更するアイデアを提供します。
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);
}
}
ユーザーアクション:
//の線に沿って何かをする必要があります
myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
その後、必要に応じてウィンドウのサイズを変更できます。
すべては、その使用方法に依存します。これら2つのパネル間を行き来する場合は、CardLayoutを使用します。 1回目から2回目のみに切り替えて(戻らない)場合は、 telcontar sの提案を使用します単に交換してください。 JPanelがあなたのフレームの唯一のものではない場合、私は使用しますが remove(java .awt.Component) removeAllではなく。
これら2つのケースの中間にいる場合は、基本的に時間と空間のトレードオフです。 CardLayoutは時間を節約しますが、この他のパネル全体を常にメモリに保持する必要があるため、より多くのメモリを使用します。ただし、必要に応じてパネルを交換し、必要に応じてパネルを構築する場合、その記憶を維持する必要はありませんが、切り替えるのに時間がかかります。
また、代わりにタブを使用するJTabbedPaneを試すことができます(表示/非表示を自動的に処理するため、CardLayoutよりも簡単です)
他の個人が質問に答えました。コンテンツを置き換える代わりに、JTabbedPaneを使用することをお勧めします。一般的なルールとして、アプリケーションの視覚的な要素が消えたり、他のコンテンツに置き換えられたりするのは良くありません。確かにすべてのルールには例外があり、あなたとあなたのユーザーコミュニティだけが最良のアプローチを決定できます。
問題:コンテナにコンポーネントを追加した後、コンポーネントが表示されません。
を呼び出す必要があります。再検証および repaint コンポーネントを追加した後、コンテナに表示される前に。
出典: http://docs.oracle.com/javase/ tutorial / uiswing / layout / problems.html
まったく同じ問題を抱えていました!!インクレディブル!!私が見つけた解決策は次のとおりです。
- コンテナへのすべてのコンポーネント(JPanels)の追加;
- すべてにsetVisible(false)メソッドを使用する;
- ユーザーアクションで、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は不要です。
layout.replace()回答は、GroupLayout Managerでのみ存在/動作します。
他のLayoutManagers(CardLayout、BoxLayoutなど)はこの機能をサポートしていませんが、最初にRemoveLayoutComponent(を、次にAddLayoutComponent(を再び戻します。
フレームの作成時に両方のパネルを追加し、両方でsetVisible(true / false)を呼び出して表示パネルを変更することをお勧めします。 setVisibleを呼び出すと、親に通知され、自分自身を再描画するように求められます。
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
}
再検証を使用せず、場合によっては再ペイントを使用せずに作業を実行できる場合があります。両方を使用することをお勧めします。
ContentPane
を設定した後、 pack()メソッドを呼び出すだけです( java 1.7
、おそらく古い):
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...
レイアウトのreplaceメソッドを使用できます:
layout.replace(existingComponent, newComponent)
既存および新規のコンポーネントもJPanelsにすることができます。