如何隐藏当前的JPanel并使用Java中的按钮显示新的JPanel?

不幸的是,我不得不在这个程序中使用多个窗口,我不认为CardLayout会起作用,因为我不能在不同的布局之间保持任何按钮不变。 所以我试图编写一个按钮来隐藏当前的JPanel(thePanel)并显示一个新的(thePlacebo)。

我试图在ActionListener中隐藏thePanel,如下所示:

frame.getContentPane().remove(thePanel); 

我认为这样可行,但只要按下按钮就会冻结我的程序。

这是上下文代码的一大块:

 public class Reflexology1 extends JFrame{ JButton button1, button2; JButton movingButton; JTextArea textArea1; int buttonAClicked, buttonDClicked; private long _openTime = 0; private long _closeTime = 0; JPanel thePanel = new JPanel(); JPanel thePlacebo = new JPanel(); final JFrame frame = new JFrame("Reflexology"); public static void main(String[] args){ new Reflexology1(); } public Reflexology1(){ frame.setSize(600, 475); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("Reflexology 1.0"); frame.setResizable(false); button1 = new JButton("Accept"); button2 = new JButton("Decline"); movingButton = new JButton("Click Me"); ListenForAcceptButton lForAButton = new ListenForAcceptButton(); ListenForDeclineButton lForDButton = new ListenForDeclineButton(); button1.addActionListener(lForAButton); button2.addActionListener(lForDButton); //movingButton.addActionListener(lForMButton); JTextArea textArea1 = new JTextArea(24, 50); textArea1.setText("Tracking Events\n"); textArea1.setLineWrap(true); textArea1.setWrapStyleWord(true); textArea1.setSize(15, 50); FileReader reader = null; try { reader = new FileReader("EULA.txt"); textArea1.read(reader, "EULA.txt"); } catch (IOException exception) { System.err.println("Problem loading file"); exception.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException exception) { System.err.println("Error closing reader"); exception.printStackTrace(); } } } JScrollPane scrollBar1 = new JScrollPane(textArea1, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); AdjustmentListener listener = new MyAdjustmentListener(); thePanel.add(scrollBar1); thePanel.add(button1); thePanel.add(button2); thePlacebo.add(movingButton); frame.add(thePanel); ListenForWindow lForWindow = new ListenForWindow(); frame.addWindowListener(lForWindow); frame.setVisible(true); } // Implement listeners private class ListenForAcceptButton implements ActionListener{ public void actionPerformed(ActionEvent e){ if (e.getSource() == button1){ Calendar ClCDateTime = Calendar.getInstance(); System.out.println(ClCDateTime.getTimeInMillis() - _openTime); _closeTime = ClCDateTime.getTimeInMillis() - _openTime; frame.getContentPane().remove(thePanel); } } } 

有人知道我可能做错了什么吗?

从容器中删除组件后,它将进入invalidate状态。 要使其恢复到valid状态,您必须revalidaterepaint它。 在您的情况下,您直接在JFrame添加/删除组件,因此根据Java版本,您可以执行以下操作:

 frame.revalidate(); // For Java 1.7 or above frame.getContentPane().validate(); // For Java 1.6 or below frame.repaint(); 

以下是一个帮助您的工作示例:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Assignment { private JFrame frame; private JPanel firstPanel; private JPanel secondPanel; private JButton forwardButton; private JButton backButton; private void displayGUI() { frame = new JFrame("Assignment"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); firstPanel = new JPanel(); firstPanel.setOpaque(true); firstPanel.setBackground(Color.BLUE); secondPanel = new JPanel(); secondPanel.setOpaque(true); secondPanel.setBackground(Color.RED); forwardButton = new JButton("Forward"); forwardButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { frame.remove(firstPanel); frame.add(secondPanel); frame.revalidate(); // For Java 1.7 or above. // frame.getContentPane().validate(); // For Java 1.6 or below. frame.repaint(); } }); backButton = new JButton("Back"); backButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { frame.remove(secondPanel); frame.add(firstPanel); frame.revalidate(); // For Java 1.7 or above. // frame.getContentPane().validate(); // For Java 1.6 or below. frame.repaint(); } }); firstPanel.add(forwardButton); secondPanel.add(backButton); frame.add(firstPanel); frame.setSize(300, 300); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Assignment().displayGUI(); } }); } } 
  1. 正确的方法可以(仅)使用CardLayout

  2. 否则必须从容器中删除JPanel并调用(作为最后一个代码行,并在完成容器的所有更改后仅调用一次)

 myJPanelsContainer#revalidate(); // in Java6 for JFrame validate() myJPanelsContainer#repaint();