【问题标题】:Automatic height using BoxLayout Layout Manager使用 BoxLayout 布局管理器的自动高度
【发布时间】:2019-08-07 18:48:35
【问题描述】:

我遇到了一个新问题,在寻找解决方案的同时,我已经将所有头发一直伸到头骨。 我在下面模拟了我的问题,(我不知道这是否是正常程序,但我倾向于简化以理解问题并尝试解决它)。 我需要将两列 JPanel 分成 70/30% 的部分。 用户将在这些单独的列中添加大量 JLabels 和 JTextField 等,所有不同的宽度。我不能使用 GridLayout,因为并非所有对象的宽度都相同。当用户插入太多对象时,我希望整个 JPanel 滚动。到目前为止,我已经实现了 3 个 JPanel,其中一个主要是 BoxLayout,其中有 2 个 FlowLayout JPanel,并且在每个子 JPanel 中我都添加了我的对象。问题是我希望将 JScrollPane 应用于 MainPanel,而不是单独应用于每个子 JPanel,否则会很难看。我不知道如何以 JScroll 适用于我的整个 MainPanel 的方式仅将 setSize 设置为宽度而不是高度。 谢谢和最好的问候

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class alignments {

    Toolkit toolkit;
    JFrame frame;
    JPanel mainPanel, leftPanel, rightPanel;

    public static void main(String[] args) {
        alignments align = new alignments();
    }

    alignments() {
        frame = new JFrame();
        setDimm();

        mainPanel = new JPanel();
        leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
        rightPanel = new JPanel();

        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));

        leftPanel.setBackground(Color.gray);
        leftPanel.setBorder(BorderFactory.createLineBorder(Color.red));

        rightPanel.setBackground(Color.yellow);
        rightPanel.setBorder(BorderFactory.createLineBorder(Color.CYAN));

        // LEFT AREA BUTTONS
        String[] arry = { "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000",
                "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000" };
        for (int i = 0; i < arry.length; i++) {
            JButton button = new JButton(arry[i]);
            leftPanel.add(button);

        }

        String[] arry2 = { "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW",
                "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN",
                "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO" };

        for (int i = 0; i < arry2.length; i++) {
            JLabel labels = new JLabel(arry2[i]);
            rightPanel.add(labels);
        }

        // The problem I suspect is here because of course if I set the height
        // then the scroll will not work anymore. If I don't set up the sizes
        // then the first FlowLayout will cover 100% of the main JPanel.
        leftPanel.setMaximumSize(new Dimension(600, 600));
        leftPanel.setMinimumSize(new Dimension(600, 600));
        leftPanel.setPreferredSize(new Dimension(600, 600));

        rightPanel.setMaximumSize(new Dimension(200, 600));
        rightPanel.setMinimumSize(new Dimension(200, 600));
        rightPanel.setPreferredSize(new Dimension(200, 600));

        mainPanel.add(leftPanel);
        mainPanel.add(rightPanel);

        JScrollPane pane = new JScrollPane(mainPanel);

        frame.add(pane);

        frame.setVisible(true);

    }

    void setDimm() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.getContentPane().setBackground(Color.white);
        toolkit = frame.getToolkit();
        Dimension size = toolkit.getScreenSize();
        frame.setLocation((size.width - frame.getWidth()) / 2, (size.height - frame.getHeight()) / 2);

    }

}

【问题讨论】:

  • 我觉得 JTable 更适合您的需求。

标签: java swing jpanel flowlayout boxlayout


【解决方案1】:

该死的这些流布局。我不知道我的答案是否是完成它的最佳方法(感觉不喜欢),但它似乎有效。代替带有BoxLayout X 轴的外部面板,您可以use a JSplitPane. 它允许用户选择右/左面板的百分比。但是,如果您坚持使用 70% 的百分比,则必须在框架中添加 ComponentListener#componentResized 侦听器以保持此百分比。代码里面的一些cmets。我尝试了很多变化,只有这个似乎工作正常。尝试花更多时间来处理我所做的更改,但忘了在评论中提及。

public class Alignments { //Class names should start with an uppercase :)
    private JFrame frame;
    private JPanel leftPanel, rightPanel;

    public static void main(String[] args) {
        //All swing apps must run on their own thread
        SwingUtilities.invokeLater(() -> {
            Alignments align = new Alignments();
        });
    }

    public Alignments() {
        frame = new JFrame();
        frame.setLayout(new BorderLayout());

        leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
        rightPanel = new JPanel(new FlowLayout());

        leftPanel.setBackground(Color.gray);
        leftPanel.setBorder(BorderFactory.createLineBorder(Color.red));

        rightPanel.setBackground(Color.yellow);
        rightPanel.setBorder(BorderFactory.createLineBorder(Color.CYAN));

        // LEFT AREA BUTTONS
        String[] arry = { "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON",
                "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON",
                "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON",
                "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON",
                "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON",
                "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON",
                "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON",
                "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON",
                "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON",
                "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON",
                "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON",
                "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON", "4000", "FIRST BUTTON", "3", "SECOND BUTTON",
                "40001", "40001", "40001", "40001", "40001", "40001", "40001", "40001", "40001", "40003" };
        for (int i = 0; i < arry.length; i++) {
            JButton button = new JButton(arry[i]);
            leftPanel.add(button);

        }

        String[] arry2 = { "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN",
                "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN", "TURBO", "WOW", "MEGA FAIN",
                "TURBO", "WOW", "MEGA FAIN", "TURBO" };

        for (int i = 0; i < arry2.length; i++) {
            JLabel labels = new JLabel(arry2[i]);
            rightPanel.add(labels);
        }

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setLeftComponent(leftPanel);
        splitPane.setRightComponent(rightPanel);
        splitPane.setDividerSize(0); //User cannot move the divider

        JScrollPane scrollPane = new JScrollPane(splitPane);

        frame.add(scrollPane);
        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                int width = frame.getWidth() * 70 / 100; //70% of frame's width
                splitPane.setDividerLocation(width);

                Component comp = getComponentWithBiggestHeight(leftPanel);
                if (comp != null) {
                    int trueHeightOfLeftPanel = comp.getBounds().y + comp.getHeight() + 5; //+ some bottom insets? 
                    //Setting splitPane's width to 1 will make it being wrapped horizontally
                    splitPane.setPreferredSize(new Dimension(1, trueHeightOfLeftPanel));
                }
            }
        });
        setDimm();
        frame.setVisible(true);

    }

    private Component getComponentWithBiggestHeight(JPanel panel) {
        Component component = null;
        int max = -1;
        for (Component c : panel.getComponents()) {
            if (c.getBounds().y > max) {
                component = c;
            }
        }
        return component;
    }

    public void setDimm() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.getContentPane().setBackground(Color.white);
        frame.setLocationRelativeTo(null); //to the center of the screen
    }
}

小预览:

【讨论】:

  • 好吧,我想它解决了我的问题。然而,我希望我自己找到一个解决方案,只使用 JPanels 布局管理器和组件,或者本网站成员的解决方案,但使用更简单的实现。通过使用您的代码,我正在添加由于缺乏经验而我还不知道或从未想过要实现的东西,如果我迟早开始将它们添加到我的代码中,那将不是我的。我真的很震惊,仅仅使用 JPanel 和布局管理器的组合没有简单的解决方案......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 2018-05-09
  • 2014-01-03
  • 1970-01-01
相关资源
最近更新 更多