2013-02-02 37 views
2

我對這個正在開發的組件有視覺問題。它帶有2個JTextFields和2個JLabel,它是JPanel。我無法建立堅實的背景。我嘗試了幾種不透明/背景顏色組合,但沒有成功。複合組件背景/透明度

我不能附加圖像,使樣本圖像是here

任何幫助嗎?

package javaapplication1; 

import java.awt.Component; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.FontMetrics; 
import java.awt.Rectangle; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UIManager.LookAndFeelInfo; 

public class JavaApplication1 { 

public static void main(String[] args) { 
    try { 
     for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
      if ("Nimbus".equals(info.getName())) { 
       UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (Exception e) { 
    } 
    JFrame testFrame = new JFrame("Test Frame"); 
    testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    JDecimal decimal = new JDecimal(); 
    decimal.setPreferredSize(new Dimension(300, 100)); 
    testFrame.setLayout(null); 
    testFrame.getContentPane().add(decimal); 
    decimal.setSize(80, 25); 
    testFrame.setLocationRelativeTo(null); 
    testFrame.setSize(300, 200); 
    testFrame.setVisible(true); 
} 

public static class JDecimal extends JPanel { 

    private String currencyString = "00"; 
    private java.text.DecimalFormat format = (java.text.DecimalFormat) java.text.DecimalFormat.getInstance(); 
    JTextField integerField = new JTextField(); 
    JLabel comaLabel = new JLabel(); 
    JTextField fractionField = new JTextField(); 
    JLabel plusMinusLabel = new JLabel(); 
    JDecimalLayout JDecimalLayout = new JDecimalLayout(); 

    public JDecimal() { 
     init(); 
    } 

    public String getText() { 
     return integerField.getText() + "." + fractionField.getText(); 
    } 

    private void init() { 
     this.setLayout(JDecimalLayout); 
     this.add(integerField); 
     this.add(fractionField); 
     this.add(comaLabel); 
     this.add(plusMinusLabel); 
     integerField.setText("0"); 
     integerField.setHorizontalAlignment(JTextField.RIGHT); 
     comaLabel.setText(format.getDecimalFormatSymbols().getDecimalSeparator() + ""); 
     fractionField.setText(currencyString); 
     plusMinusLabel.setText(""); 
     format.setDecimalSeparatorAlwaysShown(true); 
     // borders 
     javax.swing.border.Border b = integerField.getBorder(); 
     integerField.setBorder(null); 
     fractionField.setBorder(null); 
     comaLabel.setBorder(null); 
     plusMinusLabel.setBorder(null); 
     this.setBorder(b); 
    } 

    public void reshape() { 
     invalidate(); 
     validate(); 
    } 

    private class JDecimalLayout implements java.awt.LayoutManager { 

     public void addLayoutComponent(String name, Component comp) { 
     } 

     public void layoutContainer(Container parent) { 
      Rectangle r = parent.getBounds(); 
      FontMetrics fm = parent.getFontMetrics(integerField.getFont()); 
      int sirinaSlova = fm.stringWidth("0"); 
      plusMinusLabel.setBounds(new Rectangle(r.width - sirinaSlova - 2, 2, sirinaSlova, r.height - 4)); 
      fractionField.setBounds(new Rectangle(r.width - sirinaSlova - 2 - sirinaSlova * 2, 2, sirinaSlova * 2 + 1, r.height - 4)); 
      comaLabel.setBounds(new Rectangle(r.width - 2 - sirinaSlova - sirinaSlova * 2 - sirinaSlova, 0, sirinaSlova, r.height)); 
      integerField.setBounds(new Rectangle(2, 2, comaLabel.getBounds().x - 2, r.height - 4)); 
     } 

     public Dimension minimumLayoutSize(Container parent) { 
      return parent.getPreferredSize(); 
     } 

     public Dimension preferredLayoutSize(Container parent) { 
      return parent.getPreferredSize(); 
     } 

     public void removeLayoutComponent(Component comp) { 
     } 
    } 
} 

}

+0

無關:不做組件的任何手動尺寸/定位,這是一個合適的佈局管理 – kleopatra

回答

4
  1. 要對一個JPanel堅實的背景,你只需要調用setBackground()就可以了。例如在您的init()中,請撥打setBackground(Color.WHITE);(默認情況下,所有JPanel都是不透明的)
  2. 請勿使用null佈局。
  3. 不要叫setPreferredSize()任何地方
  4. 如果實現LayoutManager,在方法preferredLayoutSize(),你不能返回parent.getPreferredSize();,因爲它是需要計算(它創建了一個無限循環)正是。
  5. 您可以使用JFormattedTextField來實現完全相同的行爲並減少100行。
  6. (使用SwingUtilities.invokeLater

反正總是開始於美國東部時間你的用戶界面,這裏是你的代碼的固定版本:

import java.awt.Color; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UIManager.LookAndFeelInfo; 

public class JavaApplication1 { 

    public static void main(String[] args) { 
     try { 
      for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (Exception e) { 
     } 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame testFrame = new JFrame("Test Frame"); 
       testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       JDecimal decimal = new JDecimal(); 
       testFrame.setLayout(new GridBagLayout()); 
       testFrame.getContentPane().add(decimal, new GridBagConstraints()); 
       testFrame.pack(); 
       testFrame.setLocationRelativeTo(null); 
       testFrame.setVisible(true); 
      } 
     }); 
    } 

    public static class JDecimal extends JPanel { 

     private String currencyString = "00"; 
     private java.text.DecimalFormat format = (java.text.DecimalFormat) java.text.DecimalFormat.getInstance(); 
     JTextField integerField = new JTextField(); 
     JLabel comaLabel = new JLabel(); 
     JTextField fractionField = new JTextField(); 
     JLabel plusMinusLabel = new JLabel(); 

     public JDecimal() { 
      init(); 
     } 

     public String getText() { 
      return integerField.getText() + "." + fractionField.getText(); 
     } 

     private void init() { 
      this.setLayout(new GridBagLayout()); 
      integerField.setColumns(10); 
      fractionField.setColumns(2); 
      this.add(plusMinusLabel, new GridBagConstraints()); 
      this.add(integerField, new GridBagConstraints()); 
      this.add(comaLabel, new GridBagConstraints()); 
      this.add(fractionField, new GridBagConstraints()); 
      integerField.setText("0"); 
      integerField.setHorizontalAlignment(JTextField.RIGHT); 
      comaLabel.setText(String.valueOf(format.getDecimalFormatSymbols().getDecimalSeparator())); 
      fractionField.setText(currencyString); 
      plusMinusLabel.setText(" "); 
      format.setDecimalSeparatorAlwaysShown(true); 
      // borders 
      javax.swing.border.Border b = integerField.getBorder(); 
      integerField.setBorder(null); 
      fractionField.setBorder(null); 
      comaLabel.setBorder(null); 
      plusMinusLabel.setBorder(null); 
      this.setBorder(b); 
      setBackground(Color.WHITE); 
     } 

    } 
} 
+0

首先,感謝快速回答的專屬任務。我已經嘗試類似,但有外面的發光盒子。比較前後的邊界。 – user2035884

+0

通過比較邊界前後的含義,你是什麼意思?你在說圍繞JDecimal面板的邊框嗎?如果是這樣,就不要用'this.setBorder(b);'(註釋該行)來設置它。 –

+0

拍一個[看](http://postimage.org/image/m6h4zo8bt/),原創,背景設置,沒有邊框 – user2035884

5

你不能只設置一個JLabel的,因爲背景默認情況下它是不透明的。所以,你需要做的是這樣的:

label.setOpaque(true); 
label.setBackground(Color.WHITE);