BorderLayout.PAGE_START / NORTH 中的滚动条

Scrollbars in BorderLayout.PAGE_START / NORTH

有没有办法让添加到 BorderLayout.PAGE_START 区域的组件在(且仅当)没有足够的 space 时变得可滚动?

我附上了一个最小的例子。如果调整整个框架的大小,中间的标签将变为可滚动,顶部的标签则不会。

不幸的是,我无法更改 BorderLayout.PAGE_START 定位,因为这是框架给定的。但是我确实可以完全控制 myComponent.

的创建
  public static void main(String[] args){
    JPanel panel = new JPanel(new BorderLayout());
    JComponent myComponent = new JScrollPane(new JLabel("<html>START-START<br><br>START-START</html>"));

    panel.add(myComponent, BorderLayout.PAGE_START);
    panel.add(new JScrollPane(new JLabel("<html>CENTER-CENTER<br><br>CENTER-CENTER</html>")), BorderLayout.CENTER);

    final JFrame mainframe = new JFrame("Test");
    mainframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    mainframe.getContentPane().add(panel);

    javax.swing.SwingUtilities.invokeLater(() -> {
      mainframe.pack();
      mainframe.setVisible(true);});
 }

Is there a way such that a component that is added to the BorderLayout.PAGE_START area will become scrollable if there's not enough space?

是的。使其首选高度小于实际高度。 BorderLayout 尊重 PAGE_START 中包含的组件的首选高度,因此无论您在 JLabel 中放置多少行,它都会以其首选高度显示 – 没有滚动条.

试试下面的方法。

public static void main(String[] args) {
    JPanel panel = new JPanel(new BorderLayout());
    JComponent myComponent = new JScrollPane(new JLabel("<html>START-START<br><br>START-START</html>"));
    myComponent.setPreferredSize(new Dimension(100, 20));

    panel.add(myComponent, BorderLayout.PAGE_START);
    panel.add(new JScrollPane(new JLabel("<html>CENTER-CENTER<br><br>CENTER-CENTER</html>")),
            BorderLayout.CENTER);

    final JFrame mainframe = new JFrame("Test");
    mainframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    mainframe.getContentPane().add(panel);

    javax.swing.SwingUtilities.invokeLater(() -> {
        mainframe.pack();
        mainframe.setVisible(true);
    });
}

编辑

下面的代码没有给出最好的结果,但我认为这是可行的方法。您只需要尝试使用不同组件的不同尺寸即可。

我在 JFrame 的内容窗格中添加了 ComponentListener。当 JFrame 调整大小时,需要根据需要重新计算顶部组件和中心组件的高度,然后更新相关组件尺寸。请注意,以下代码不是完整的解决方案,但希望足以让您获得完整的解决方案。

public static void main(String[] args) {
    final JFrame mainframe = new JFrame("Test");
    JLabel topLabel = new JLabel("<html>START-START<br><br>START-START");
    JScrollPane topPane = new JScrollPane(topLabel);
    mainframe.add(topPane, BorderLayout.PAGE_START);
    JLabel centerLabel = new JLabel("<html>CENTER-CENTER<br><br>CENTER-CENTER");
    centerLabel.setMinimumSize(centerLabel.getPreferredSize());
    JPanel centerPane = new JPanel();
    centerPane.add(centerLabel);
    mainframe.add(centerPane, BorderLayout.CENTER);

    javax.swing.SwingUtilities.invokeLater(() -> {
        mainframe.pack();
        mainframe.setVisible(true);
        final Dimension centerPaneDim = centerPane.getPreferredSize();
        final Dimension topLabelDim = topLabel.getPreferredSize();
        mainframe.getContentPane().addComponentListener(new ComponentListener() {
            
            @Override
            public void componentShown(ComponentEvent e) {
                // Do nothing.
            }
            
            @Override
            public void componentResized(ComponentEvent e) {
                Dimension size = e.getComponent().getSize();
                if (size.height < centerPaneDim.height + topLabelDim.height + 10) {
                    topPane.setPreferredSize(new Dimension(topLabelDim.width, 10 + size.height - centerPaneDim.height));
                }
                else {
                    topPane.setPreferredSize(new Dimension(topLabelDim.width, topLabelDim.height + 10));
                }
                e.getComponent().revalidate();
                e.getComponent().repaint();
            }
            
            @Override
            public void componentMoved(ComponentEvent e) {
                // Do nothing.
            }
            
            @Override
            public void componentHidden(ComponentEvent e) {
                // Do nothing.
            }
        });
    });
}