Динамически добавлять компоненты в JDialog - PullRequest
25 голосов
/ 09 августа 2011

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

When the dialog is opened

Затем, когда пользователь нажимает «Добавить новое поле», я хочу, чтобы оно выглядело так:

After the user clicks

Я не могу получить диалоговое окно для добавления нового 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, что означало, что мой ярлык, вероятно, находился в какой-то странной позиции, а не в границах моего диалога (только предположение). Я решил эту проблему с label.setBounds(), чтобы она показала, где именно я хотел.

Ответы [ 3 ]

21 голосов
/ 09 августа 2011

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

13 голосов
/ 09 августа 2011

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

уведомление: для добавления / удаления 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();
    }
}
11 голосов
/ 09 августа 2011

Я согласен с 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();
         }
      });
   }
}
...