1

我有以下程序在 java awt 中逐个字符串打印一个句子字符串:

package awt;

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.lowagie.text.pdf.DefaultFontMapper;

public class ItalicTest extends JPanel{
    private static final int FONT_SIZE = 9;
    protected static Graphics2D bgWorkGraphics = null;
    protected static Graphics2D fgWorkGraphics = null;
    private static DefaultFontMapper fontMapper = new DefaultFontMapper();


    static float width = 0;
    static int height = 0;
    static String arial_family = "Arial";
    static String arial_italic_filePath = "C:\\WINDOWS\\Fonts\\Ariali.ttf";

    static String familyToUse = arial_family;
    static String filepathToUse = arial_italic_filePath;

    public static final double AT_SCALE_X = 1.34;
    public static final double AT_SCALE_Y = 1.34;

    public static List<Image> outputList;

    public static Graphics2D currentGraphics = null;

    static List<String> myContentWords = new ArrayList<String>();
    static {
        myContentWords.add("and");
        myContentWords.add(" ");
        myContentWords.add("additional");
        myContentWords.add(" ");
        myContentWords.add("description");
        myContentWords.add(" ");
        myContentWords.add("text");
        myContentWords.add(" ");
        myContentWords.add("#");
        myContentWords.add(" ");
        myContentWords.add("4");
    }
   public void paint(Graphics g) {

      Graphics2D g2 = (Graphics2D)g;

      fontMapper.insertDirectory("C:\\Windows\\Fonts");

      Font font = new Font(familyToUse, java.awt.Font.ITALIC, FONT_SIZE);

      FontRenderContext frc = g2.getFontRenderContext();

      g2.setFont(font);

      TextLayout textLayout = null;
      float width1 = 0.0f;
      float x = 0.0f;
        float y = 8.2946780f;
        float previousWidth = 0.0f;
        for(int i=0; i<myContentWords.size(); i++) {
             textLayout = new TextLayout(myContentWords.get(i), font, frc);

             previousWidth = width1;

             x=x+previousWidth;
             width1 = textLayout.getAdvance();
            if(myContentWords.get(i).equals(" ")) {
                System.out.println("Width of space calculated is "+width1);
            }
            g2.drawString(myContentWords.get(i), x, y);
        }
   }

   public static void main(String[] args) {
      JFrame f = new JFrame();
      f.getContentPane().add(new ItalicTest());
      f.setSize(300, 200);
      f.setVisible(true);
   }

}

这给了我单词之间空格的错误宽度。所以,间距显得太宽了。这仅适用于斜体字体。

我需要知道是否有任何其他方法来检索正确的空间宽度?

我不想使用 drawString("and additional description text to # 4", x, y) 作为完整的东西。我需要一个字一个字地画出来。

通过使用字体度量获取字符串宽度的解决方案给出了正确的结果,但是,我需要从 TextLayout 中获取正确的值,因为在更大的应用程序中编写的算法使用 TextLayout 来计算高度、宽度等。这个算法完美地工作,当我们使用倾斜字体以外的任何字体。对于 Oblique 字体,它为任何输入字符串提供额外的宽度。我需要知道,如果倾斜字体有什么特别之处,如果是,那么在倾斜字体的情况下检索宽度的正确方法是什么?

4

1 回答 1

1

尝试并使用FontMetrics. 你可以在这里了解更多

private final Font font = new Font("impact", Font.ITALIC, 20);
....
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setFont(font);
    FontMetrics fm = g.getFontMetrics();
    int height = fm.getAscent();
    int y = getHeight()/2 + height/2;
    int x = 0;
    for (String s : list) {
        g.drawString(s, x, y);
        x += fm.stringWidth(s);
    }
}

在此处输入图像描述

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Italic extends JPanel{
    private final List<String> list;
    private final Font font = new Font("impact", Font.ITALIC, 20);

    public Italic() {
       list = createList();
    }

    private List<String> createList() {
        List<String> myContentWords = new ArrayList<>();
        myContentWords.add("and");
        myContentWords.add(" ");
        myContentWords.add("additional");
        myContentWords.add(" ");
        myContentWords.add("description");
        myContentWords.add(" ");
        myContentWords.add("text");
        myContentWords.add(" ");
        myContentWords.add("#");
        myContentWords.add(" ");
        myContentWords.add("4");
        return myContentWords;
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setFont(font);
        FontMetrics fm = g.getFontMetrics();
        int height = fm.getAscent();
        int y = getHeight()/2 + height/2;
        int x = 0;
        for (String s : list) {
            g.drawString(s, x, y);
            x += fm.stringWidth(s);
        }
    }

    @Override 
    public Dimension getPreferredSize() {
        return new Dimension(300, 100);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                JOptionPane.showMessageDialog(null, new Italic());
            }
        });
    }
}
于 2014-02-20T12:31:36.060 回答