Swing:GridLayout中的级联JPanel会导致调整大小

时间:2015-12-05 13:12:40

标签: java swing layout-manager grid-layout

我遇到了级联JPanelGridLayout s的奇怪行为。

以下演示显示了我的问题:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class JPanelGridLayoutDemo {

    public static void main(String[] args) {
        JFrame frame = new JFrame("JPanel GridLayout Demo");

        int cols = 5, rows = 5;
        int innerCols = 15, innerRows = 15;

        frame.setLayout(new GridLayout(cols, rows, 0, 0));

        for (int col = 0; col < cols; col++) {
            for (int row = 0; row < rows; row++) {
                JPanel panel = new JPanel();
                panel.setBackground(new Color((int)(Math.random() * 0x1000000)));

                // panel.setLayout(new GridLayout(cols, rows, 0, 0));
                // fixed it as FastSnail suggested
                panel.setLayout(new GridLayout(innerCols, innerRows, 0, 0));
                frame.add(panel);

                for (int innerCol = 0; innerCol < innerCols; innerCol++) {
                    for (int innerRow = 0; innerRow < innerRows; innerRow++) {
                        JPanel innerPanel = new JPanel();
                        innerPanel.setBackground(new Color((int)(Math.random() * 0x1000000)));
                        panel.add(innerPanel);
                    }
                }
            }
        }

        frame.setSize(new Dimension(400, 300));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

这将显示以下面板:

400x300px (standard size)

我通常不希望看到外面板的背景颜色。 GridLayout通常表现为填充父容器。当我将面板水平调整到特定的框架宽度时,它就是这样。然后按预期显示:

436x300px (resized)

一旦我再次调整大小,就会再次出现差距。似乎在frameSize % x == 0时一切都正常,如果这有助于理解问题。

如何解决此问题,以便内部面板始终填写整个父容器?我是否必须覆盖GridLayout? 对我来说,这似乎是GridLayout的实现问题,如舍入问题或其他问题。

我修改了内部GridLayouts作为FastSnail建议,差距不小但仍然可见:

inner GridLayout fixed

背景资料/附带问题:

我希望渲染一个类似于此的可视化,并首先考虑像素方式渲染。但我想提供悬停,突出显示,点击事件和动态调整大小,因此我在这种情况下使用面板。你有没有看到任何问题(性能问题除外)?

1 个答案:

答案 0 :(得分:0)

正如我发现here(和建议的FastSnail)GridLayout因内部组件的大小计算而产生间隙。

因此,如果您有一个100px宽面板,则其包含15个面板的大小将为6px100/15 = 6.67)。结果10px100 - 6 * 15)会产生差距。

因此我将GridLayout更改为MigLayout,现在它按预期工作:

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

public class JPanelGridLayoutDemo  {

    public static void main(String[] args) {
        JFrame frame = new JFrame("JPanel GridLayout Demo");

        int cols = 5, rows = 5;
        int innerCols = 15, innerRows = 15;

        // fill, remove margin, remove grid gaps
        frame.setLayout(new MigLayout("fill, insets 0, gapx 0, gapy 0"));

        for (int col = 0; col < cols; col++) {
            for (int row = 0; row < rows; row++) {
                JPanel panel = new JPanel();
                panel.setBackground(new Color((int) (Math.random() * 0x1000000)));
                panel.setLayout(new MigLayout("fill, insets 0, gapx 0, gapy 0"));

                // cell position, fill, min-width 1, min-height 1
                frame.add(panel, String.format("cell %d %d, grow, w 1::, h 1::", col, row));

                for (int innerCol = 0; innerCol < innerCols; innerCol++) {
                    for (int innerRow = 0; innerRow < innerRows; innerRow++) {
                        JPanel innerPanel = new JPanel();
                        innerPanel.setBackground(new Color((int) (Math.random() * 0x1000000)));
                        panel.add(innerPanel, String.format("cell %d %d, grow, w 1::, h 1::", innerCol, innerRow));
                    }
                }
            }
        }

        frame.setSize(new Dimension(400, 300));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }

}