web-dev-qa-db-ja.com

JDialogにコンポーネントを動的に追加する

ユーザーがJDialogのボタンをクリックしたときに、JComponentsをJDialogに追加するのに問題があります。基本的に私はそれをこのように見せたいです:

When the dialog is opened

次に、ユーザーが[新しいフィールドの追加]をクリックすると、次のように表示されます。

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

[〜#〜]ソリューション[〜#〜]

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

私の問題のもう1つは、NetBeansで「フリーデザイン」レイアウトを使用していることです。これは、ラベルがダイアログの境界内ではなく、おそらく奇妙な位置にあったことを意味します(単なる推測)。この問題をlabel.setBounds()で解決したので、希望する場所が正確に表示されました。

25
NeilMonday

コンテナからコンポーネントを動的に追加/削除する場合は、 revalidate() / validate() および repaint() 後で。前者はコンテナにそのコンポーネントを再度レイアウトするように強制し、後者は視覚的な「アーティファクト」を削除します。

21
mre

必須/非必須のメソッドについてのこれ以上の議論を避けるために.。

注意:追加/削除の場合、JComponents(1つの行/列で単純に構造化され、同じ_Size on Screen_)で十分です。アクションJFrame.pack()

enter image description here

enter image description here

enter image description here

しかし、いくつかの標準的な_Swing LayoutManagers_によって構築されたほとんどの完全なGUIには、

_revalidate();
repaint(); // required in most of cases 
_

1つの列の例

_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
mKorbel

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