java 最终使用滚动条的 JPanel 列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14615888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:50:32  来源:igfitidea点击:

List of JPanels that eventually uses a scrollbar

javaswingscrollbar

提问by Horstinator

im trying to build a GUI for my Java application. I dynamically add JPanels, which are a "row" in my GUI. Under the List of the Panels there is a button to add a new Panel. As the List grows, it reaches the end of the parent Container. Then I want to use scrollbars, so that the user is able to reach every panel in the List.

我正在尝试为我的 Java 应用程序构建一个 GUI。我动态添加了 JPanel,它是我的 GUI 中的一个“行”。在面板列表下,有一个按钮可以添加新面板。随着 List 的增长,它会到达父容器的末尾。然后我想使用滚动条,以便用户能够访问列表中的每个面板。

So far I experimented with JScrollPanes and Layouts but I have no Idea how to get it working.

到目前为止,我尝试了 JScrollPanes 和 Layouts,但我不知道如何让它工作。

Can you give me some advice?

你能给我一些建议吗?

this.setLayout(new BorderLayout());
JPanel listContainer = new JPanel();
listContainer.setLayout(BoxLayout(listContainer, BoxLayout.Y_AXIS);

this.add(new JScrollPane(listContainer), BorderLayout.CENTER);
this.add(new JButton(), BorderLayout.PAGE_END);

//then i add panels to the listContainer. this wont work, when the space is complettly used there is no scrollbar.

回答by MadProgrammer

It's difficult to assertain from your code snippet exactly where you might be having problems.

很难从您的代码片段中断言您可能遇到问题的确切位置。

enter image description here

在此处输入图片说明

public class DynamicPanelList {

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

    public DynamicPanelList() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

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

    public class TestPane extends JPanel {

        private JPanel mainList;

        public TestPane() {
            setLayout(new BorderLayout());

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

            add(new JScrollPane(mainList));

            JButton add = new JButton("Add");
            add.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JPanel panel = new JPanel();
                    panel.add(new JLabel("Hello"));
                    panel.setBorder(new MatteBorder(0, 0, 1, 0, Color.GRAY));
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    gbc.weightx = 1;
                    gbc.fill = GridBagConstraints.HORIZONTAL;
                    mainList.add(panel, gbc, 0);

                    validate();
                    repaint();
                }
            });

            add(add, BorderLayout.SOUTH);

        }

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

You really need to provide a SSCCEwhich would allow us to diagnose the problems you are having.

您确实需要提供一个SSCCE,以便我们能够诊断您遇到的问题。

Personally, and this will depend on you requirements, a better layout manager might be VerticalLayoutfrom SwingLabs SwingX libraries.

就个人而言,这取决于您的要求,更好的布局管理器可能VerticalLayout来自 SwingLabs SwingX 库。

回答by Guillaume Polet

You probably forgot to call revalidate()on your listContainer(and you made a bunch of syntax errors). BoxLayoutdoes not do a great job in my opinion, but that is not the matter here.

你可能忘记调用revalidate()你的listContainer(并且你犯了一堆语法错误)。BoxLayout在我看来并没有做得很好,但这不是问题。

Here is a small demo code which seems to work quite well:

这是一个小演示代码,它似乎工作得很好:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestScollpane {
    private int i;
    private JPanel listContainer;

    private void initUI() {
        final JFrame frame = new JFrame(TestScollpane.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        listContainer = new JPanel();
        listContainer.setLayout(new BoxLayout(listContainer, BoxLayout.Y_AXIS));

        frame.add(new JScrollPane(listContainer), BorderLayout.CENTER);
        JButton button = new JButton("Add");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final JPanel newPanel = new JPanel();
                newPanel.add(new JLabel("Label " + i++));
                listContainer.add(newPanel);
                listContainer.revalidate();
                // Scroll down to last added panel
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        newPanel.scrollRectToVisible(newPanel.getBounds());
                    }
                });
            }
        });
        frame.add(button, BorderLayout.PAGE_END);

        frame.setSize(300, 200);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestScollpane().initUI();
            }
        });
    }
}