Java MIG布局+;JScrollPane宽度问题

Java MIG布局+;JScrollPane宽度问题,java,swing,jscrollpane,miglayout,Java,Swing,Jscrollpane,Miglayout,我想模拟一个带有滚动条的表格,但宽度有问题。 这是一个极其简化的代码(但它是一个完整的应用程序,所以您可以轻松地编译它并直接查看所有内容) 如果没有这些元素,span()方法将无效。 以下是完整的代码示例: package view; import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.

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

如果没有这些元素,
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();
            }
        });
    }
}
包视图;
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入javax.swing.Box;
导入javax.swing.BoxLayout;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.SwingUtilities;
导入net.miginfocom.layout.AC;
导入net.miginfocom.layout.CC;
导入net.miginfocom.layout.LC;
导入net.miginfocom.swing.MigLayout;
公共类AppView
{
专用最终JFrame主框架;
公共AppView()
{
主框架=新的JFrame();
main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
主框架集合标题(“示例”);
JPanel主面板=新JPanel(){
私有静态最终长serialVersionUID=1L;
公共维度getPreferredSize()
{
返回新维度(300200);
}
};
主面板设置布局(新布局(“填充”);
JPanel table_panel=新的JPanel();
表_panel.setLayout(新的MigLayout(新的LC().fill().debug(1).hideMode(2),新的AC().gap(“0”),新的AC().gap(“0”);
JScrollPane scroll\u pane=新的JScrollPane(表格面板);
scroll_pane.setHorizontalScrollBarPolicy(JScrollPane.HorizontalScrollBar_NEVER);
盒子是空的;
对于(int i=0;i<20;i++){
空=新框(BoxLayout.X_轴);
空。setVisible(false);
如果(i==19)
表_面板添加(空,“包装”);
其他的
表\u面板添加(空);
}
int[]宽度_arr={20,20,20,20,20};
对于(int i=0;i<60;i++)
对于(int j=0;j
这实际上工作得很好,不再需要水平滚动,但不可见框的宽度存在问题-它们的宽度不是恒定的,对于所有框都是相等的,这取决于JLabels宽度。所以比例是不正确的。 下面是一些屏幕截图,说明:

1) 最简单的情况是:五列,每列宽度20%,工作正常。

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


嗯,现在我不知道下一步该怎么办。我所有在互联网上查找内容的尝试都是徒劳的。

如果将滚动条策略更改为if_NEEDED.@mKorbel使用
scroll_pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_scrollbar_AS_NEEDED)的结果是什么在第二个屏幕截图上。不是MigLayout用户,但使用GrigLayout不会出现问题,必须测试返回JLabel的大小(第二幅图像)。必须有方法或参数如何将JLabel转换为1PreferredSize@mKorbel谢谢,你的回答帮助了我。您提到了GridLayout,所以我决定在Miglayout中使用网格功能,它工作得很好。当然,有一个小缺点-列应该具有相同的宽度,但使用列跨越可以避免这种情况。也许你应该复制你的评论并将其作为答案发布,这样我就可以将其标记为已接受?你可以发布你自己的答案,如果有,我将向上投票打印屏幕:-)
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);
}
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();
            }
        });
    }
}