setfont java,Graphics2D setfont()大大减缓了Java应用程序的启动速度

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.

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 imgWorker = new SwingWorker() {

@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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值