动态添加组件到JDialog

Nei*_*day 25 java swing jdialog

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

打开对话框时

然后,当用户点击"添加新字段"时,我希望它看起来像这样:

用户点击

我似乎无法获得添加新JLabel或JTextField的对话框.谁能指出我正确的方向?

编辑:这是"添加新字段"按钮的操作(现在只是尝试标签).

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

解决方案:

我使用了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();
}
Run Code Online (Sandbox Code Playgroud)

我的另一个问题是我在NetBeans中使用"自由设计"布局,这意味着我的标签可能处于一些奇怪的位置而不是在我的对话框中(只是一个猜测).我解决了这个问题,label.setBounds()以便它显示我想要的确切位置.

mre*_*mre 21

当动态地添加/从一个容器中取出组件,有必要以调用revalidate()/ validate()repaint()之后.前者将强制容器再次布局其组件,后者将删除任何视觉"工件".


mKo*_*bel 13

避免对任何方法的必要/不需要进一步的争论......

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

在此输入图像描述

在此输入图像描述

在此输入图像描述

但对于大多数完整的GUI,一些标准Swing LayoutManagers是需要使用的

revalidate();
repaint(); // required in most of cases 
Run Code Online (Sandbox Code Playgroud)

一列的示例

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();
    }
}
Run Code Online (Sandbox Code Playgroud)


Hov*_*els 11

我同意mre(他的答案是1+),但我还想补充一点,你可能需要pack()在添加或删除组件后调用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();
         }
      });
   }
}
Run Code Online (Sandbox Code Playgroud)