我正在使用Java Swing和MigLayout(这是一个很棒的工具!)在java中创建一个项目,我遇到了一个问题。
为了显示尽可能大的每个字符串,我创建了一个JLabel子类,它根据组件的大小更改字体,我将附加我将提供的示例中的代码。
项目非常大,嵌套了很多面板,我还可以动态更改主窗口的内容,验证之后的所有内容。
但是,如果我尝试在MigLayout中使用组件的单元格配置,那就是错误的。
如果我使用相同的布局,使用相同的约束,但是使用普通的JLabel而不是使用我的自定义标签,一切都像魅力一样。
这里是示例的要点:
https://gist.github.com/bracco23/c47975ede0d857ac3b134f197c4371a2
代码分为两个文件:
JAdaptiveLabel.java,自定义组件,只需在文本更改或按需时重新计算最佳字体大小。
test.java,一个模拟示例。更改CUSTOM可以在我的组件和普通JLabel之间切换并查看差异。预期的布局是普通的JLabel。
有人能告诉我什么是错的,我该如何解决?
答案 0 :(得分:0)
好的,经过努力我解决了。
在测试之后,我得出结论(显而易见),我的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中添加了对调整大小方法的调用,因为您必须在标签调整大小或更改其内容时更改大小。