我想在componentResized事件上设置按钮的字体大小。我得到屏幕尺寸和按钮的大小。但无法想办法计算要设置的首选字体大小。如果按钮的宽度增加/减少,字体大小也应相应增加/减少。我也无法获得Graphics的对象。
可以解决这个问题的解决方案是什么?
答案 0 :(得分:1)
这更多是强力解决方案。
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;
}
答案 1 :(得分:1)
您可以使用包含super.paintComponent的paintComponent创建一个ResizingButton类。然后在(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也会缩放边框,因此太麻烦了。
答案 2 :(得分:1)
如果您希望在调整大小时自动调整字体大小,可以尝试以下方法:
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();
}
});
}
}
答案 3 :(得分:1)
将文本设置为最后一个但只有一个答案会导致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);
}
}