2012-01-06 99 views
2

我已經創建了一個文本字段組件,其中帶有一個「x」按鈕,用於清除該字段的文本。當使用Window的系統外觀和感覺(對於Windows)時,它非常適用,但是在使用Nimbus時我試圖獲得正確的外觀,即我無法像使用系統一樣使用button.setMargin(new Inset(0, 0, 0, 0)更改按鈕上的邊距外觀和感覺。如何覆蓋單個按鈕的Nimbus按鈕邊距

我確實在使用Nimbus時尋找幫助來設置邊距,這似乎是一個常見問題。我能夠找到一個部分解決方案,它允許我更改邊距,但它會更改所有按鈕的邊距,我只希望單個按鈕與默認值不同。

我明確地設置了'x'按鈕的大小,它是從'x'字符串的邊界計算出來的,以便它顯示出'x'的大小。

結果使用Windows的系統的外觀和感覺,這就是我要找的整體外觀時:使用默認的Nimbus外觀時

System look and feel

結果; 'x'溢出Nimbus允許的空間,導致省略號。使用雨雲並重寫Button.contentMargins時

Nimbus look and feel

結果:現在的「X」按鈕看起來是正確的,但「測試」按鈕看起來可怕。

Nimbus look and feel, plus margin overrides

的源代碼:

import java.awt.Graphics; 
import java.awt.Insets; 
import java.awt.geom.Rectangle2D; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.LookAndFeel; 
import javax.swing.UIDefaults; 
import javax.swing.UIManager; 
import javax.swing.UIManager.LookAndFeelInfo; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TextFieldTest {   
    public static void main(String[] args) { 
     boolean useNimbusLookAndFeel = false; 
     boolean overrideNimbusDefaults = false; 
     String lafName = UIManager.getSystemLookAndFeelClassName(); 

     if (useNimbusLookAndFeel) { 
      for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        lafName = info.getClassName();  
        break; 
       } 
      } 
     } 

     try { 
      UIManager.setLookAndFeel(lafName);    
     } 
     catch (ClassNotFoundException e) {} 
     catch (InstantiationException e) {} 
     catch (IllegalAccessException e) {} 
     catch (UnsupportedLookAndFeelException e) {} 

     //Code to set override default button insets for Nimbus: 
     if (useNimbusLookAndFeel && overrideNimbusDefaults) { 
      LookAndFeel laf = UIManager.getLookAndFeel();    
      if (laf != null) { 
       UIDefaults def = laf.getDefaults(); 
       def.put("Button.contentMargins", new Insets(0,0,0,0)); 
      } 
     }  

     //Create frame: 
     JPanel panel = new JPanel();   
     panel.add(new JButton("test")); 
     panel.add(new DeletableTextField()); 

     JFrame frame = new JFrame(); 
     frame.getContentPane().add(panel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    static class DeletableTextField extends JTextField { 
     JButton   mButton  = null; 

     public DeletableTextField() { 
      super(30); 
      setup(); 
     } 

     private void setup() { 
      mButton = new JButton("x"); 
      mButton.setMargin(new Insets(0, 0, 0, 0)); 
      add(mButton); 
     } 

     @Override 
     public void paint(Graphics g) { 
      g.setFont(mButton.getFont()); 
      Rectangle2D rect = g.getFontMetrics().getStringBounds(mButton.getText(), g); 
      int stringWidth  = (int)rect.getWidth(); 

      int topOffset  = 3; 
      int rightOffset  = 3; 
      int bottomOffset = 3; 
      int width   = (int)Math.ceil(stringWidth * 2.5); 
      int height   = getHeight() - (bottomOffset + topOffset);   
      int x_coord   = getWidth() - (rightOffset + width); 

      mButton.setMargin(new Insets(0, 0, 0, 0)); 
      mButton.setBounds(x_coord, topOffset, width, height); 

      super.paint(g); 
     } 
    } 
} 

我知道,我可以用其他方式做到這一點,像畫我自己的「X」在上面,但我認爲這將是很好拿當前外觀按鈕繪畫功能的優勢,可以實現統一的外觀。

所以我想問一下,在使用Nimbus的外觀時感覺沒有更改所有按鈕的邊距是否有改變單個JButton邊距的方法。或者,如果已經有一個外觀類似的swing組件(帶有'x'按鈕的文本框),我可以使用它。

+1

雖然我不能與你的問題的幫助,該功能是太酷了:d GL與修復! – Ari 2012-01-07 05:12:48

回答

7

雨雲支持per-instance overrides of LAF properties,在你的背景是這樣的:

mButton = new JButton("x"); 
    UIDefaults def = new UIDefaults(); 
    def.put("Button.contentMargins", new Insets(0,0,0,0)); 
    mButton.putClientProperty("Nimbus.Overrides", def); 
+0

感謝您的回答;這就是我尋找的結果。我的'x'按鈕現在至少可以在三種外觀(Mac,Windows和Nimbus)中很好地顯示。 – purplecat 2012-01-09 19:14:40

2

您可以使用其中一種較小尺寸的變體,然後讓按鈕顯示其首選大小,以保證文本有空間嗎?

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/size.html

+0

我嘗試了迷你尺寸,但按鈕仍然包含比我想要的文字更多的空間,而'x'太小了。但是知道我可以調整這樣的組件以供將來參考是有幫助的。 – purplecat 2012-01-09 19:12:19

1

也許,作爲一個黑客,你可以嘗試用左/右inset值玩,使他們不爲零,使文本顯示在兩個LAF的。

我知道,我可以用其他方式做到這一點,像畫我自己的「X」在上面

如果它來的那麼也許你可以使用Text Icon類做定製爲你畫畫。

+0

如果您建議更改如下所示的插入:'mButton.setMargin(new Insets(0,10,0,10));',它不適用於Nimbus,因爲它會覆蓋具有其默認值的任何設置邊距值。 – purplecat 2012-01-09 19:20:39