如何动态添加元素到JScrollPanel?

时间:2016-06-24 20:02:52

标签: java swing user-interface jpanel jscrollpane

我正在尝试使用Java中的Swing创建一个GUI,它执行以下操作:

当"添加"按下按钮,创建JPanel并填充GUI的整个宽度。在JPanel内部将使用FlowLayout安排JLabel,它告诉具体细节(即名称,用户ID等)。每当按下Add按钮时,我想在前一个下添加一个新的JPanel,这样JScrollPane将在必要时激活其垂直滚动条。基本上,我希望JScrollPane能够在其中动态添加新的JPanel。

但是,我在尝试这样做时遇到了一些问题。我无法弄清楚哪个LayoutManager用于JScrollPane中的面板。我已经尝试过使用GridlLayout,但这似乎不起作用,因为当有足够的JPanel来掩盖整个JScrollPane时,GridLayout只会创建一个新列来压缩新的JPanel而不是将它添加到前一个JPanel之下。我该怎么做才能实现这个目标?以下是我所拥有的一些图像以及我想要发生的事例。

GUI

以下是我想要发生的事情:

GUI Example

任何帮助将不胜感激,谢谢你提前! :)

编辑:这是我尝试使用GridLayout的代码示例。

public Window() {


    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 701, 400);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JPanel buttonPanel = new JPanel();
    contentPane.add(buttonPanel, BorderLayout.SOUTH);

    JButton btnAdd = new JButton("Add");
    buttonPanel.add(btnAdd);

    JScrollPane scrollPane = new JScrollPane();
    contentPane.add(scrollPane, BorderLayout.CENTER);

    JPanel systemsPanel = new JPanel();
    scrollPane.setViewportView(systemsPanel);
    systemsPanel.setLayout(new GridLayout(8, 1, 0, 0)); //8 rows for now



    for (int i = 1; i < 50; i++) {
        systemsPanel.add(new JButton("test"), "cell 0 " + i);
    }
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    this.setLocation(dim.width / 2 - this.getSize().width / 2, dim.height / 2 - this.getSize().height / 2); //Center the Frame 

}

1 个答案:

答案 0 :(得分:2)

如果要将JPanels行添加到GUI中,我会将它们放在使用GridLayout(0,1)或(0,1,x,y)的JPanel中。 0表示可变数量的行,1表示1列,x和y表示垂直和水平间隙。然后我将它放入BorderLayout-使用JPanel进入NORTH位置,这样行不会扩展以填充滚动窗格的视口,因为它们原本想要这样做。我将第二个包装器JPanel放入JScrollPane的视口中。

添加任何组件后,我会在容器上调用revalidate并重新绘制,以便其布局管理器将激活并正确放置新组件,并重新绘制以清除可能悬挂的任何脏像素(在删除时更为重要)组件)。

例如,我的MCVE:

TextConn

但是,你最好使用JTable ......例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class AddRowA extends JPanel {
    private static final int PREF_W = 650;
    private static final int PREF_H = 400;

    // JPanel to hold all rows. uses gridlayout that has 1 column and variable number
    // of rows
    private JPanel rowHolderPanel = new JPanel(new GridLayout(0, 1, 1, 1));

    public AddRowA() {
        // outerPanel is a wrapper or container JPanel that is 
        // held by JScrollPane's viewport that holds the rowHolderPanel in 
        // a BorderLayout.PAGE_START location, so the rows don't expand unnecessarily
        JPanel outerPanel = new JPanel(new BorderLayout());
        outerPanel.add(rowHolderPanel, BorderLayout.PAGE_START);
        JScrollPane scrollPane = new JScrollPane(outerPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        JPanel addPanel = new JPanel();
        addPanel.add(new JButton(new AddAction("Add")));

        setLayout(new BorderLayout());
        add(scrollPane, BorderLayout.CENTER);
        add(addPanel, BorderLayout.PAGE_END);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class AddAction extends AbstractAction {
        public AddAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            JPanel panel = new JPanel();
            panel.add(new JLabel("Foo"));
            panel.add(Box.createHorizontalStrut(25));
            panel.add(new JButton("Bar"));
            panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));

            rowHolderPanel.add(panel);
            rowHolderPanel.revalidate();
            rowHolderPanel.repaint();
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Add Row A");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new AddRowA());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}