Dee*_*pak 5 java swing components
我的应用程序有一个模块,允许用户在运行时在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();
}
Run Code Online (Sandbox Code Playgroud)
jjn*_*guy 10
原始答案 一般情况良好,但在这种情况下做的不同
为了跟踪任意数量的添加JButtons,您需要将它们保存在列表中.
因此,在创建新按钮,向其添加侦听器并将其添加到窗格后,您需要将该新按钮保存在列表中.
这样您就可以跟踪已添加的所有按钮.
您还可以使用Map<String, JButton>将按钮名称映射到按钮的按钮.
例:
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();
}
Run Code Online (Sandbox Code Playgroud)
以下是一个完整的类,可让您动态添加和删除按钮.这不完全是你想要的,但它应该让你非常接近.
针对您具体案例的代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
绝对.所有这些东西都可以随时以编程方式完成.以下是一些避免问题和陷阱的提示:
SwingUtilities.invokeLater(Runnable).在Runnable中,您希望将组件添加到面板,连接侦听器以及重新布局面板.SwingUtilities.isEventDispatchThread()来检查,看看是否已经在事件调度线程上.如果你是,那么你可以立即运行Runnable而不是调用invokeLater.Component.invalidate()面板以确保再次布局.这是一项非常常见的任务,Java完全支持它.你应该能够毫不费力地完成它.