stringWidth这很慢

时间:2019-09-17 19:37:28

标签: java swing

我需要编写一个绘制居中String的通用方法。为此,我需要知道String的宽度,并计算出我有不同的选择:

Rectangle2D rect=Toolkit.getDefaultToolkit().getFontMetrics(gc.getFont()).getStringBounds(text, gc);

AffineTransform affinetransform = new AffineTransform();    
FontRenderContext frc = new FontRenderContext(affinetransform,true,true);    
Rectangle2D rect=gc.getFont().getStringBounds(text, frc);

FontMetrics metrics = g.getFontMetrics(font);
metrics.stringWidth(text)

但是我使用哪种方法都没关系,大约需要1秒钟来计算,这太疯狂了,我在Macbook 3,1 GHz Intel Core i7上的Java 1.8.0_121中使用Eclipse,太疯狂了!

这是怎么了?

第一个示例:

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Map;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Main {


  public static void main(String[] args) {
    JFrame jf = new JFrame("Demo");
    Container cp = jf.getContentPane();
    MyCanvas1 tl = new MyCanvas1();
    cp.add(tl);
    jf.setSize(300, 200);
    jf.setVisible(true);
  }
}

class MyCanvas1 extends JComponent {

  public void paint(Graphics g) {
      long start=System.currentTimeMillis();
    Graphics2D g2 = (Graphics2D) g;

    drawCenteredString(g2, "Example", getBounds(), g.getFont());
    System.out.println("executed in:"+(System.currentTimeMillis()-start));


  }

  public void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
        FontMetrics metrics = g.getFontMetrics(font);

        int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
        // Determine the Y coordinate for the text (note we add the ascent, as in java 2d 0 is top of the screen)
        int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
        // Set the font
        g.setFont(font);
        // Draw the String
        g.drawString(text, x, y);
    }


}

在以下位置执行:922

示例2:

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Map;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Main {


  public static void main(String[] args) {
    JFrame jf = new JFrame("Demo");
    Container cp = jf.getContentPane();
    MyCanvas1 tl = new MyCanvas1();
    cp.add(tl);
    jf.setSize(300, 200);
    jf.setVisible(true);
  }
}

class MyCanvas1 extends JComponent {

  public void paint(Graphics g) {
      long start=System.currentTimeMillis();
    Graphics2D g2 = (Graphics2D) g;

    drawCenteredString(g2, "Example", getBounds(), g.getFont());
    System.out.println("executed in:"+(System.currentTimeMillis()-start));


  }

  public void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
      AffineTransform affinetransform = new AffineTransform();    
      FontRenderContext frc = new FontRenderContext(affinetransform,true,true);    
      Rectangle2D rect2=font.getStringBounds(text, frc);
        // Draw the String
        g.drawString(text, (int) (rect.width/2-rect2.getWidth()/2),(int) (rect.height/2-rect2.getHeight()/2));
    }


}

执行于:916

示例3:

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Map;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Main {


  public static void main(String[] args) {
    JFrame jf = new JFrame("Demo");
    Container cp = jf.getContentPane();
    MyCanvas1 tl = new MyCanvas1();
    cp.add(tl);
    jf.setSize(300, 200);
    jf.setVisible(true);
  }
}

class MyCanvas1 extends JComponent {

  public void paint(Graphics g) {
      long start=System.currentTimeMillis();
    Graphics2D g2 = (Graphics2D) g;

    drawCenteredString(g2, "Example", getBounds(), g.getFont());
    System.out.println("executed in:"+(System.currentTimeMillis()-start));


  }

  public void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
      AffineTransform affinetransform = new AffineTransform();    
      FontRenderContext frc = new FontRenderContext(affinetransform,true,true);    
      Rectangle2D rect2=Toolkit.getDefaultToolkit().getFontMetrics(font).getStringBounds(text, g);

        // Draw the String
        g.drawString(text, (int) (rect.width/2-rect2.getWidth()/2),(int) (rect.height/2-rect2.getHeight()/2));
    }


}

执行时间:908

似乎其他人也有类似的问题,但没有任何解决办法:

Java: Fastest way to draw text?

有人看到问题可能在哪里吗?

编辑: 只是使用Java 8u221进行的更新具有相同的结果,使用最新的Java 13却得到了一些改进,而不是900左右,它们在700毫秒左右的时间内执行了。。。我不敢相信。。。这似乎在Mac上非常慢。 。不管我使用的Java版本是什么...

EDIT2:

即使执行以下代码:

public class Main {


  public static void main(String[] args) {
      long start=System.currentTimeMillis();
      BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = image.createGraphics();

        drawCenteredString(g2, "Example", new Rectangle (0,0,300,300), g2.getFont());
        System.out.println("executed in:"+(System.currentTimeMillis()-start));
  }




  public static void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {

      Rectangle2D rect2=Toolkit.getDefaultToolkit().getFontMetrics(font).getStringBounds(text, g);
        // Draw the String
        g.drawString(text, (int) (rect.width/2-rect2.getWidth()/2),(int) (rect.height/2-rect2.getHeight()/2));
    }


}

我得到:在以下位置执行:1342

0 个答案:

没有答案