Java Swing 在运行时添加/删除 jButton
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3468844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Swing add/remove jButtons on runtime
提问by Deepak
My application has a module which allows the user to add jButtons on the jLayeredpane during runtime. I want to add action listeners to this dynamically added contents and also i have to provide access to delete the dynamically added buttons during runtime. Is there any way to do this ?
我的应用程序有一个模块,允许用户在运行时在 jLayeredpane 上添加 jButton。我想向这个动态添加的内容添加动作侦听器,并且我必须提供访问权限以在运行时删除动态添加的按钮。有没有办法做到这一点?
private Map<String, JButton> dynamicButtons;
public void addButton(String name) {
JButton b = new JButton(name);
b.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jLayeredPane2.add(b);
dynamicButtons.put(name, b);
jLayeredPane2.invalidate();
}
public void removeButton(String name) {
JButton b = dynamicButtons.remove(name);
jLayeredPane2.remove(b);
jLayeredPane2.invalidate();
}
采纳答案by jjnguy
Original AnswerGood in general, but done differently in this case
原始答案总体上很好,但在这种情况下的做法有所不同
In order to keep track of an arbitrary number of added JButtons
, you will need to keep them in a list.
为了跟踪任意数量的添加JButtons
,您需要将它们保存在列表中。
So, after you create a new button, add the listeners to it, and add it to the pane, you then need to save that new button in a list.
因此,在创建新按钮后,向其添加侦听器并将其添加到窗格中,然后您需要将该新按钮保存在列表中。
That way you can keep track of all of the buttons you have added.
这样您就可以跟踪您添加的所有按钮。
You could also use a Map<String, JButton>
that maps a button name to the button.
您还可以使用Map<String, JButton>
将按钮名称映射到按钮的 。
Example:
例子:
private Map<String, JButton> dynamicButtons;
public void addButton(String name) {
JButton b = new JButton(name);
b.addActionListener(someAction);
yourPanel.add(b);
dynamicButtons.put(name, b);
yourPanel.invalidate();
}
public void removeButton(String name) {
Button b = dynamicButtons.remove(name);
yourPanel.remove(b);
yourPanel.invalidate();
}
The following is a full class that lets you add and remove buttons dynamically. It's not exactly what you want, but it should get you really close.
以下是一个完整的类,可让您动态添加和删除按钮。这不完全是你想要的,但它应该让你真正接近。
Code for your specific case:
您的具体情况的代码:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ExampleFrame extends JFrame {
private JButton add, remove;
private JPanel dynamicButtonPane, addRemovePane;
private boolean waitingForLocationClick;
public ExampleFrame() {
super("Dynamic button example");
waitingForLocationClick = false;
add = new JButton("Add Button");
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addButton(JOptionPane
.showInputDialog("Name of the new button:"));
}
});
remove = new JButton("Remove Button");
remove.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
lookingToRemove = true;
}
});
JPanel mainPane = new JPanel(new BorderLayout());
dynamicButtonPane = new JPanel();
dynamicButtonPane.setLayout(null);
dynamicButtonPane.setPreferredSize(new Dimension(300, 300));
addRemovePane = new JPanel();
addRemovePane.add(add);
addRemovePane.add(remove);
mainPane.add(dynamicButtonPane, BorderLayout.NORTH);
mainPane.add(addRemovePane, BorderLayout.SOUTH);
add(mainPane);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
dynamicButtonPane.addMouseListener(pointSelectorListener);
}
private JButton buttonToPlace;
public void addButton(String name) {
JButton b = new JButton(name);
b.setActionCommand(name);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (lookingToRemove) {
if (e.getSource() instanceof JButton) {
dynamicButtonPane.remove((Component) e.getSource());
dynamicButtonPane.validate();
dynamicButtonPane.repaint();
}
} else
JOptionPane.showMessageDialog(ExampleFrame.this, "This is " + e.getActionCommand());
}
});
waitingForLocationClick = true;
lookingToRemove = false;
buttonToPlace = b;
}
public void putButtonAtPoint(Point p) {
System.out.println("Placing a button at: " + p.toString());
dynamicButtonPane.add(buttonToPlace);
buttonToPlace.setBounds(new Rectangle(p, buttonToPlace
.getPreferredSize()));
dynamicButtonPane.validate();
buttonToPlace = null;
waitingForLocationClick = false;
}
private boolean lookingToRemove = false;
private final MouseListener pointSelectorListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (waitingForLocationClick) {
putButtonAtPoint(e.getPoint());
} else {
System.out.println("Not in waiting state");
}
}
};
public static void main(String[] args) {
new ExampleFrame();
}
}
回答by Erick Robertson
Absolutely. All of this stuff can be done programatically at any time. Here are a couple of hints to avoid problems and pitfalls:
绝对地。所有这些工作都可以随时以编程方式完成。以下是一些避免问题和陷阱的提示:
- When you add components to any panel, make sure this is done on the Event Dispatch Thread through
SwingUtilities.invokeLater(Runnable)
. Inside the Runnable, you want to add the component to the panel, hook up the listeners, and re-layout the panel. - Use
SwingUtilities.isEventDispatchThread()
to check to see if you are already on the event dispatch thread. If you are, then you can just run the Runnable immediately instead of callinginvokeLater
. - Once you've modified the layout of a panel, be sure to call
Component.invalidate()
on the panel to make sure it gets laid out again. - Maintain your own list of listeners. Overwrite the add and remove methods on the panel to add or remove them from your list and also from all existing buttons. When you add new buttons, add all listeners on the list.
- 当您将组件添加到任何面板时,请确保这是在事件调度线程上通过
SwingUtilities.invokeLater(Runnable)
. 在 Runnable 中,您想将组件添加到面板,连接监听器,并重新布局面板。 - 使用
SwingUtilities.isEventDispatchThread()
来检查,看看是否已经在事件调度线程上。如果是,那么您可以立即运行 Runnable 而不是调用invokeLater
. - 一旦您修改了面板的布局,请务必调用
Component.invalidate()
面板以确保其重新布局。 - 维护您自己的听众列表。覆盖面板上的添加和删除方法,以便从列表和所有现有按钮中添加或删除它们。添加新按钮时,将所有侦听器添加到列表中。
This is a very common task, and it is fully supported by Java. You should be able to get it done without too much trouble.
这是一项非常常见的任务,Java 完全支持它。你应该能够在没有太多麻烦的情况下完成它。