好的,让我们试试这个。这是一个动态创建 JButton 的小型 Java 应用程序。我试图找到一种方法来完全删除创建的 JButton,以便垃圾收集将释放它们曾经使用的内存。这是一个最小的可重复示例,作为我想要实现的目标的示例。
因此,用户可以设置控件的x和y位置并单击创建按钮,这使得JButton称为myButton。现在我想要的是删除按钮删除所有创建的按钮,使其为空。我知道我可以让它隐形,将其从容器中取出等,但我希望销毁它。
问题1:据我了解,如果我设置一个object = null,它会允许它被垃圾收集并从内存中删除吗?因此,如果我执行 myButton=null,该对象是否能够从内存中删除?
问题 2:如果问题 1 正确,我知道创建时所有新对象按钮都将具有相同的名称。那么我该如何动态创建它们的实例,同时仍然能够在以后销毁它们呢?我尝试过使用 ListArray,虽然我可以访问它们,但无法将它们清空。
问题 3:当另一个按钮添加到容器中时,即使我制作另一个 Jbutton 来替换原始按钮 myButton 的内容,该对象仍然可以正常运行。我想我对实例化和将其添加到容器之间发生的过程感到困惑。
我想要做的事情是不可能的吗?是我的严重概念错误,还是有办法做到这一点?
package makeControls;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class MakeControls {
private JFrame frame;
private JTextField txtXPosition;
private JTextField txtYPosition;
private JButton btnDelete;
private JButton myButton;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MakeControls window = new MakeControls();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MakeControls() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btCreateButton = new JButton("Create Button");
btCreateButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
myButton = new JButton(); // create new button
int x = Integer.valueOf(txtXPosition.getText());
int y = Integer.valueOf(txtYPosition.getText());
myButton.setBounds( x,y,50,20); // set bounds based on entered values
frame.getContentPane().add(myButton);
myButton.setVisible(true);
frame.repaint();
}
});
btCreateButton.setBounds(222, 11, 146, 23);
frame.getContentPane().add(btCreateButton);
txtXPosition = new JTextField();
txtXPosition.setText("X Position");
txtXPosition.setHorizontalAlignment(SwingConstants.LEFT);
txtXPosition.setBounds(36, 12, 86, 20);
frame.getContentPane().add(txtXPosition);
txtXPosition.setColumns(10);
txtYPosition = new JTextField();
txtYPosition.setText("Y Position");
txtYPosition.setBounds(126, 12, 86, 20);
frame.getContentPane().add(txtYPosition);
txtYPosition.setColumns(10);
btnDelete = new JButton("Delete All");
btnDelete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Deleting");
myButton = null;
}
});
btnDelete.setBounds(222, 50, 146, 23);
frame.getContentPane().add(btnDelete);
}
}
像往常一样,提前致谢。
我重新排列了您的代码以创建以下 GUI。
我把
JFrame
分成了两个JPanels
。 左侧的 JPanel
是您的用户创建的控件将出现的位置。 右侧的 JPanel
包含 GUI 控件。
我这样做的原因是为了防止用户覆盖 GUI 控件并将 GUI 控件与用户创建的控件分开。 当我们删除用户创建的控件时,这一点将变得很重要。
这是用户创建的 GUI
JButton
。 我在 JButtons
上写了一些文字,这样我就可以区分它们。
Oracle 有一个有用的教程,使用 Swing 创建 GUI。 跳过使用 NetBeans IDE 学习 Swing 部分。 添加书签并学习本教程的其余部分。
我使用了JFrame
默认
BorderLayout
。 我使用
JPanel
内部的
GridLayout
创建了 GUI 控件
FlowLayout
。
GridLayout
使四个 Swing 组件大小相等,并将它们排列成两行或两列。
FlowLayout
使
GridLayout
JPanel
成为最小尺寸。用户创建的控件
JPanel
具有
null
布局和初始大小。 您可以通过更改
JPanel
的大小来增大或缩小此
JFrame
。 一种方法是最大化
JFrame
。要删除所有用户创建的控件,我从用户创建的控件中删除了 Swing 组件
JPanel
。 我不必担心删除 GUI 控件 Swing 组件。代码
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MakeControls {
private int buttonCounter;
private JFrame frame;
private JPanel makeControlsPanel;
private JTextField txtXPosition;
private JTextField txtYPosition;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MakeControls();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MakeControls() {
this.buttonCounter = 1;
this.makeControlsPanel = createMakeControlsPanel();
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame("Make Controls");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(makeControlsPanel, BorderLayout.CENTER);
frame.add(createControlPanel(), BorderLayout.EAST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMakeControlsPanel() {
JPanel panel = new JPanel(null);
panel.setPreferredSize(new Dimension(500, 500));
return panel;
}
private JPanel createControlPanel() {
JPanel outerPanel = new JPanel(new FlowLayout());
JPanel panel = new JPanel(new GridLayout(0, 2, 5, 5));
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JButton btCreateButton = new JButton("Create Button");
btCreateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
JButton button = new JButton("Button " + buttonCounter++);
int x = Integer.valueOf(txtXPosition.getText());
int y = Integer.valueOf(txtYPosition.getText());
Dimension d = button.getPreferredSize();
button.setBounds(x, y, d.width + 10, d.height);
makeControlsPanel.add(button);
frame.repaint();
}
});
panel.add(btCreateButton);
JButton btnDelete = new JButton("Delete All");
btnDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
int size = makeControlsPanel.getComponentCount();
for (int index = size - 1; index >= 0; index--) {
makeControlsPanel.remove(index);
}
buttonCounter = 1;
frame.repaint();
}
});
panel.add(btnDelete);
txtXPosition = new JTextField(10);
txtXPosition.setText("X Position");
panel.add(txtXPosition);
txtYPosition = new JTextField(10);
txtYPosition.setText("Y Position");
panel.add(txtYPosition);
outerPanel.add(panel);
return outerPanel;
}
}