2011-04-07 69 views
2

我在GridBagLayout中放置了组件。我想要所有组件之间以及JPanel本身之间的1px黑线。Swing Draw GridBagLayout组件中组件之间的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

回答

2

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

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


一种替代解决方案可能是让你的背景容器有一个黑色的背景和1页像素的插图,然后将非边界部件在其上,在它们之间为1间的象素的间隙。这应该导致非常精确的黑色线条,无论顶部没有组件,还可以消除多个边框会合并产生双倍宽度边框的问题。


最后,它看起来像我使用组件来绘制表格。你是否需要这些组件来实现某种行为,或者真的只需要在组件上放置表就可以了?你可以很方便地使用例如JLabel s JTextPanel s,并将它们的text属性设置为HTML,以用于任何想要显示的内容。 Java集成了一个相当复杂的HTML布局引擎,它甚至可以处理CSS的一个很好的子集,可以是内联的,也可以是来自href的d文件。

+0

卡尔,我试图得到精确的边界。如果两个组件的边框互相靠在一起,则会有2px的边框,而不是1px。 – 2011-04-07 20:37:53

+0

我尝试了黑色背景,使用1px填充,并重叠了白色组件,但由于某些原因,顶部和底部子组件的顶部和底部都有较粗的边框。另外,我从这个组件生成一个PDF,并担心黑色背景可能不是最佳的PDF指令,而不是实际的线坐标。 – 2011-04-07 20:39:22

+0

@ Sam Barnum:谢谢你的澄清!我没有完全解决你的问题,但我已经能够重现它。通过在不同的面板上设置不同的背景颜色,我能够证明你的内部组件不能完全填充外部面板:顶部,右侧和底部有2px的间隙。也许有没有你不知道或没有看过的插页? – 2011-04-08 14:26:37