基于 JList 值将 JButtons 动态添加到 JPanel

Adding JButtons Dynamically to JPanel based on JList values

我正在开发 Java Swing 应用程序。 我的要求:-

在我的 JFrame 中,我有一个 JList,其值为 "One"、"Two"、"Three" 等。当我 select 一个列表项时,我想显示 "n" 按钮,其中 "n" 是值 selected.

示例:- 如果我从列表中 select "Three",JFrame 中应该有 3 个按钮。

下面是我的代码:-

public class Details extends JFrame {

    String[] navData = new String{"One","Two","Three","Four"};
    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Details frame = new Details();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */

    public Details()  {

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        Toolkit tk = Toolkit.getDefaultToolkit();
         int xSize = ((int) tk.getScreenSize().getWidth());
         int ySize = ((int) tk.getScreenSize().getHeight());
         //frame.setSize(xSize,ySize);
        setTitle("Test");
        setBounds(0, 0, 776, 457);
        setResizable(false);
        //setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        final JList list = new JList(navData);
        list.setBounds(0, 0, 140, ySize);
        contentPane.add(list);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setFixedCellHeight(50);
        list.setFixedCellWidth(70);
        list.setBorder(new EmptyBorder(10,10, 10, 10));


        list.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent arg0) {

                int numButtons;
                String selectedItem = navData[list.getSelectedIndex()];
                switch (selectedItem) {
                case "One":
                    addButtons(1);
                    break;
                case "Two":
                    addButtons(2);
                    break;
                case "Three":
                    addButtons(3);
                    break;
                case "Four":
                    addButtons(4);
                    break;
                default:
                    break;
                }

            }
        });
        list.setSelectedIndex(0);


    }

    public void addButtons(int n)
    {
        revalidate();
        for(int i = 0; i<n;i++)
        {
            JButton button = new JButton(" "+navData[i]);
            button.setBounds(200 + (i*50), 150, 50, 50);
            contentPane.add(button);    
        }

    }
}

- 问题:-

当我更改列表中的 selected 项时,JPanel 没有更新。换句话说,当我从列表中 select "Three" 时,我没有得到 3 个按钮。我只有 1 个默认创建的按钮 selection.

contentPane.setLayout(null); 替换为某种布局,例如 contentPane.setLayout(new GridBagLayout());

添加

contentPane.removeAll() 作为 addButtons().

中的第一行

您可以为按钮创建一个 "wrapper" 面板,即

...
private JPanel buttonsWrapper;
...
// in the constructor
buttonsWrapper = new JPanel();
buttonsWrapper.setLayout(null);
buttonsWrapper.setBounds(200, 150, 200, 50);
buttonsWrapper.add(wrapperPanel);

并向该面板添加按钮

public void addButtons(int n) {
    buttonsWrapper.removeAll();
    for(int i = 0; i < n; i++) {
        JButton button = new JButton(" " + navData[i]);
        button.setBounds((i*50), 0, 50, 50);
        buttonsWrapper.add(button);    
    }
    buttonsWrapper.revalidate();
    buttonsWrapper.repaint();
}

我做了这些更改:

  1. 我将 JList 放在一个 JPanel 中,将 JButton 放在另一个 JPanel 中。

  2. 我为 JList JPanel 使用了 FlowLayout,为 JButtons JPanel 使用了 FlowLayout。如果您愿意,您可以随意更改这些 Swing 布局。

  3. 我将默认值更改为 4 个按钮,因此 JFrame 最多可以正确打包 4 个 JButton。

  4. 在尝试将 JButton 添加到 JPanel 之前,我添加了一种从 JPanel 中删除 JButton 的方法。

  5. 我重新验证并重新绘制了 JButton JPanel。

代码如下:

package com.ggl.testing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Details extends JFrame {

    private static final long serialVersionUID = -555805219508469709L;

    private String[] navData = { "One", "Two", "Three", "Four" };

    private JPanel buttonPanel;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Details frame = new Details();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */

    public Details() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setTitle("Test");

        buttonPanel = new JPanel();

        JPanel listPanel = new JPanel();
        final JList<String> list = new JList<String>(navData);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setFixedCellHeight(50);
        list.setFixedCellWidth(70);
        list.setBorder(new EmptyBorder(10, 10, 10, 10));

        list.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent event) {

                String selectedItem = navData[list.getSelectedIndex()];
                switch (selectedItem) {
                case "One":
                    removeButtons(buttonPanel);
                    addButtons(buttonPanel, 1);
                    break;
                case "Two":
                    removeButtons(buttonPanel);
                    addButtons(buttonPanel, 2);
                    break;
                case "Three":
                    removeButtons(buttonPanel);
                    addButtons(buttonPanel, 3);
                    break;
                case "Four":
                    removeButtons(buttonPanel);
                    addButtons(buttonPanel, 4);
                    break;
                default:
                    break;
                }

            }
        });
        list.setSelectedIndex(3);

        listPanel.add(list);

        add(listPanel, BorderLayout.WEST);
        add(buttonPanel, BorderLayout.CENTER);

        pack();
    }

    public void removeButtons(JPanel panel) {
        Component[] components = panel.getComponents();
        for (int i = 0; i < components.length; i++) {
            panel.remove(components[i]);
        }
    }

    public void addButtons(JPanel panel, int n) {
        for (int i = 0; i < n; i++) {
            JButton button = new JButton(navData[i]);
            panel.add(button);
        }
        panel.revalidate();
        panel.repaint();
    }
}