2

我想模仿一个带有滚动条的表格,但是宽度有问题。这是一个极其简化的代码(但它是完整的应用程序,因此您可以轻松编译它并直接查看所有内容)。

package view;

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

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;

public class AppView
{
    private final JFrame main_frame;

    public AppView()
    {
        main_frame = new JFrame();
        main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main_frame.setTitle("Example");

        JPanel main_panel = new JPanel() {
            private static final long serialVersionUID = 1L;

            public Dimension getPreferredSize()
            {
                return new Dimension(300,  200);
            }
        };
        main_panel.setLayout(new MigLayout("fill"));

        JPanel table_panel = new JPanel();
        table_panel.setLayout(new MigLayout(new LC(), new AC().gap("0"), new AC().gap("0")));

        JScrollPane scroll_pane = new JScrollPane(table_panel);
        scroll_pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        int[] width_arr = {20, 20, 20, 20, 20};
        for (int i = 0; i < 60; i++) {
            for (int j = 0; j < width_arr.length; j++) {
                if (j == width_arr.length - 1)
                    table_panel.add(new JLabel(i + 1 + ", " + (j + 1)), new CC().width(width_arr[j] + "%").wrap());

                else
                    table_panel.add(new JLabel(i + 1 + ", " + (j + 1)),  new CC().width(width_arr[j] + "%"));
            }
        }

        main_frame.getContentPane().add(main_panel, BorderLayout.CENTER);
        main_panel.add(scroll_pane, new CC().grow());
        main_frame.pack();
        main_frame.setVisible(true);
    }

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

如您所见,我创建了一个table_panel并用scroll_pane. 然后我添加 60 行,每行有 5 个 JLabel。问题是,如果我指定每列的宽度以使总行宽为 100%,则滚动元素的宽度开始迅速增加。这是两个屏幕截图 - 一个用于禁用水平滚动的情况,另一个用于启用水平滚动的情况。 在此处输入图像描述在此处输入图像描述

我对这种行为的建议是JScrollPane元素的宽度非常大,但似乎这个建议是不正确的,因为如果我为每一列定义宽度,使总宽度为 98%,一切正常。

在此处输入图像描述

请帮助我理解这些奇怪的事情。提前致谢。

[更新]

我决定使用另一种方法来实现我所需要的。这种方法基于网格功能。有一个小条件 - 所有宽度值都应该是 5 的倍数。我想这个条件不是限制性的,因为很难想象需要超过 5% 精度的情况。首先,我添加了 20 个不可见元素(用于进一步调用span()方法):

Box empty;
for (int i = 0; i < 20; i++) {
    empty = new Box(BoxLayout.X_AXIS);
    empty.setVisible(false);
    if (i == 19) 
        table_panel.add(empty, "wrap");
    else
        table_panel.add(empty);
}

没有这些元素,span()方法就没有效果。这是完整的代码示例:

package view;

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

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;

public class AppView
{
    private final JFrame main_frame;

    public AppView()
    {
        main_frame = new JFrame();
        main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main_frame.setTitle("Example");

        JPanel main_panel = new JPanel() {
            private static final long serialVersionUID = 1L;

            public Dimension getPreferredSize()
            {
                return new Dimension(300,  200);
            }
        };
        main_panel.setLayout(new MigLayout("fill"));

        JPanel table_panel = new JPanel();
        table_panel.setLayout(new MigLayout(new LC().fill().debug(1).hideMode(2), new AC().gap("0"), new AC().gap("0")));

        JScrollPane scroll_pane = new JScrollPane(table_panel);
        scroll_pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        Box empty;
        for (int i = 0; i < 20; i++) {
            empty = new Box(BoxLayout.X_AXIS);
            empty.setVisible(false);
            if (i == 19) 
                table_panel.add(empty, "wrap");
            else
                table_panel.add(empty);
        }

        int[] width_arr = {20, 20, 20, 20, 20};
        for (int i = 0; i < 60; i++) 
            for (int j = 0; j < width_arr.length; j++) {
                if (j == width_arr.length - 1)
                    table_panel.add(new JLabel(i + 1 + ", " + (j + 1)), new CC().span(width_arr[j] / 5).wrap());

                else
                    table_panel.add(new JLabel(i + 1 + ", " + (j + 1)),  new CC().span(width_arr[j] / 5));
            }

        main_frame.getContentPane().add(main_panel, BorderLayout.CENTER);
        main_panel.add(scroll_pane, new CC().grow());
        main_frame.pack();
        main_frame.setVisible(true);
    }

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

这实际上工作得很好,并且不再需要水平滚动,但是不可见框的宽度存在问题 - 它们的宽度不是恒定的并且对于所有框都相等,它取决于 JLabels 宽度。所以比例不对。这里有一些截图,说明:

1) 最简单的情况:五列,每列 20% 的宽度,工作正常。 在此处输入图像描述

2)更复杂的例子:三列 - 10%、40%、50%。比例无效,因为第二列没有比第一列宽 4 倍。

在此处输入图像描述 在此处输入图像描述

好吧,现在我不知道下一步该做什么。我所有在互联网上寻找东西的尝试都是徒劳的。

4

0 回答 0