我需要用图形#drawString
绘制文本我正在绘制宽度和高度(通过拖动)的JPanel
的顶部。
我正在寻找一种生成界限的解决方案,以便我可以自动扭曲行并相应地调整文本,而不会溢出。
我认为我可以通过使用Fontmetrics的像素来进行编码,但是,我宁愿拥有一个自动执行此操作的组件(drawString
也不支持'n'
)。
在文档以及其他答案中,我发现了这一点:
Graphics2D g = ...;
Point2D loc = ...;
Font font = Font.getFont("Helvetica-bold-italic");
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout("This is a string", font, frc);
layout.draw(g, (float)loc.getX(), (float)loc.getY());
Rectangle2D bounds = layout.getBounds();
bounds.setRect(bounds.getX()+loc.getX(),
bounds.getY()+loc.getY(),
bounds.getWidth(),
bounds.getHeight());
g.draw(bounds);
确实绘制了字符串和边界,但它们没有效果,所以这里没有运气。
我可以使用任何类吗?
我可以使用任何类吗?
另一个选择是使用LinebreakMeasurer:
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.text.*;
import java.util.Objects;
import javax.swing.*;
import javax.swing.border.Border;
public final class LineBreakMeasurerTest {
private static final String TEXT = "1234567890 ABCDEFG HIJKLMN OPQRSTU VWXYZ";
private final JLabel lbl1 = new JLabel(TEXT);
private final JTextArea lbl2 = new JTextArea(TEXT);
private final JLabel lbl3 = new WrappingLabel(TEXT);
public JComponent makeUI() {
Border b = BorderFactory.createLineBorder(Color.GREEN, 5);
lbl1.setBorder(
BorderFactory.createTitledBorder(b, "JLabel"));
lbl2.setBorder(
BorderFactory.createTitledBorder(b, "JTextArea"));
lbl3.setBorder(
BorderFactory.createTitledBorder(b, "LineBreakMeasurer"));
lbl2.setFont(lbl1.getFont());
lbl2.setEditable(false);
lbl2.setLineWrap(true);
lbl2.setWrapStyleWord(true);
lbl2.setBackground(lbl1.getBackground());
JPanel p = new JPanel(new GridLayout(3, 1));
p.add(lbl1);
p.add(lbl2);
p.add(lbl3);
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
UIManager.put("swing.boldMetal", Boolean.FALSE);
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new LineBreakMeasurerTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class WrappingLabel extends JLabel {
//TEST: private AffineTransform at = AffineTransform.getScaleInstance(.8, 1d);
protected WrappingLabel(String text) {
super(text);
}
@Override protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(getForeground());
Insets i = getInsets();
float x = i.left;
float y = i.top;
int w = getWidth() - i.left - i.right;
AttributedString as = new AttributedString(getText());
//TEST: as.addAttribute(TextAttribute.FONT, g2.getFont());
//TEST: as.addAttribute(TextAttribute.TRANSFORM, at);
AttributedCharacterIterator aci = as.getIterator();
FontRenderContext frc = g2.getFontRenderContext();
LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
while (lbm.getPosition() < aci.getEndIndex()) {
TextLayout tl = lbm.nextLayout(w);
tl.draw(g2, x, y + tl.getAscent());
y += tl.getDescent() + tl.getLeading() + tl.getAscent();
}
g2.dispose();
}
}
最简单的解决方案:使用jtextarea。
您可以将其进行钻机,以使其甚至通过将其设置为Null,使其不可转移来看起来像JTextarea,如果您在其上调用setLineWrap(true)
和setWrapStyleWord(true)
,它将自动包装单词。要使它填充jpanel,请给面板一个边框,然后添加jtextarea borderlayout.center。您甚至可以根据需要设置保证金。