2011-04-07 73 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