使用JButton在运行时添加新面板

时间:2015-03-01 23:58:32

标签: java swing jpanel grid-layout

我觉得作为初学者,我可能在应用程序构建方面遇到了太多问题。也就是说,我正在为朋友开发一个应用程序,该应用程序将提示每个JPanel将提供字段以创建稍后要使用的对象。我希望发生的是,当面板加载时,它会显示一个对象创建面板和一个按钮,以便在用户想要制作倍数时动态添加新面板(加号按钮会添加新面板)。

我在绘画中画了一些东西来说明这一点:

根据我非常有限的理解,我可以创建一个面板来保存这些子面板,然后在' +'中添加一个动作监听器。用于创建新面板的按钮。我能想到实现这个的唯一方法是为我想要添加的面板创建一个构造函数。这可能吗?让我告诉你我的所作所为:

package com.company;

import java.awt.*;
import javax.swing.*;

/**
 * Created by Travis on 3/1/2015.
 */
public class MainSnakeGui extends JFrame{

    protected int panelCount;


    //row 1
    JPanel row1 = new JPanel();
    JLabel splitSnakeLabel = new JLabel("Create a Split Snake", JLabel.CENTER);

    //row 2
    JPanel row2 = new JPanel();
    JButton addButton = new JButton("+");



    public MainSnakeGui() {
        super("Snake Channels");

        setSize(550, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridLayout layout = new GridLayout(5, 1, 10, 10);
        setLayout(layout);

        FlowLayout layout1 = new FlowLayout(FlowLayout.CENTER, 10, 10);
        row1.setLayout(layout1);
        row1.add(splitSnakeLabel);
        add(row1);

        GridLayout layout2 = new GridLayout(1, 2, 10, 10);
        row2.setLayout(layout2);
        row2.add(addButton);
        MainSnakeConstructor snakePanel = new MainSnakeConstructor();
        row2.add(snakePanel);
        add(row2);

        setVisible(true);
    }

    public static void setLookAndFeel () {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception e) {
        }
    }

    public static void main(String[] arg) {
        MainSnakeGui.setLookAndFeel();
        MainSnakeGui frame = new MainSnakeGui();
    }
}

这是构造函数:

package com.company;

import javax.swing.*;
import java.awt.*;

/**
 * Created by Travis on 3/1/2015.
 */
public class MainSnakeConstructor extends JFrame {

    public  MainSnakeConstructor () {
        JPanel splitSnakeRow = new JPanel();
        JLabel snakeNameLabel = new JLabel("Snake Name");
        JLabel channelCountLabel = new JLabel("Channel Count");
        JCheckBox artistSuppliedCheckBox = new JCheckBox("Artist Supplied?");
        JTextField snakeNameTextField = new JTextField(30);
        JTextField channelCountTextField =  new JTextField(3);

        GridLayout layout = new GridLayout(3,2,10,10);
        splitSnakeRow.setLayout(layout);
        splitSnakeRow.add(snakeNameLabel);
        splitSnakeRow.add(channelCountLabel);
        splitSnakeRow.add(artistSuppliedCheckBox);
        splitSnakeRow.add(snakeNameTextField);
        splitSnakeRow.add(channelCountTextField);
        add(splitSnakeRow);
    }
}

1 个答案:

答案 0 :(得分:2)

以不同的方式思考。你想要一个允许你添加新面板的按钮,所以你真的只需要一个按钮。

从那里,你需要一些通用的面板,它为用户提供你想要的功能(创建面板)。然后,当用户单击添加按钮时,您将创建一个新的创建面板并将其添加到用于显示它们的容器中,例如......

MakeItSo

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JButton btnAdd = new JButton("+");
            setLayout(new BorderLayout());
            JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
            buttons.add(btnAdd);
            add(buttons, BorderLayout.NORTH);

            JPanel content = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weighty = 1;
            content.add(new JPanel(), gbc);

            add(new JScrollPane(content));

            btnAdd.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    CreationPane pane = new CreationPane();
                    int insertAt = Math.max(0, content.getComponentCount() - 1);
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    gbc.fill = GridBagConstraints.HORIZONTAL;
                    gbc.weightx = 1;
                    content.add(pane, gbc, insertAt);
                    content.revalidate();
                    content.repaint();
                }
            });

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public static class CreationPane extends JPanel {

        private static int count;

        public CreationPane() {

            setLayout(new GridBagLayout());
            add(new JLabel("Make it so " + (count++)));
            setBorder(new CompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));

        }

    }

}

现在已经完成了所有这些,我更喜欢SwingLabs的VerticalLayout经理,SwingX库,基本上做同样的事情......