stringWidth это очень медленно

Мне нужно написать универсальный метод, нарисуйте по центру строки. Для того, чтобы делать то, что мне нужно знать ширину строки, и для того, чтобы посчитать, что у меня есть разные варианты:

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 секунды, чтобы вычислить, что это безумие, что я использую Eclipse с Java 1.8.0_121 на на MacBook 3,1 процессор Intel процессор i7, это безумие!

Что случилось с ним?

Первый Пример:

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 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

+1
2019-09-17 21:37:28
источник

Посмотрите другие вопросы по меткам