摇摆绳:文本边界和线条包裹



我需要用图形#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。您甚至可以根据需要设置保证金。

相关内容

  • 没有找到相关文章

最新更新