Graphics2D setfont()大大减缓了Java应用程序的启动速度 [英] Graphics2D setfont() heavily slows down the start up of java application

查看:2038
本文介绍了Graphics2D setfont()大大减缓了Java应用程序的启动速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在用java制作游戏,每秒刷新60次。每次它执行一个循环,我用g2d绘制图像和字符串。事情工作正常,如果我做 g2d.setFont(新字体(Arial,Font.PLAIN,8));
和drawstring,这将是正常的,但是如果我将字体设置为一些不熟悉的字体,并且做同样的事情,那么在启动的第一秒钟内就会显示白屏,然后正确地绘制所有的东西,显然太慢了。(2秒)



我把一个jpanel放在一个jframe中,并重写jpanel的paint()方法来绘制我需要的所有东西。我已经在我的代码中使用了 SwingUtilities.invokeLater

  import javax.swing中*。 
import java.awt。*;
$ b $ public class Window扩展JFrame {
public Window(){
add(new Board());
setSize(800,600);
setVisible(true);

public static void main(String [] args){
new Window();


private class Board扩展JPanel {
Font font = new Font(Bitmap,Font.PLAIN,64);

public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g;
g2d.setFont(font);
g2d.drawString(This is slow,220,200);
Toolkit.getDefaultToolkit()。sync();
g2d.dispose();
g.dispose();





这不是循环但它是非常滞后的。



http:/ /fontsov.com/download-fonts/bitmap1159.html



这是可以降低我们的应用程序的可爱字体。 Arial会快速加载。首先,为了获得最好的帮助,请创建并发布您的 https://stackoverflow.com/help/mcve\">最小代码示例程序,供我们审查,测试和可能的修复。如果没有这个,我们很难完全理解你的问题。



考虑:


  • 覆盖 paintComponent 不是 paint 来获得双缓冲的优势。
  • 避免使用 invokeLater ,除非您确定代码是从Swing事件线程中调用的,并且您正在调用需要在事件线程中的调用。

  • 将缓慢运行的代码放在后台线程中,例如可以使用SwingWorker找到的代码。
  • 将文本放在JLabel中,而不是绘制
  • 将所有静态图像绘制到BufferedImage中,并将其显示在 paintComponent 中。然后直接在 paintComponent 方法中绘制所有不断变化的图像,如移动的精灵。

  • 不要忘记调用 super.paintCompmonent(g)在您的 paintComponent(Graphics g)方法覆盖中。





编辑

BufferedImage解决方案看起来像... 。

  import java.awt.Color; 
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event。*;
import java.awt.image.BufferedImage;

import javax.swing。*;

public class FooFun {

private static void createAndShowGui(){
ChildClass mainPanel = new ChildClass();

JFrame frame = new JFrame(FooFun);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane()。add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);


public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndShowGui();
}
});



抽象类FirstClass extends JPanel {

private static final int FPS = 20;
$ b $ public FirstClass(){
新计时器(1000 / FPS,taskPerformer).start();


ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent e){
gameLoop(); //在这里循环
repaint();
}
};
$ b $ private void gameLoop(){


$ b @Override
protected void paintComponent(Graphics g){
super .paintComponent(克);
Graphics2D g2d =(Graphics2D)g;
paintGame(g2d);
// Toolkit.getDefaultToolkit()。sync();
// g2d.dispose();
// g.dispose();
}

public abstract void paintGame(Graphics2D g2d);


class ChildClass extends FirstClass {
private static final Font font = new Font(Bitmap,Font.PLAIN,64);
private static final int PREF_W = 900;
private static final int PREF_H = 600;
private static final String NIGHT_IN_VEGAS_TEXT =拉斯维加斯之夜;
private static final int NIV_X = 240;
private static final int NIV_Y = 130;
private BufferedImage mainImage;
$ b $ public ChildClass(){
mainImage = new BufferedImage(PREF_W,PREF_H,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = mainImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(font);
g2.setColor(Color.black);
g2.drawString(NIGHT_IN_VEGAS_TEXT,NIV_X,NIV_Y);
g2.dispose();


$ b @Override
public void paintGame(Graphics2D g2d){
if(mainImage!= null){
g2d.drawImage (mainImage,0,0,this);


$ b @Override
public Dimension getPreferredSize(){
return new Dimension(PREF_W,PREF_H);







$ p
$ SwingWorker后台线程
$ b $ pre $ <$ p code> import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event。*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;

import javax.swing。*;

public class FooFun {

private static void createAndShowGui(){
ChildClass mainPanel = new ChildClass();

JFrame frame = new JFrame(FooFun);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane()。add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);


public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndShowGui();
}
});



抽象类FirstClass extends JPanel {

private static final int FPS = 20;
$ b $ public FirstClass(){
新计时器(1000 / FPS,taskPerformer).start();


ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent e){
gameLoop(); //循环这里
repaint();
}
};
$ b $ private void gameLoop(){


$ b @Override
protected void paintComponent(Graphics g){
super .paintComponent(克);
Graphics2D g2d =(Graphics2D)g;
paintGame(g2d);
}

public abstract void paintGame(Graphics2D g2d);


class ChildClass extends FirstClass {
private static final Font font = new Font(Bitmap,Font.PLAIN,64);
private static final int PREF_W = 900;
private static final int PREF_H = 600;
private static final String NIGHT_IN_VEGAS_TEXT =拉斯维加斯之夜;
private static final int NIV_X = 240;
private static final int NIV_Y = 130;
private BufferedImage mainImage;
$ b $ public ChildClass(){
imgWorker.addPropertyChangeListener(new ImgWorkerListener());
imgWorker.execute();


private class ImgWorkerListener implements PropertyChangeListener {
$ b $ @Override
public void propertyChange(PropertyChangeEvent pcEvt){
if(pcEvt.getNewValue ()== SwingWorker.StateValue.DONE){
try {
mainImage = imgWorker.get();
//如果没有运行
}的游戏循环,则在这里重绘()这里catch(InterruptedException | ExecutionException e){
e.printStackTrace();




$ b SwingWorker< BufferedImage,Void> imgWorker = new SwingWorker< BufferedImage,Void>(){

@Override
protected BufferedImage doInBackground()抛出Exception {
BufferedImage img = new BufferedImage(PREF_W,PREF_H,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(font);
g2.setColor(Color.black);
g2.drawString(NIGHT_IN_VEGAS_TEXT,NIV_X,NIV_Y);
g2.dispose();
return img;
}
};
$ b $ @Override
public void paintGame(Graphics2D g2d){
if(mainImage!= null){
g2d.drawImage(mainImage,0,0,this) ;


$ b @Override
public Dimension getPreferredSize(){
return new Dimension(PREF_W,PREF_H);
}

}


Hi guys I'm making a game by java and it refreshes itself 60 times per second. Every time it executes a loop and I use g2d to draw images and strings. Things work fine if I do g2d.setFont(new Font("Arial", Font.PLAIN, 8)); and drawstring and it would be normal, but if I set the font to some "unfamiliar" fonts and do the same thing, the swing would show white screen in the first second of start up then paint everything correctly and it's apparently too slow.(2 secs)

I put a jpanel in a jframe and override the paint() method of jpanel to draw everything I need. I've already used SwingUtilities.invokeLater in my code.

import javax.swing.*;
import java.awt.*;

public class Window extends JFrame{
    public Window(){
        add(new Board());
        setSize(800,600);
        setVisible(true);
    }
    public static void main(String[] args){
        new Window();
    }

    private class Board extends JPanel {
        Font font = new Font("Bitmap", Font.PLAIN, 64);

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D)g;
            g2d.setFont(font);
            g2d.drawString("This is slow", 220,200);
            Toolkit.getDefaultToolkit().sync();
            g2d.dispose();
            g.dispose();
        }
    }
}

This is not in a loop but it's very laggy.

http://fontsov.com/download-fonts/bitmap1159.html

This is the cutie font that slows our application down. "Arial" will load blazingly fast. How can I make this less laggy?

解决方案

First and foremost, for best help, create and post your minimal code example program for us to review, test, and possibly fix. Without this, it will be hard for us to fully understand your problem.

Consider:

  • Overriding paintComponent not paint to get the advantage of double buffering.
  • Avoid using invokeLater unless you're sure that the code is being called off of the Swing event thread and you are making calls that need to be on the event thread.
  • Put slow running code in a background thread such as that which can be found using a SwingWorker.
  • Putting your text in a JLabel, not drawn on a component.
  • Draw all static images to a BufferedImage, and displaying that in paintComponent. Then draw all changing images, such as your moving sprites, directly in the paintComponent method.
  • Don't forget to call your super.paintCompmonent(g) within your paintComponent(Graphics g) method override.

Edit
A BufferedImage solution could look like,....

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class FooFun {

   private static void createAndShowGui() {
      ChildClass mainPanel = new ChildClass();

      JFrame frame = new JFrame("FooFun");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

abstract class FirstClass extends JPanel {

   private static final int FPS = 20;

   public FirstClass() {
      new Timer(1000 / FPS, taskPerformer).start();
   }

   ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
          gameLoop(); //do loop here
          repaint();
      }
  };

  private void gameLoop() {

  }

  @Override
protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D)g;
   paintGame(g2d);
   // Toolkit.getDefaultToolkit().sync();
   // g2d.dispose();
   // g.dispose();
}

  public abstract void paintGame(Graphics2D g2d);
}

class ChildClass extends FirstClass {
   private static final Font font = new Font("Bitmap", Font.PLAIN, 64);
   private static final int PREF_W = 900;
   private static final int PREF_H = 600;
   private static final String NIGHT_IN_VEGAS_TEXT = "a Night in Vegas";
   private static final int NIV_X = 240;
   private static final int NIV_Y = 130;
   private BufferedImage mainImage;

   public ChildClass() {
      mainImage = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = mainImage.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      g2.setFont(font);
      g2.setColor(Color.black);
      g2.drawString(NIGHT_IN_VEGAS_TEXT, NIV_X, NIV_Y); 
      g2.dispose();
   }


   @Override
   public void paintGame(Graphics2D g2d) {
      if (mainImage != null) {
         g2d.drawImage(mainImage, 0, 0, this);     
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

}


Edit 2
Or with a SwingWorker background thread....

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

public class FooFun {

   private static void createAndShowGui() {
      ChildClass mainPanel = new ChildClass();

      JFrame frame = new JFrame("FooFun");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

abstract class FirstClass extends JPanel {

   private static final int FPS = 20;

   public FirstClass() {
      new Timer(1000 / FPS, taskPerformer).start();
   }

   ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
         gameLoop(); // do loop here
         repaint();
      }
   };

   private void gameLoop() {

   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      paintGame(g2d);
   }

   public abstract void paintGame(Graphics2D g2d);
}

class ChildClass extends FirstClass {
   private static final Font font = new Font("Bitmap", Font.PLAIN, 64);
   private static final int PREF_W = 900;
   private static final int PREF_H = 600;
   private static final String NIGHT_IN_VEGAS_TEXT = "a Night in Vegas";
   private static final int NIV_X = 240;
   private static final int NIV_Y = 130;
   private BufferedImage mainImage;

   public ChildClass() {
      imgWorker.addPropertyChangeListener(new ImgWorkerListener());
      imgWorker.execute();
   }

   private class ImgWorkerListener implements PropertyChangeListener {

      @Override
      public void propertyChange(PropertyChangeEvent pcEvt) {
         if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
            try {
               mainImage = imgWorker.get();
               // repaint() here if you don't have a game loop running
            } catch (InterruptedException | ExecutionException e) {
               e.printStackTrace();
            }
         }
      }
   }

   SwingWorker<BufferedImage, Void> imgWorker = new SwingWorker<BufferedImage, Void>() {

      @Override
      protected BufferedImage doInBackground() throws Exception {
         BufferedImage img = new BufferedImage(PREF_W, PREF_H,
               BufferedImage.TYPE_INT_ARGB);
         Graphics2D g2 = img.createGraphics();
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
         g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
               RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         g2.setFont(font);
         g2.setColor(Color.black);
         g2.drawString(NIGHT_IN_VEGAS_TEXT, NIV_X, NIV_Y);
         g2.dispose();
         return img;
      }
   };

   @Override
   public void paintGame(Graphics2D g2d) {
      if (mainImage != null) {
         g2d.drawImage(mainImage, 0, 0, this);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

}

这篇关于Graphics2D setfont()大大减缓了Java应用程序的启动速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