簡體   English   中英

擺動縮放組件的文字字體

[英]Swing Scale a Text Font of Component

我想在componentResized事件上設置按鈕的字體大小。 我得到了屏幕尺寸和按鈕的尺寸。 但是無法計算出要設置的首選字體大小。 如果按鈕的寬度增加/減少,字體大小也應相應增加/減少。 我也無法獲得Graphics對象。

解決此問題的解決方案是什么?

將文本設置為最后一個答案中的一個會導致CPU負擔很大。 我的建議是相應地縮放字體:

public class ScalableJButton extends JButton {
    int mCurrentSize = 0;
    Font mInitialFont = null;
    int mInitialHeight;

    private static final long serialVersionUID = 1L;

    public ScalableJButton(String pString) {
        super(pString);
        init();
    }

    public ScalableJButton() {
        super();
        init();
    }

    private void init() {
        mInitialFont = getFont();
    }

    @Override
    protected void paintComponent(Graphics g) {
        if (mInitialHeight == 0) {
            mInitialHeight = getHeight();
        }
        int resizal = this.getHeight() * mInitialFont.getSize() / mInitialHeight;
        if(resizal != mCurrentSize){
            setFont(mInitialFont.deriveFont((float) resizal));
            mCurrentSize = resizal;
        }
        super.paintComponent(g);
    }
}

這更像是蠻力解決方案。

1)您可以嘗試使用以下方法獲取字體指標:

// get metrics from the graphics
FontMetrics metrics = graphics.getFontMetrics(font);
// get the height of a line of text in this font and render context
int hgt = metrics.getHeight();
// get the advance of my text in this font and render context
int adv = metrics.stringWidth(text);
// calculate the size of a box to hold the text with some padding.
Dimension size = new Dimension(adv+2, hgt+2);

2)然后,您可以搜索適合您組件的字體大小。

        Font savedFont = oldFont;
    for (int i = 0; i < 100; i++) {
        Font newFont = new Font(oldFont.getFontName(), oldFont.getStyle(), i);
        Dimension d = getFontSize(g,newFont,text);
        if(componentSize.height < d.height || componentSize.width < d.width){
            return savedFont;
        }
        savedFont = newFont;
    }

放在一起(注意這未經測試)

public Dimension getFontSize(Graphics graphics, Font font, String text){
    // get metrics from the graphics
    FontMetrics metrics = graphics.getFontMetrics(font);
    // get the height of a line of text in this font and render context
    int hgt = metrics.getHeight();
    // get the advance of my text in this font and render context
    int adv = metrics.stringWidth(text);
    // calculate the size of a box to hold the text with some padding.
    Dimension size = new Dimension(adv+2, hgt+2);
    return size;
}

public Font findFont(Dimension componentSize, Font oldFont, String text, Graphics g){
    //search up to 100
    Font savedFont = oldFont;
    for (int i = 0; i < 100; i++) {
        Font newFont = new Font(oldFont.getFontName(), oldFont.getStyle(), i);
        Dimension d = getFontSize(g,newFont,text);
        if(componentSize.height < d.height || componentSize.width < d.width){
            return savedFont;
        }
        savedFont = newFont;
    }
    return oldFont;
}

使用組件進行編輯以獲取FontMetrics

    public Dimension getFontSize(FontMetrics metrics ,Font font, String text){
    // get the height of a line of text in this font and render context
    int hgt = metrics.getHeight();
    // get the advance of my text in this font and render context
    int adv = metrics.stringWidth(text);
    // calculate the size of a box to hold the text with some padding.
    Dimension size = new Dimension(adv+2, hgt+2);
    return size;
}

public Font findFont(Component component, Dimension componentSize, Font oldFont, String text){
    //search up to 100
    Font savedFont = oldFont;
    for (int i = 0; i < 100; i++) {
        Font newFont = new Font(oldFont.getFontName(), oldFont.getStyle(), i);
        Dimension d = getFontSize(component.getFontMetrics(newFont),newFont,text);
        if(componentSize.height < d.height || componentSize.width < d.width){
            return savedFont;
        }
        savedFont = newFont;
    }
    return oldFont;
}

測量文字

您可以創建一個帶有paintComponent的ResizingButton類,該類包裝了super.paintComponent。 然后在(Graphics2D)圖形上進行調整大小的轉換。 原因:字體大小調整是逐步的。

如果您深入研究字體的大小調整,請使用帶有小數指標的FontRenderingContext。


為了回應評論,一些代碼:

public class ResizingButton extends JButton {

@Override
protected void paintComponent(Graphics g) {        
    int h = this.getHeight();
    final int DEFAULT_H = 26;
    double resizal = ((double)h) / DEFAULT_H;

    String t = getText();
    setText("<html><span style='font-size:" + (resizal*11) + "'>" + t);
    super.paintComponent(g);
    setText(t);
}

我發現以上(Java 6/7)有效。 Graphics2D.scale也可以縮放邊框,因此太麻煩了。

如果您希望字體大小在調整大小時自動調整,可以嘗試執行以下操作:

import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;


public final class ButtonFrame extends JFrame {

ButtonFrame(String buttonText) {
    final JButton button = new JButton(buttonText);

    addComponentListener(new ComponentAdapter() {
        @Override
        public void componentResized(ComponentEvent e) {
            float fittedFontSize = 1.0f;        
            while (getFittedText(button, fittedFontSize += 1.0f).equals(button.getText()));
            button.setFont(button.getFont().deriveFont(fittedFontSize - 1.0f));
            button.revalidate();
            button.repaint();
        }
    });

    getContentPane().add(button);
}

private String getFittedText(JButton button, float fontSize) {
    Insets i = button.getInsets();
    Rectangle viewRect = new Rectangle();
    Rectangle textRect = new Rectangle();
    Rectangle iconRect = new Rectangle();
    viewRect.x = i.left;
    viewRect.y = i.top;
    viewRect.width = button.getWidth() - (i.right + viewRect.x);
    viewRect.height = button.getHeight() - (i.bottom + viewRect.y);
    textRect.x = textRect.y = textRect.width = textRect.height = 0;
    iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;

    return SwingUtilities.layoutCompoundLabel(
            button, 
            button.getFontMetrics(button.getFont().deriveFont(fontSize)),
            button.getText(),
            button.getIcon(),
            button.getVerticalAlignment(),
            button.getHorizontalAlignment(),
            button.getVerticalTextPosition(),
            button.getHorizontalTextPosition(),
            viewRect,
            textRect,
            iconRect,
            button.getIconTextGap());
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {         
        @Override
        public void run() {
            JFrame frame = new ButtonFrame("sample text");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.setVisible(true);
            frame.pack();
        }
    });     
}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM