调整JScrollPane大小的最佳实践

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调整JScrollPane大小的最佳实践相关的知识,希望对你有一定的参考价值。

我在这个论坛(例如this one)中阅读了一些已回答的问题,其中严格建议避免使用setXXXSize()方法来调整swing应用程序中的组件大小。

所以,遇到我的问题,我想知道如何最好地调整JScrollPane的大小,以避免其父面板在没有任何控制的情况下增加其大小。

在编写一些代码之前,我想描述真实情况,因为我将发布一个“玩具示例”。

在我的JFrame中,我目前正在为我的内容窗格使用边框布局。在BorderLayout.CENTER有一个JPanel,我在那里做一些自定义绘画。在BorderLayout.EAST,有一个JPanel(比如说eastPanel)包含另一个面板中的一些组件(这个面板将被添加到BorderPaayout.NORTH的eastPanel),以及一个包含JTable的JScrollPane(添加到BorderLayout.CENTER的eastPanel)。这个表会有很多行。由于我希望eastPanel的高度与centerPanel的高度相同,我需要一些方法来避免JScrollPane增加其大小以尝试显示尽可能多的行。

现在除了在包含滚动窗格的eastPanel上调用setPreferredSize之外我无法找到另一种解决方案,但我不得不承认我讨厌这种解决方案。

示例代码

在这个代码示例中,我在eastPanel的北部和JScrollPane内部添加了一些随机标签,因为我的目的是发布一小段代码。但是,情况与我上面描述的情况非常相似。如果不使用这个“可怕的”代码行,我无法解决我的问题:

eastPanel.setPreferredSize(new Dimension(eastPanel.getPreferredSize().width, centerPanel.getPreferredSize().height));

对于像这样的简单情况,我想避免更复杂的布局。我错过了什么吗?此外,设置该空白边框是一种可接受的方式来设置面板的大小我将做一些自定义绘画?

代码:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class Test
{
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {                       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    new TestFrame().setVisible(true);
                }
                catch(Exception exception) {
                    JOptionPane.showMessageDialog(null, "Fatal error while initialiing application", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
    }
}
class TestFrame extends JFrame 
{
    public TestFrame() {
        super("Test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel pane = new JPanel(new BorderLayout(20, 0));
        pane.setBorder(new EmptyBorder(20, 20, 20, 20));
        JPanel centerPanel = new JPanel();
        centerPanel.setBackground(Color.WHITE);
        centerPanel.setBorder(new EmptyBorder(400, 400, 0, 0));
        // centerPanel.setPreferredSize(new Dimension(400, 400));
        JPanel eastPanel = new JPanel(new BorderLayout(0, 20));
        JPanel labelsContainer = new JPanel(new GridLayout(0, 1));
        for(int i=0;i<7;i++) labelsContainer.add(new JLabel(String.valueOf(i)));
        eastPanel.add(labelsContainer, BorderLayout.NORTH);
        JPanel moreLabelsContainer = new JPanel(new GridLayout(0, 1));
        for(int i=7;i<70;i++) moreLabelsContainer.add(new JLabel(String.valueOf(i)));
        JScrollPane scroll = new JScrollPane(moreLabelsContainer, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        eastPanel.add(scroll, BorderLayout.CENTER);
        eastPanel.setPreferredSize(new Dimension(eastPanel.getPreferredSize().width, centerPanel.getPreferredSize().height));
        pane.add(centerPanel, BorderLayout.CENTER);
        pane.add(eastPanel, BorderLayout.EAST);
        setContentPane(pane);
        pack();
        setLocationRelativeTo(null);
    }
}

谢谢你的帮助 !

答案

我不知道布局管理器根据面板中特定组件的高度来限制面板的高度。

一种方法是自定义包含两个子组件的父面板的行为。

代码可能是这样的:

@Override
public Dimension getPreferredSize()
{
    Dimension d = super.getPreferredSize();

    BorderLayout layout = (BorderLayout)getLayout();
    Component center = layout.getLayoutComponent(BorderLayout.CENTER);

    int centerHeight = center.getPreferreidSize().height;

    if (d.height > centerHeight)
        d.height = centerHeight;

    return d;
}

该方法将允许基于中心的组件动态计算高度。

另一种选择是编写自己的布局管理器。然后,您可以在布局管理器中控制此类逻辑。

此外,设置该空白边框是一种可接受的方式来设置面板的大小我将做一些自定义绘画?

我重写getPreferredSize()以返回适当的尺寸。

通过使用EmptyBorder,您将失去向面板添加真正边框的功能,因此我不推荐它。

以上是关于调整JScrollPane大小的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

UIView 绘图最佳实践

UIViewController 最佳实践——加载

JScrollPane 中的 JTable:禁用滚动条的最佳高度

更新片段参数的最佳实践?

在片段和活动之间进行通信 - 最佳实践

如何强制刷新/重绘 JScrollPane?