如何使用 removeAll() 从 JFrame 中删除所有组件?
Posted
技术标签:
【中文标题】如何使用 removeAll() 从 JFrame 中删除所有组件?【英文标题】:How to remove all components from a JFrame with removeAll()? 【发布时间】:2013-07-26 15:38:11 【问题描述】:因此,当字符串等于某个值时,我希望从JFrame
中删除所有内容,但是当我调用removeAll();
后跟revalidate();
和repaint();
时,它不会改变任何内容。
我尝试按照here 的指示拨打getContentPane.removeAll();
,但没有任何效果。
我的代码如下:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class MTGSAMPServerReference extends JFrame implements ActionListener
private static final long serialVersionUID = 1L;
private static JList list1;
private static JButton select1;
public static String selectionMenu = "Main";
public MTGSAMPServerReference()
this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
Object[]mainMenu = "Vehicles", "Bikes/Bicycles", "Boats", "Houses", "Businesses", "Objects", "Jobs", "Ranks", "Licenses", "VIP", "FAQ's";
Object[]VehiclesValueMenu = "Lower Class", "Upper Class", "VIP";
if ("Main".equals(selectionMenu))
JPanel controls = new JPanel(new BorderLayout(5,5));
list1 = new JList<Object>(mainMenu);
list1.setVisibleRowCount(10);
select1 = new JButton("Select");
select1.addActionListener(this);
controls.add(new JScrollPane(list1));
controls.add(select1, BorderLayout.PAGE_END);
controls.setBorder(new EmptyBorder(25,25,0,0));
add(controls);
revalidate();
repaint();
if ("VehiclesValue".equals(selectionMenu))
removeAll();
revalidate();
repaint();
@Override
public void actionPerformed(ActionEvent e)
if ("Main".equals(selectionMenu))
if (e.getActionCommand().equals("Select"))
int indexMain = list1.getSelectedIndex();
System.out.println("Index Selected: " + indexMain);
String valueMain = (String) list1.getSelectedValue();
System.out.println("Value Selected: " + valueMain);
if ("Vehicles".equals(valueMain))
selectionMenu = "VehiclesValue";
System.out.println("Menu selected: " + selectionMenu);
revalidate();
repaint();
public void createAndShowGUI()
JFrame f = new MTGSAMPServerReference();
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//f.add(new drawOnPanel());
f.setSize(1200, 800);
f.setLocationRelativeTo(null);
list1.setSize(250, 250);
list1.setLocation(0, 0);
select1.setSize(75, 25);
select1.setLocation(251, 276);
MTGSAMPServerReference.this.repaint();
public static void main(String[] args)
javax.swing.SwingUtilities.invokeLater(new Runnable()
public void run()
MTGSAMPServerReference gui = new MTGSAMPServerReference();
gui.createAndShowGUI();
);
我已经完成了研究,但无法弄清楚我做错了什么。
如果我尝试更改我的JFrame f to a Global Variable instead of a Local Variable
,它不会显示任何开头的内容。
是的,我知道我是mixing Commmand Line with GUI
,但那是only for debugging purposes
。完成后,我将简单地删除所有Command Line related
。
无论如何,对我的问题有什么想法吗?
提前致谢!
【问题讨论】:
static
变量很好地表明了糟糕的设计
为此,我会使用CardLayout
,如short example所示。
通过容器实例
list1
和select1
不必是static
,因为它们应该属于MTGSAMPServerReference
的单个实例。 selectionMenu
不必是 static
,因为它可以作为参数传递给 MTGSAMPServerReference
构造函数。如果您需要访问 JList
或 JButton
包含的值,则应根据需要提供 getter 和 setter。如果可以避免,则应避免将子组件暴露给外界,因为这意味着其他人会突然控制您的整个组件,并且可以做您无法阻止的事情
“一旦你批评了我的代码,你介意提供一个解决方案吗?” 我不认为这是一个很有帮助的评论。 1) 提供建议的人可能不知道答案,但仍然能够识别会导致问题的代码(我同意使用static
- 如果有的话,这很少是解决方案)。 2) 修复他们指出的问题实际上可能成为解决方案,或者 90% 的解决方案,并且.. 3) 它听起来像是“除非你打算提供答案,不要批评我的代码'。通常,当人们“将代码撕成碎片”时,他们会把你的最大利益放在心上。
【参考方案1】:
我发现该代码存在几个问题:
MTGSAMPServerReference 被调用两次,一次是主要的,另一次被createAndShowGUI()
调用。
MTGSAMPServerReference 扩展了 JFrame,但 createAndShowGUI() 也包含一个局部变量 JFrame f
。本质上,您将this
分配给了一个局部变量f
,这没有任何意义。
要初始化 GUI,您需要执行构造函数和createAndShowGUI()
,之后所有可以执行的代码都归因于事件。在您的情况下,使用 actionPerformed()
方法。如果你想删除框架内的组件,你必须在那里(或在某个时候从那里调用)执行正确的代码。
如您的链接所述,要删除所有组件,您必须在 JFrame 的 contentPane 上执行 removeAll()
,通过 getContentPane()
获得。
我不知道您打算如何处理这些比较 if("Main".equals(selectionMenu))
。同样是初始化代码,它运行了一次。在那里你构建了所有的 GUI。变量selectionMenu
将来可能会更改,但这不会追溯执行该代码。如果您想使用 selectionMenu
的新值执行任何操作,请在 actionListener 上执行。
这是您的代码的有效修改。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class MTGSAMPServerReference extends JFrame implements ActionListener
private static final long serialVersionUID = 1L;
private static JList list1;
private static JButton select1;
public static String selectionMenu = "Main"; //accomplishes nothing
public static void main(String[] args)
javax.swing.SwingUtilities.invokeLater(new Runnable()
public void run()
MTGSAMPServerReference gui = new MTGSAMPServerReference();
gui.createAndShowGUI();
);
public void createAndShowGUI()
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//f.add(new drawOnPanel());
setSize(1200, 800);
setLocationRelativeTo(null);
list1.setSize(250, 250);
list1.setLocation(0, 0);
select1.setSize(75, 25);
select1.setLocation(251, 276);
setVisible(true);
public MTGSAMPServerReference()
this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
Object[]mainMenu = "Vehicles", "Bikes/Bicycles", "Boats", "Houses", "Businesses", "Objects", "Jobs", "Ranks", "Licenses", "VIP", "FAQ's";
Object[]VehiclesValueMenu = "Lower Class", "Upper Class", "VIP";
JPanel controls = new JPanel(new BorderLayout(5,5));
list1 = new JList<Object>(mainMenu);
list1.setVisibleRowCount(10);
select1 = new JButton("Select");
select1.addActionListener(this);
controls.add(new JScrollPane(list1));
controls.add(select1, BorderLayout.PAGE_END);
controls.setBorder(new EmptyBorder(25,25,0,0));
add(controls);
//revalidate(); //uneeded at this point the JFrame is not yet visible, thus nothing to repaint
//repaint();
@Override
public void actionPerformed(ActionEvent e)
if (e.getActionCommand().equals("Select"))
int indexMain = list1.getSelectedIndex();
System.out.println("Index Selected: " + indexMain);
String valueMain = (String) list1.getSelectedValue();
System.out.println("Value Selected: " + valueMain);
if ("Vehicles".equals(valueMain))
System.out.println("Menu selected: " + selectionMenu);
getContentPane().removeAll(); //equivalent to this.getContentPane().removeAll();
revalidate();
repaint();
我还删除了对变量 selectionMenu
的修改,它现在并没有真正做任何事情。
正如其他人所说,您可能希望在某些时候使用另一个布局。哪一个取决于您在 JFrame 上还需要什么。
干杯。
【讨论】:
实际上,修改确实改变了一些事情。但无论如何,我会试试这个!【参考方案2】:这是一个使用 CardLayout
的示例,它取消了 static
变量并通过 setter 和 getter 提供对一些内部值的访问,用于演示
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
public class MTGSAMPServerReference extends JFrame implements ActionListener
private JList list1;
private JButton select1;
private String selectionMenu;
private JPanel mainMenuPane;
private JPanel vehicleMenuPane;
public MTGSAMPServerReference(String selectionMenu)
this.getContentPane().setLayout(new FlowLayout(FlowLayout.LEADING));
Object[] mainMenu = "Vehicles", "Bikes/Bicycles", "Boats", "Houses", "Businesses", "Objects", "Jobs", "Ranks", "Licenses", "VIP", "FAQ's";
Object[] VehiclesValueMenu = "Lower Class", "Upper Class", "VIP";
mainMenuPane = new JPanel(new BorderLayout(5, 5));
list1 = new JList<Object>(mainMenu);
list1.setVisibleRowCount(10);
select1 = new JButton("Select");
select1.addActionListener(this);
mainMenuPane.add(new JScrollPane(list1));
mainMenuPane.add(select1, BorderLayout.PAGE_END);
mainMenuPane.setBorder(new EmptyBorder(25, 25, 0, 0));
vehicleMenuPane = new JPanel();
vehicleMenuPane.add(new JLabel("Vehicle"));
CardLayout cl = new CardLayout();
setLayout(cl);
add("main", mainMenuPane);
add("vehicle", vehicleMenuPane);
cl.show(getContentPane(), "main");
setSelectionMenu(selectionMenu);
public String getSelectionMenu()
return selectionMenu;
public void setSelectionMenu(String value)
if (selectionMenu == null ? value != null : !selectionMenu.equals(value))
selectionMenu = value;
updateMenu();
protected void updateMenu()
CardLayout cl = (CardLayout) getContentPane().getLayout();
if ("Main".equals(selectionMenu))
cl.show(getContentPane(), "main");
else if ("VehiclesValue".equals(selectionMenu))
cl.show(getContentPane(), "vehicle");
@Override
public void actionPerformed(ActionEvent e)
if ("Main".equals(selectionMenu))
if (e.getActionCommand().equals("Select"))
int indexMain = list1.getSelectedIndex();
System.out.println("Index Selected: " + indexMain);
String valueMain = (String) list1.getSelectedValue();
System.out.println("Value Selected: " + valueMain);
if ("Vehicles".equals(valueMain))
setSelectionMenu("VehiclesValue");
System.out.println("Menu selected: " + selectionMenu);
else
setSelectionMenu("Main");
public static void main(String[] args)
javax.swing.SwingUtilities.invokeLater(new Runnable()
public void run()
MTGSAMPServerReference gui = new MTGSAMPServerReference("Main");
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.pack();
gui.setLocationRelativeTo(null);
gui.setVisible(true);
);
【讨论】:
以上是关于如何使用 removeAll() 从 JFrame 中删除所有组件?的主要内容,如果未能解决你的问题,请参考以下文章