JButton大小和JScrollPane不能很好地协同工作

时间:2014-07-17 09:09:01

标签: java swing user-interface jframe jbutton

我很困惑。我对每个布局管理器的工作原理以及每个布局管理器的用途都有一个相当不错的理解,但我不了解布局管理器和JPanel的组合是什么使我需要工作所必需的。

我想要实现的目标

我有一个顶栏和一个容器面板的底栏,位于BorderLayout的NORTH和SOUTH。 在中心面板中,我想要一个或多个未知数量的按钮。无论有多少个按钮,它们都需要具有相同的大小,如果有几十个,那么一旦按钮超出窗口大小限制就应该开始滚动。

我得到了什么

根据布局管理器的组合和我使用的嵌套JPanel的数量以及各种故障排除,我得到一个巨大的按钮填充整个CENTER元素。我得到了两个尺寸合适的按钮,但是分开了(填充CENTER空间的间隙),或者我得到了十几个尺寸合适但没有滚动的按钮。

我可以解决其中任何一个问题,但其他问题就解决了。 IE,如果我得到一堆正确大小的按钮,正确滚动,然后当我用一个按钮替换它一个巨大的按钮。或者,如果我得到一个正确大小的按钮,那么较大的数量将不会滚动等。

我的代码

import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.io.*;

public class TestCode extends JFrame {
     private final JFrame frame;

    public TestCode(){

        frame = new JFrame();

        JLabel title = new JLabel("Test Title");

        JPanel windowContainer = new JPanel();      
        JPanel topPanel = new JPanel();             
        final JPanel middlePanel = new JPanel();    
        JPanel bottomPanel = new JPanel();          

        JButton searchButton = new JButton("Search");
        JButton browseButton = new JButton("Browse...");
        JButton testButton = new JButton("Button 1");
        JButton exitButton = new JButton("Exit");

        final JTextField searchBar = new JTextField("Search database...");

        topPanel.setLayout(new GridLayout(2,0));
        topPanel.add(title);
                title.setHorizontalAlignment(JLabel.CENTER);
        topPanel.setPreferredSize(new Dimension(getWidth(), 100));
                // This is a subset of the top section. Top part is two panels, bottom panel is two cells (grid)
                JPanel topPanelSearch = new JPanel();
                topPanelSearch.setLayout(new GridLayout(0,2));
                topPanelSearch.add(searchBar);
                topPanelSearch.add(searchButton);
        topPanel.add(topPanelSearch);

// PROBLEM AREA STARTS

//      middlePanel.setLayout(new FlowLayout());
        middlePanel.setLayout(new GridLayout(0, 1, 10, 10));
//      middlePanel.setLayout(new BoxLayout(middlePanel, BoxLayout.PAGE_AXIS));
        JPanel innerContainer = new JPanel();

        innerContainer.setLayout(new BoxLayout(innerContainer, BoxLayout.PAGE_AXIS));
//      innerContainer.setLayout(new FlowLayout());
//      innerContainer.setLayout(new GridLayout(0, 1, 10, 10));

        for(int i = 0; i < 2; i++){
            JButton button = new JButton("Button ");
            button.setPreferredSize(new Dimension(400, 100));
            JPanel test = new JPanel();
            test.add(button);
            innerContainer.add(test);
        }

        JScrollPane midScroll = new JScrollPane(innerContainer);
        middlePanel.add(midScroll);

// PROBLEM AREA ENDS

        bottomPanel.setLayout(new GridLayout(0, 3));
        bottomPanel.setPreferredSize(new Dimension(getWidth(), 100));
        bottomPanel.add(testButton);
        bottomPanel.add(browseButton);
        bottomPanel.add(exitButton);

        windowContainer.setLayout(new BorderLayout());
        windowContainer.add(topPanel, BorderLayout.NORTH);
        windowContainer.add(middlePanel, BorderLayout.CENTER);
        windowContainer.add(bottomPanel, BorderLayout.SOUTH);

        frame.add(windowContainer);


        frame.setTitle("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(480, 800);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

    public static void main(String[] args){
        TestCode test = new TestCode();
    }
}

部分失败结果的视觉

我想要最左边的图片,但是当只有少量结果时,按钮应该整齐地堆叠(如中间图片),当有很多结果时,按钮应该可滚动。

我做错了什么?

enter image description here

1 个答案:

答案 0 :(得分:0)

尝试使用GridBagLayout和填充组件来获取剩余的垂直空间,从而强制按钮向上。

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.Box.Filler;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class GridbagButtons extends JFrame {

    private final JScrollPane jscrpButtons;
    private final JPanel jpButtons;

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

        jpButtons = new JPanel(new GridBagLayout());
        jscrpButtons = new JScrollPane(jpButtons);
        add(jscrpButtons, BorderLayout.CENTER);

        // add a custom number of buttons
        int numButtons = 10;
        for (int i = 0; i < numButtons; i++) {
            JButton jbButton = new JButton("Button");
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = i;
            jpButtons.add(jbButton, gbc);
        }

        // add a vertical filler as last component to "push" the buttons up
        GridBagConstraints gbc = new GridBagConstraints();
        Filler verticalFiller = new Filler(
                new java.awt.Dimension(0, 0), 
                new java.awt.Dimension(0, 0), 
                new java.awt.Dimension(0, Integer.MAX_VALUE));
        gbc.gridx = 0;
        gbc.gridy = numButtons;
        gbc.fill = java.awt.GridBagConstraints.VERTICAL;
        gbc.weighty = 1.0;
        jpButtons.add(verticalFiller, gbc);

        setSize(300, 200);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {        
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GridbagButtons().setVisible(true);
            }
        });

    }

}