【问题标题】:Where to insert the JScrollPane?在哪里插入 JScrollPane?
【发布时间】:2014-03-15 10:52:15
【问题描述】:

我已经使用 GridBagLayout 进行了布局,以强制子组件从底部向上堆叠。

我唯一剩下的就是让“容器”组件可滚动。

我尝试将 JScrollPane 插入不同的位置,但我找不到工作点。

我的 2 个内部 JPanel 在底部正确对齐,并且在我调整窗口大小时它们会正确调整大小。但是,当我将窗口的大小调整得太小而无法容纳文本时,我希望“容器”组件能够滚动。

请帮助新手:)

更新 1:滚动应该针对整个 GridBagLayout。不适用于每个单独的文本窗格。

更新 2:将代码更改为使用 BorderLayout,因为它对我的滚动问题没有影响。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class BorderTest extends JFrame {

private static final long serialVersionUID = 1L;

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

public BorderTest() {

    UIManager.put("swing.boldMetal", Boolean.FALSE);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Grid Bag");
    setSize(500, 300);
    setLocationRelativeTo(null);

    JPanel container = new JPanel();
    container.setLayout(new BorderLayout());
    container.setBorder(new LineBorder(Color.RED, 2));
    add(container);

    JPanel bottom = new JPanel();
    bottom.setBorder(new LineBorder(Color.YELLOW, 2));
    bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
    container.add(bottom, BorderLayout.SOUTH);

    JTextPane textPane = new JTextPane();
    textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane.setBorder(new LineBorder(Color.GREEN, 2));
    bottom.add(textPane);

    JTextPane textPane2 = new JTextPane();
    textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane2.setBorder(new LineBorder(Color.BLUE, 2));
    bottom.add(textPane2);

}

}

上面代码运行时的截图:

当我缩小窗口时,项目不适合(当然),然后我希望出现垂直滚动条(但不是水平的,因为单词应该只是换行)

如您所见,“红色”边框位于窗口“外部”,因此在此处放置滚动窗格似乎是个好主意。这是添加了滚动窗格的代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class BorderTest extends JFrame {

private static final long serialVersionUID = 1L;

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

public BorderTest() {

    UIManager.put("swing.boldMetal", Boolean.FALSE);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Grid Bag");
    setSize(500, 300);
    setLocationRelativeTo(null);

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBorder(new LineBorder(Color.CYAN, 2));
    add(scrollPane);

    JPanel container = new JPanel();
    container.setLayout(new BorderLayout());
    container.setBorder(new LineBorder(Color.RED, 2));
    scrollPane.setViewportView(container);

    JPanel innerContainer = new JPanel();
    innerContainer.setLayout(new BorderLayout());
    innerContainer.setBorder(new LineBorder(Color.PINK, 2));
    scrollPane.setViewportView(innerContainer);

    JPanel bottom = new JPanel();
    bottom.setBorder(new LineBorder(Color.YELLOW, 2));
    bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
    innerContainer.add(bottom, BorderLayout.SOUTH);

    JTextPane textPane = new JTextPane();
    textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane.setBorder(new LineBorder(Color.GREEN, 2));
    bottom.add(textPane);

    JTextPane textPane2 = new JTextPane();
    textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane2.setBorder(new LineBorder(Color.BLUE, 2));
    bottom.add(textPane2);

}

}

但结果不是我想要的。现在添加了水平 scoll 条,使我的文本项目成为一大行宽:

【问题讨论】:

  • 那个 GridBagLayout 没有做太多,因为你只添加了 1 个组件与该布局(网格是 1x1)。我不认为你理解它是如何工作的。你为什么要把它放在gridx = 0;gridy = 2;上?
  • GridBagLayout 帮助我将组件从下到上放置,而无需在内部组件上设置固定高度。我只是在哪里添加 JScrollPane 时遇到问题。我尝试添加到“容器”,但没有奏效。
  • 不,帮助您将组件从下到上放置的是带有 Y_AXIS 的 bottom 面板的 BoxLayout。 GridBagLayout 什么也没做。您可以将这些组件放在 BoirderLayout 的南侧位置以实现类似的效果。
  • 对不起,那些是错字。我已经更新了它。但是,Y_AXIS 并未将其置于底部。它只是从上到下堆叠,没有 GridBagLayout,它会导致 2 个面板每个高 50% 并填满整个高度。
  • 将 Y_AXIS 更改为 X_AXIS,您会看到 JPanel 仍在底部。这是 GridBagLayout 的帮助。

标签: java swing jscrollpane


【解决方案1】:

要将JScrollPane 添加到组件,您只需使用该组件创建一个JScrollPane,然后将JScrollPane 添加到您想要该组件的面板中。

所以而不是:

