我是Java的新手,我对面板有疑问。我的程序中有一个JFrame
和两个JPanels
。
button1
时,panel1
将显示在框架中。 button2
时,panel2
将显示在框架中,panel1
将消失/隐藏。 问题是panel1
无法仅显示panel2
。如何以这种方式显示两个面板?
这是我的代码:
public class test{
public static void main(String args[]){
JButton b1 = new JButton("show p1");
JButton b2 = new JButton("show p2");
JLabel l1 = new JLabel("This is p1");
JLabel l2 = new JLabel("This is p2");
final JPanel p1 = new JPanel(new FlowLayout());
p1.add(l1);
final JPanel p2 = new JPanel(new FlowLayout());
p2.add(l2);
JPanel buttonPNL = new JPanel(new FlowLayout());
buttonPNL.add(b1);
buttonPNL.add(b2);
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
p1.setVisible(true);
p2.setVisible(false);
}
});
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
p1.setVisible(false);
p2.setVisible(true);
}
});
JFrame frm = new JFrame();
frm.setLayout(new BorderLayout());
frm.add(p1,BorderLayout.CENTER);
frm.add(p2,BorderLayout.CENTER);
frm.add(buttonPNL,BorderLayout.SOUTH);
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(300,300);
}
}
答案 0 :(得分:6)
BorderLayout只能处理每个约束的一个组件,即在CENTER中添加p2的那一刻,p1被遗忘。因此,要么删除/添加actionListeners,要么使用另一个LayoutManager,如f.i. CardLayout
答案 1 :(得分:3)
要实现此类目标,您需要使用CardLayout。
此外,从JFrame中删除旧的JPanel以添加新的JPanel后,请始终在JFrame上执行revalidate()和repaint()以实现更改。请记住,在任何给定位置的任何给定时间只能添加一个组件。请尝试修改此代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PanelTest
{
public PanelTest()
{
JButton b1 = new JButton("show p1");
JButton b2 = new JButton("show p2");
JLabel l1 = new JLabel("This is p1");
JLabel l2 = new JLabel("This is p2");
final JPanel p1 = new JPanel(new FlowLayout());
p1.add(l1);
final JPanel p2 = new JPanel(new FlowLayout());
p2.add(l2);
JPanel buttonPNL = new JPanel(new FlowLayout());
buttonPNL.add(b1);
buttonPNL.add(b2);
final JFrame frm = new JFrame(); // shifted this line here.
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
// Added by me , these three lines
if (p2.isShowing())
{
frm.remove(p2);
frm.add(p1, BorderLayout.CENTER);
frm.revalidate(); // for JDK 1.7+
//frm.getRootPane().revalidate(); // for JDK 1.6 or lower
frm.repaint();
}
}
});
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (p1.isShowing())
{
frm.remove(p1);
frm.add(p2, BorderLayout.CENTER);
// Added by me , these three lines
frm.revalidate(); // for JDK 1.7+
//frm.getRootPane().revalidate(); // for JDK 1.6 or lower
frm.repaint();
}
}
});
frm.setLayout(new BorderLayout());
frm.add(p1,BorderLayout.CENTER);
frm.add(buttonPNL,BorderLayout.SOUTH);
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(300,300);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PanelTest();
}
});
}
}
答案 2 :(得分:2)
我认为问题是你在CENTER中只能有一个JComponent。因此,将两个面板包裹在一个面板中,只在CENTER中包含它:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JFrameProblem {
public static void main(String[] args){
JButton b1 = new JButton("show p1"); JButton b2 = new JButton("show p2");
JLabel l1 = new JLabel("This is p1");
JLabel l2 = new JLabel("This is p2");
final JPanel p1 = new JPanel(new FlowLayout());
p1.add(l1);
final JPanel p2 = new JPanel(new FlowLayout());
p2.add(l2);
p2.setVisible(false);
JPanel panelPNL = new JPanel(new FlowLayout());
panelPNL.add(p1);
panelPNL.add(p2);
JPanel buttonPNL = new JPanel(new FlowLayout());
buttonPNL.add(b1);
buttonPNL.add(b2);
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
p1.setVisible(true);
p2.setVisible(false);
}
});
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
p1.setVisible(false);
p2.setVisible(true);
}
});
JFrame frm = new JFrame();
frm.setLayout(new BorderLayout());
frm.add(panelPNL,BorderLayout.CENTER);
frm.add(buttonPNL, BorderLayout.SOUTH);
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(300,300);
frm.pack();
frm.setVisible(true);
}
}
答案 3 :(得分:2)
我将使用选项卡式窗格来实现此功能。有关详细信息,请参阅How to Use Tabbed Panes。
答案 4 :(得分:1)
您可以使用BorderLayout执行此操作,您只需记住重新添加要显示的面板。实际上你已经解决了重估问题,因为你正在使用setVisible()。
这基本上就是kleopatra所说的 - 这是代码:
JButton b1 = new JButton("show p1");
JButton b2 = new JButton("show p2");
JLabel l1 = new JLabel("This is p1");
JLabel l2 = new JLabel("This is p2");
final JPanel p1 = new JPanel(new FlowLayout());
p1.add(l1);
final JPanel p2 = new JPanel(new FlowLayout());
p2.add(l2);
JPanel buttonPNL = new JPanel(new FlowLayout());
buttonPNL.add(b1);
buttonPNL.add(b2);
final JFrame frm = new JFrame();
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
p1.setVisible(true);
p2.setVisible(false);
frm.add(p1, BorderLayout.CENTER);
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
p1.setVisible(false);
p2.setVisible(true);
frm.add(p2, BorderLayout.CENTER);
}
});
frm.setLayout(new BorderLayout());
frm.add(p1, BorderLayout.CENTER);
p2.setVisible(false); // initial state
frm.add(buttonPNL, BorderLayout.SOUTH);
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(300, 300);