JScrollPane 内部的内部 JScrollPane 无法正常工作

Inner JScrollPane Inside a JScrollPane Is Not Working Properly

我正在尝试创建一个带有滚动条的容器,并且容器内部有两个内部面板。在顶部内部面板内还有另一个 JScrollPane。

但目前我遇到的问题是我的顶部内部面板太长(宽度)顶部内部面板内的滚动条被禁用,我只能滚动容器的滚动条。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class TestFrame {

    public static void main(String... args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        for (int i = 0; i < 10; i++) {
            panel.add(new JButton("Hello-" + i));
        }
        JScrollPane scrollPane = new JScrollPane(panel);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        JPanel contentPane = new JPanel(new BorderLayout());

        JPanel contentPaneSub = new JPanel();
        contentPaneSub.add(scrollPane);

        contentPane.add(contentPaneSub, BorderLayout.NORTH);

        JPanel centerPanel = new JPanel(new FlowLayout());
        centerPanel.add(new JButton("Example"));
        contentPane.add(centerPanel, BorderLayout.CENTER);

        JScrollPane scrollPane1 = new JScrollPane(contentPane);
        scrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);

        frame.setContentPane(scrollPane1);
        //for demo purpose we set this using hard coded way
        //in real life project the java will auto adjust it size based on windows resolution
        frame.setSize(new Dimension(500, 160));
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }
}

我希望得到的是,如果顶部内部面板的宽度太长,那么顶部内部面板内的滚动条将可见并允许滚动。不是容器中的滚动条。

我在尝试解决此问题时遇到了两个不同的问题。第一个是让 JScrollPane 包含在 window 中,第二个是让 JScrollPane 的大小调整为动态的。

我能够解决第一个问题,但无法使用自定义 class 完全解决第二个问题。 JScrollPane 会随着 window 的增加而动态增加宽度,但不会随着 window 的大小而动态缩小。这是因为当window尺寸减小时,外层JScrollPane锁定了里面内容的宽度,包括内层JScrollPane.

我无法找到一种方法让内部窗格在不有效删除外部窗格功能的情况下动态收缩,这是行不通的,因为你的问题是专门针对另一个功能中的 JScrollPane JScrollPane.

public class TestFrame {

    public static void main(String... args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        for (int i = 0; i < 10; i++) {
            panel.add(new JButton("Hello-" + i));
        }

        MyCustomPane scrollPane = new MyCustomPane(panel); //changed this line

        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        JPanel contentPane = new JPanel(new BorderLayout());

        JPanel contentPaneSub = new JPanel();
        contentPaneSub.add(scrollPane);

        scrollPane.setOuterContainer(contentPaneSub); //added this line

        contentPane.add(contentPaneSub, BorderLayout.NORTH);

        JPanel centerPanel = new JPanel(new FlowLayout());
        centerPanel.add(new JButton("Example"));
        contentPane.add(centerPanel, BorderLayout.CENTER);

        JScrollPane scrollPane1 = new JScrollPane(contentPane);
        scrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);

        frame.setContentPane(scrollPane1);
        //for demo purpose we set this using hard coded way
        //in real life project the java will auto adjust it size based on windows resolution
        frame.setSize(new Dimension(500, 160));
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }
}

MyCustomPane 的代码class:

public class MyCustomPane extends JScrollPane {
    Container outerContainer;

    public MyCustomPane(Component view) {
        super(view);
    }

    public void setOuterContainer(Container outerContainer) {
        this.outerContainer = outerContainer;
    }

    private Dimension getCustomDimensions() {
        if (outerContainer == null) {
            return new Dimension(0, 0);
        }
        return new Dimension(outerContainer.getWidth() - 10, 60); //10 pixels less than container width, arbitrary height
    }
    @Override
    public Dimension getMaximumSize() {
        return getCustomDimensions();
    }
    @Override
    public Dimension getMinimumSize() {
        return getCustomDimensions();
    }
    @Override
    public Dimension getPreferredSize() {
        return getCustomDimensions();
    }
}