panel.add(component, constraints);

使用

JScrollPane scrollPane = new JScrollPane(component);
panel.add(scrollPane, constraints);

当然,您可以使用scrollPane 变量来稍微自定义JScrollPane,查看它的文档,但是通过将其简单地放入您的代码中,我们有:

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class GridBag extends JFrame
{

    private static final long serialVersionUID = 1L;

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

    public GridBag()
    {

        UIManager.put("swing.boldMetal", Boolean.FALSE);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Grid Bag");
        setSize(500, 300);
        setLocationRelativeTo(null);

        JPanel container = new JPanel(new GridBagLayout());
        container.setBorder(new LineBorder(Color.RED, 2));
        add(container);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 1;
        c.weightx = 1.0;
        c.weighty = 1.0;
        c.anchor = GridBagConstraints.LAST_LINE_START;

        JPanel bottom = new JPanel();
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
        bottom.setBorder(new LineBorder(Color.GREEN, 2));
        container.add(bottom, c);

        JTextPane textPane = new JTextPane();
        textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane.setBorder(new LineBorder(Color.BLACK, 2));
        bottom.add(new JScrollPane(textPane));

        JTextPane textPane2 = new JTextPane();
        textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane2.setBorder(new LineBorder(Color.BLUE, 2));
        bottom.add(new JScrollPane(textPane2));
    }
}

让它看起来像这样:

这可行但看起来不太好,所以让我向您展示如何使用 GridBagConstraints.weighty 属性进行正确的高度分布的示例。

我要做的是将两个面板添加到GridBagLayout(2 个单元格)中,并使用weighty 数字告诉他们要占用多少空间。为此,我想将 c.fill 更改为 BOTH

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class GridBag extends JFrame
{

    private static final long serialVersionUID = 1L;

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

    public GridBag()
    {

        UIManager.put("swing.boldMetal", Boolean.FALSE);

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setTitle("Grid Bag");
        setSize(500, 300);
        setLocationRelativeTo(null);

        JPanel container = new JPanel(new GridBagLayout());
        container.setBorder(new LineBorder(Color.RED, 2));
        add(container);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH; //make it fill both directions
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.weighty = 1.0; //modify this number to change the proportion of the screen division
        c.anchor = GridBagConstraints.CENTER; //for this example anything here goes.

        JPanel topPanel = new JPanel();
        topPanel.add(new JTextField("Put other components here"));
        //topPanel.setBorder(new LineBorder(Color.YELLOW, 2));
        container.add(topPanel, c);

        c.gridy = 1;
        c.weighty = 1.0; //modify this number to change the proportion of the screen division

        JPanel bottom = new JPanel();
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
        bottom.setBorder(new LineBorder(Color.GREEN, 2));
        container.add(bottom, c);

        JTextPane textPane = new JTextPane();
        textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane.setBorder(new LineBorder(Color.BLACK, 2));
        bottom.add(new JScrollPane(textPane));

        JTextPane textPane2 = new JTextPane();
        textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane2.setBorder(new LineBorder(Color.BLUE, 2));
        bottom.add(new JScrollPane(textPane2));
    }
}

看起来像这样:

上面的组件占屏幕的一半,两个textPanes占屏幕的一半,这是因为两个单元格(topPanelbottom)的weighty都是1.0,相同的值,所以比例是1:1。您可以更改这些数字以更改它们占用的空间。例如,将第一个权重设为 0.5 将使其比例为 1:2。

【讨论】:

  • 请注意,我在最后更改了关于权重值的评论,因为它们应该只从 0.0 变为 1.0。请记住,价值观本身并不重要,重要的是它们之间的比例。两个具有 1.0 或两个具有 0.5 的行为完全相同,只要它们的值大于 0.0
  • 对不起,我没有说清楚。我不希望每个组件都有一个滚动窗格。滚动窗格应用于“容器”(红色边框区域)。我只会用更多的“项目”填充“底部”。不会将其他组件放入“容器”内
  • @DanieleTesta 没有本质区别,container 是一个组件,我告诉你如何将 JScrollPanes 放入组件中。所以我相信你可以弄清楚如何把它放在那里而不是放在 JTextPanes 中
  • 但如果我将滚动窗格放在容器之前(或内部),文本窗格将不再自动换行。相反,它们变成了一条巨大的宽滚动线。我会添加截图给你看。
  • @DanieleTesla 修复它的丑陋方法是手动设置最大/首选大小。正确的做法是使用不占用尽可能多空间的布局。您不想使用 fill = HORIZONTAL/BOTH。我不知道所有这样的布局,但快速的谷歌搜索给出了几个候选人。另外,如果您不打算放置更多组件,我不知道为什么要制作所有这些布局结构。
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多