Динамически добавлять компоненты в JDialog

У меня возникают проблемы с добавлением JComponents в JDialog, когда пользователь нажимает кнопку на JDialog. В основном я хочу, чтобы оно выглядело так:

When the dialog is opened

Затем, когда пользователь нажимает кнопку "Add New Field", я хочу, чтобы оно выглядело так:

After the user clicks "Add New Field"

Похоже, что я не могу получить диалог для добавления новой JLabel или JTextField. Кто-нибудь может указать мне правильное направление?

EDIT: Это действие для кнопки "Добавить новое поле" (Просто попробуйте метку сейчас).

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

SOLUTION:

Я использовал решение 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();
}

Другая моя проблема в том, что я использую компоновку "Free Design" в NetBeans, что означало, что мой лейбл, вероятно, находился в каком-то странном положении, а не в границах моего диалога (просто догадка). Я решил эту проблему с помощью label.setBounds(), так что она показала именно то, где я хотел.

25
задан NeilMonday 8 August 2011 в 22:00
поделиться

3 ответа

При динамическом добавлении / удалении компонентов из контейнера необходимо вызвать revalidate() / validate() и repaint() впоследствии. Первый заставит контейнер снова размещать свои компоненты, а второй удалит все визуальные «артефакты».

21
ответ дан 28 November 2019 в 21:02
поделиться

Я согласен с 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();
         }
      });
   }
}
11
ответ дан 28 November 2019 в 21:02
поделиться

чтобы избежать дальнейших дискуссий о необходимых / необязательных методах ...

примечание: для добавления / удаления JComponents (простой структурированный только в одной строке / столбце и с одинаковым Size on Screen) достаточно просто действия JFrame.pack(),

enter image description here

enter image description here

enter image description here

, но для наиболее полного GUI, заложенного по некоторым стандартным 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();
    }
}
13
ответ дан 28 November 2019 в 21:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: