java 将组件动态添加到 JDialog
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6988317/
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
Dynamically Add Components to a JDialog
提问by NeilMonday
I am having trouble adding JComponents to a JDialog when the user clicks a button on the JDialog. Basically I want it to look like this:
当用户单击 JDialog 上的按钮时,我无法将 JComponents 添加到 JDialog。基本上我希望它看起来像这样:
Then, when the user clicks "Add New Field" I want it to look like this:
然后,当用户单击“添加新字段”时,我希望它看起来像这样:
I cannot seem to get the dialog to add the new JLabel or JTextField. Can anyone point me in the right direction?
我似乎无法获得添加新 JLabel 或 JTextField 的对话框。任何人都可以指出我正确的方向吗?
EDIT: This is the action for the "Add New Field" button (Just trying a label now).
编辑:这是“添加新字段”按钮的操作(现在只是尝试一个标签)。
@Action
public void addNewField()
{
Container contentPane = getContentPane();
JLabel label = new JLabel ("welkom");
contentPane.add(label, BorderLayout.CENTER);
}
SOLUTION:
解决方案:
I used mre's solution and got it to work. Here is my final function:
我使用了 mre 的解决方案并使其正常工作。这是我的最终功能:
@Action
public void addNewField()
{
System.out.println("New Field...");
Container contentPane = getContentPane();
JLabel label = new JLabel ("welcome");
label.setBounds(10,10,100,10); //some random value that I know is in my dialog
contentPane.add(label);
contentPane.validate();
contentPane.repaint();
this.pack();
}
Another one of my problems is that I am using a "Free Design" layout in NetBeans, which meant that my label was probably in some weird position rather than being in the bounds of my dialog (just a guess). I solved this problem with label.setBounds()
so that it showed exactly where I wanted it to.
我的另一个问题是我在 NetBeans 中使用了“自由设计”布局,这意味着我的标签可能处于某个奇怪的位置,而不是在我的对话框的边界内(只是猜测)。我解决了这个问题,label.setBounds()
以便它准确地显示我想要的位置。
采纳答案by mre
When dynamically adding/removing components from a container, it's necessary to invoke revalidate()
/validate()
and repaint()
afterward. The former will force the container to layout its components again and the latter will remove any visual "artifacts".
从容器中动态添加/删除组件时,有必要调用revalidate()
/validate()
和repaint()
之后。前者将强制容器重新布局其组件,后者将删除任何视觉“工件”。
回答by mKorbel
to avoiding any further discusion about required/non-required any of Methods ...
避免任何关于必需/非必需的任何方法的进一步讨论......
notice: for adds/removes JComponents
(simple structured just in one Row/Column and with same Size on Screen
) is sufficient just action JFrame.pack()
,
注意:对于添加/删除JComponents
(简单的结构仅在一行/列中并且具有相同的Size on Screen
)就足够了 action JFrame.pack()
,
but for most complete GUI layed by some of standard Swing LayoutManagers
is required usage of
但是对于大多数由一些标准奠定的完整 GUISwing LayoutManagers
需要使用
revalidate();
repaint(); // required in most of cases
example for one Column
一列的例子
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
回答by Hovercraft Full Of Eels
I agree with mre (1+ to his answer), but I would also like to add that you may need to call pack()
on the JDialog after adding or removing components especially if the dialog will need to resize to accomodate the component as your images indicate may happen.
我同意 mre(他的回答为 1+),但我还想补充一点,您可能需要pack()
在添加或删除组件后调用JDialog,特别是如果对话框需要调整大小以适应组件,如您的图像所示可能发生。
Edit 1
For example with a JFrame (but it works the same with a JDialog):
编辑 1
例如使用 JFrame(但它与 JDialog 的工作方式相同):
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SwingFoo extends JPanel {
private JTextField nameField = new JTextField(10);
private JComboBox searchTermsCombo = new JComboBox();
private JButton addNewFieldBtn = new JButton("Add New Field");
private JButton submitBtn = new JButton("Submit");
private JPanel centerPanel = new JPanel(new GridBagLayout());
private int gridY = 0;
public SwingFoo() {
GridBagConstraints gbc = createGBC(0, gridY);
centerPanel.add(new JLabel("Name:"), gbc);
gbc = createGBC(1, gridY);
centerPanel.add(nameField, gbc);
gridY++;
gbc = createGBC(0, gridY);
centerPanel.add(new JLabel("Search Terms:"), gbc);
gbc = createGBC(1, gridY);
centerPanel.add(searchTermsCombo, gbc);
gridY++;
addNewFieldBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addNewFieldAction(e);
}
});
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.PAGE_AXIS));
JPanel addNewFieldPanel = new JPanel(new GridLayout(1, 0));
addNewFieldPanel.add(addNewFieldBtn);
addNewFieldPanel.add(new JLabel());
JPanel submitPanel = new JPanel(new BorderLayout());
submitPanel.add(submitBtn);
bottomPanel.add(addNewFieldPanel);
bottomPanel.add(Box.createVerticalStrut(5));
bottomPanel.add(submitPanel);
int eb = 8;
setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
setLayout(new BorderLayout());
add(centerPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.SOUTH);
}
private void addNewFieldAction(ActionEvent e) {
GridBagConstraints gbc = createGBC(0, gridY);
centerPanel.add(new JLabel("New Item:"), gbc);
gbc = createGBC(1, gridY);
centerPanel.add(new JTextField(10), gbc);
gridY++;
Window win = SwingUtilities.getWindowAncestor(addNewFieldBtn);
if (win != null) {
win.pack();
win.setLocationRelativeTo(null);
}
}
private GridBagConstraints createGBC(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = (x == 0) ? gbc.LINE_START : gbc.LINE_END;
gbc.fill = (x == 0) ? gbc.BOTH : gbc.HORIZONTAL;
gbc.insets = (x == 0) ? new Insets(5, 0, 5, 5) : new Insets(5, 5, 5, 0);
return gbc;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SwingFoo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SwingFoo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}