2016-10-23 23 views
0

我正在使用Java Swing和MigLayout(一個奇妙的工具!)在java中創建項目,我遇到了問題。MigLayout和JLabel派生顯示奇怪的行爲,不遵循佈局

要顯示每一個儘可能大的字符串,我創建了一個JLabel的子類,它根據組件的大小更改字體,我將在我將提供的示例中附加代碼。

該項目真的很大,有很多面板嵌套,我也改變主窗口的內容,驗證後面的所有內容。

但是,如果我嘗試使用MigLayout內的組件的單元配置,evrything是錯誤的。

如果我使用相同的佈局,使用相同的約束,而不是使用我的自定義標籤,我使用普通的JLabel,一切都像魅力一樣。

在這裏,實施例的要點是:

https://gist.github.com/bracco23/c47975ede0d857ac3b134f197c4371a2

的代碼在兩個文件:

  • JAdaptiveLabel.java,定製組件,僅僅重新計算最佳字體大小每當文本被改變或按需求。

  • test.java,一個模擬的例子。改變CUSTOM你可以在我的組件和一個普通的JLabel之間切換並查看其差異。預期的佈局是帶有普通JLabel的佈局。

任何人都可以給我一個線索有什麼問題,我該如何解決它?

回答

0

好吧,經過努力,我解決了。

經過測試後,我得出結論(顯而易見)somethig與我的JAdaptiveLabel是錯誤的。所以我在網上搜索了另一個版本,看看它是我的實現還是適應性本身的問題。

我來到了這個答案:@Warren K

我用他的課,因爲它是和它的工作,所以我的實現被竊聽。我從他的版本開始,改變了調整大小算法,因爲他是迭代(改變大小,直到你找到完美的一個),我的數學(只是得到所涉及的措施,並計算出完美的大小)。

它工作。現在佈局得到妥善處理,如果我調整窗口大小,標籤將更改字體大小。

下面的代碼修改:

package it.bracco23.util; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 

// Improved version of http://java-sl.com/tip_adapt_label_font_size.html 

public class JAdaptiveLabel extends JLabel { 

    private Graphics g; 
    private boolean init = false; 

    public JAdaptiveLabel(String text, Icon icon, int horizontalAlignment) { 
     super(text, icon, horizontalAlignment); 
     init(); 
    } 

    public JAdaptiveLabel(String text, int horizontalAlignment) { 
     super(text, horizontalAlignment); 
     init(); 
    } 

    public JAdaptiveLabel(String text) { 
     super(text); 
     init(); 
    } 

    public JAdaptiveLabel(Icon image, int horizontalAlignment) { 
     super(image, horizontalAlignment); 
     init(); 
    } 

    public JAdaptiveLabel(Icon image) { 
     super(image); 
     init(); 
    } 

    public JAdaptiveLabel() { 
     init(); 
    } 



    protected void init() { 
     addComponentListener(new ComponentAdapter() { 
      public void componentResized(ComponentEvent e) { 
       adaptLabelFont(JAdaptiveLabel.this); 
      } 
     }); 
     init = true; 
    } 

    protected void adaptLabelFont(JLabel l) { 
     if (g==null) { 
      return; 
     } 

     Rectangle r = l.getBounds(); 
     Insets ins = l.getInsets(); 
     r.x   = 0;  
     r.y   = 0;  
     Font f  = l.getFont(); 
     Dimension dim = getTextSize(l, f); 
     //0.9f is a scale factor to don't let the text take too much space 
     //without it will work, but the text may appear to close to the border 
     float xFactor = ((r.width - ins.left - ins.right) * 0.9f)/dim.width; 
     float yFactor = ((r.height - ins.top - ins.bottom) * 0.9f)/dim.height; 

     /*the next lines assure the scaling factors are not zero (can happen) 
     and are different enough from 1. Without this last check, it might happen 
     that the font starts to cycle between two sizes. */ 
     xFactor = (xFactor != 0 && Math.abs(xFactor - 1)>0.1) ? xFactor : 1; 
     yFactor = (yFactor != 0 && Math.abs(xFactor - 1)>0.1) ? yFactor : 1; 
     float fontSize = f.getSize() * Math.min(xFactor, yFactor); 

     setFont(f.deriveFont(f.getStyle(), fontSize)); 
     repaint(); 
    } 

    private Dimension getTextSize(JLabel l, Font f) { 
     Dimension size = new Dimension(); 
     FontMetrics fm = g.getFontMetrics(f); 
     size.width  = fm.stringWidth(l.getText()); 
     size.height  = fm.getHeight(); 
     return size; 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     this.g=g; 
    } 

     @Override 
    public void setText(String text) { 
     super.setText(text); 
     if(init){ 
      adaptLabelFont(this); 
     } 
    } 

} 

如果你使用這個版本我給的例子裏的類的,一切正常!

P.S.我還在setText中添加了對調整大小方法的調用,因爲在調整標籤大小或更改其內容時必須更改大小。