Swing在GridBagLayout组件中的组件之间绘制1px边框线

时间:2011-04-07 19:33:41

标签: java swing layout border

我在GridBagLayout中布置了组件。我想在所有组件之间以及JPanel本身之间使用1px黑线。

目前,我正在使用MatteBorder来执行此操作。父组件在顶部和左侧边缘上具有1px MatteBorder。每个子组件的右边和底边都有1px MatteBorder。 GridBagLayout上的水平和垂直间隙为零。

这主要是有效的,除了我偶尔会出现儿童边界与父母边界相遇的空白。 Gaps in borders

我怀疑这是由于子组件的额外空间分布的舍入/浮点不准确。

有没有更好的方法来实现这种外观?

附件是一个更简单的例子:

public class SSBGuiTest extends JDialog {
    public SSBGuiTest(Frame owner) {
        super(owner);
        initComponents();
    }

    public SSBGuiTest(Dialog owner) {
        super(owner);
        initComponents();
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
        wrapperPanel = new JPanel();
        panelWithTopLeftMatteBorder = new JPanel();
        panel1 = new JPanel();
        label1 = new JLabel();
        panel2 = new JPanel();
        label2 = new JLabel();
        panel3 = new JPanel();
        label3 = new JLabel();

        //======== this ========
        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());

        //======== wrapperPanel ========
        {
            wrapperPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
            wrapperPanel.setLayout(new BorderLayout());

            //======== panelWithTopLeftMatteBorder ========
            {
                panelWithTopLeftMatteBorder.setBorder(new MatteBorder(1, 1, 0, 0, Color.black));
                panelWithTopLeftMatteBorder.setLayout(new GridBagLayout());
                ((GridBagLayout)panelWithTopLeftMatteBorder.getLayout()).columnWidths = new int[] {0, 0};
                ((GridBagLayout)panelWithTopLeftMatteBorder.getLayout()).rowHeights = new int[] {0, 0, 0, 0};
                ((GridBagLayout)panelWithTopLeftMatteBorder.getLayout()).columnWeights = new double[] {1.0, 1.0E-4};
                ((GridBagLayout)panelWithTopLeftMatteBorder.getLayout()).rowWeights = new double[] {1.0, 1.0, 1.0, 1.0E-4};

                //======== panel1 ========
                {
                    panel1.setBorder(new MatteBorder(0, 0, 1, 1, Color.black));
                    panel1.setLayout(new BorderLayout());

                    //---- label1 ----
                    label1.setHorizontalAlignment(SwingConstants.CENTER);
                    label1.setText("label1");
                    panel1.add(label1, BorderLayout.CENTER);
                }
                panelWithTopLeftMatteBorder.add(panel1, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                    new Insets(0, 0, 0, 0), 0, 0));

                //======== panel2 ========
                {
                    panel2.setBorder(new MatteBorder(0, 0, 1, 1, Color.black));
                    panel2.setLayout(new BorderLayout());

                    //---- label2 ----
                    label2.setHorizontalAlignment(SwingConstants.CENTER);
                    label2.setText("label2");
                    panel2.add(label2, BorderLayout.CENTER);
                }
                panelWithTopLeftMatteBorder.add(panel2, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                    new Insets(0, 0, 0, 0), 0, 0));

                //======== panel3 ========
                {
                    panel3.setBorder(new MatteBorder(0, 0, 1, 1, Color.black));
                    panel3.setLayout(new BorderLayout());

                    //---- label3 ----
                    label3.setHorizontalAlignment(SwingConstants.CENTER);
                    label3.setText("label3");
                    panel3.add(label3, BorderLayout.CENTER);
                }
                panelWithTopLeftMatteBorder.add(panel3, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                    new Insets(0, 0, 0, 0), 0, 0));
            }
            wrapperPanel.add(panelWithTopLeftMatteBorder, BorderLayout.CENTER);
        }
        contentPane.add(wrapperPanel, BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(getOwner());
        // JFormDesigner - End of component initialization  //GEN-END:initComponents
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
    private JPanel wrapperPanel;
    private JPanel panelWithTopLeftMatteBorder;
    private JPanel panel1;
    private JLabel label1;
    private JPanel panel2;
    private JLabel label2;
    private JPanel panel3;
    private JLabel label3;
    // JFormDesigner - End of variables declaration  //GEN-END:variables
}

看起来像这样:

enter image description here

1 个答案:

答案 0 :(得分:2)

我认为我会使用BorderFactory.createLineBorder(color, thickness)而不是matteBorder,因为LineBorder似乎更接近你想要做的事情。为方便起见,您还可以使用LineBorder.createBlackLineBorder()

如果某些组件的外部没有完全碰到其容器的内部,请检查容器(即外部组件)是否设置了非零插件!


另一种解决方案可能是让您的背景容器具有黑色背景和1个像素插图,并在其上放置非边界组件,它们之间有1个像素间隙。这应该会导致在顶部没有组件的地方出现非常精确的黑线,并且还消除了多个边框会合并导致双宽边框的问题。


最后,它让我觉得你正在使用组件来绘制表格。您是否需要这些组件具有某种行为,或者只是将表放在组件上就可以了?你可以使用例如非常方便的方法JLabel s JTextPanel s并将其text属性设置为HTML,以用于您想要显示的内容。 Java包含了一个相当复杂的HTML布局引擎,它甚至可以处理一个很好的CSS子集,无论是内联还是来自href'文件。