动态添加组件到一个JDialog

当用户单击JDialog上的按钮时,我无法将JComponents添加到JDialog。 基本上我希望它看起来像这样:

当对话框打开时

然后,当用户点击“添加新字段”我想它看起来像这样:

用户点击“添加新字段”

我似乎无法让对话框添加新的JLabel或JTextField。 任何人都可以指向正确的方向吗?

编辑 :这是“添加新字段”按钮(只是现在试图标签)的行动。

@Action public void addNewField() { Container contentPane = getContentPane(); JLabel label = new JLabel ("welkom"); contentPane.add(label, BorderLayout.CENTER); } 

方案

我使用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(); } 

我的另一个问题是,我在NetBeans中使用了“Free Design”布局,这意味着我的标签可能处于某种奇怪的位置,而不是处于对话框的边界(只是猜测)。 我用label.setBounds()解决了这个问题,所以它显示了我想要的地方。

当动态添加/删除容器中的组件时,需要在之后调用revalidate() / validate()repaint() 。 前者将强制容器再次布置其组件,后者将删除任何可见的“文物”。

以避免任何进一步的必要/不需要任何方法…

注意:对于添加/删除JComponents (简单地在一行/列中进行结构化,并且Size on Screen具有相同的Size on Screen )就足够了,只需要操作JFrame.pack()

在这里输入图像描述

在这里输入图像描述

在这里输入图像描述

但是对于大多数完整的图形用户界面来说, Swing LayoutManagers是一些标准的必需用法

 revalidate(); repaint(); // required in most of cases 

一列的例子

 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(); } } 

我同意mre(1+到他的答案),但我也想补充一点,你可能需要在添加或删除组件后,在JDialog上调用pack() ,特别是如果对话框需要调整大小以适应组件图像表明可能会发生。

编辑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(); } }); } }