Java AWT Initial drawString()调用需要很长时间

Java AWT Initial drawString()调用需要很长时间,java,macos,swing,edit,lag,Java,Macos,Swing,Edit,Lag,我遇到的问题非常简单——我使用Java AWT(和Swing)制作游戏,但是最初的图形。drawString(String str,int x,int y)调用太长。我没有设置自定义字体或任何东西。我没有设置任何渲染提示。我正在MacBookAir中使用MacSierra10.12.4,我还没有在Windows中测试我的程序。如果这有什么关系的话 如果您不想花时间阅读这个最小的示例,我有一个名为GamePanel的类,它扩展了我在main方法中添加到JFrame中的JPanel(并实现runna

我遇到的问题非常简单——我使用Java AWT(和Swing)制作游戏,但是最初的
图形。drawString(String str,int x,int y)
调用太长。我没有设置自定义字体或任何东西。我没有设置任何渲染提示。我正在MacBookAir中使用MacSierra10.12.4,我还没有在Windows中测试我的程序。如果这有什么关系的话

如果您不想花时间阅读这个最小的示例,我有一个名为GamePanel的类,它扩展了我在main方法中添加到JFrame中的JPanel(并实现runnable)。我在构造函数中初始化游戏线程,并在
run()
方法中启动游戏循环。然后,游戏循环使用摆动计时器进行重复。在游戏循环中,我通过
redraw()
调用
paintComponent(Graphics g)
——文本在
paintComponent
方法中绘制。这不是真正必要的信息,因为问题是可以重复的,没有游戏循环,只需使用游戏线程和
paintComponent
方法,但我把它放在这里只是简单的

感谢您的帮助

游戏类(JFrame)

游戏面板类(面板)


我知道在最小示例中,游戏循环的速度是不断变化的(这与一个好的游戏循环应该做的恰恰相反)。但在一个最小的示例中,这又有什么关系呢?

之所以会发生这种情况,是因为您从另一个线程调用了repaint。您可以阅读有关事件分派线程的信息


我也有同样的问题。我的解决方案是将我使用的字体保存在资源文件夹中,然后加载字体。 在Eclips中,您可以通过“新建/源文件夹”轻松创建文件夹。如果您遵循我的示例,文件夹的名称并不重要。我保存在资源文件夹中的字体称为“DroidSans Bold.ttf”


好的,我明白了。。。谢谢你的回答。不过,我现在还有一个问题。我将如何继续游戏循环?我会在EventDispatching线程中运行整个游戏循环吗?我不太了解Java中的游戏开发,但是在我构建非常简单的游戏时,我只是在EDT上使用了一个带有scheduleAtFixedRate的TimerTask来更新我的对象。如果我要创建一个更复杂、更大的游戏,我肯定会使用一个库来帮助渲染。我曾经和libgdx打过一些交道,我喜欢它,但在制作游戏的过程中,我不是回答我认为的问题的合适人选。祝你好运,并享受发展的乐趣!
public class Game {
    public static JFrame frame;
    public static JPanel gamePanel;

    public static void main(String[] args) {
        frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLayout(new BorderLayout());
        gamePanel = new GamePanel();
        frame.add(gamePanel, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
public class GamePanel() extends JPanel implements Runnable {
    public static Thread thread;

    public GamePanel() {
        super();

        setPreferredSize(new Dimension(640, 480));

        setFocusable(true);
        requestFocus();

        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public void run() {
        while (! Game.frame.isVisible()) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        EventQueue.invokeLater(new Runnable() {
            public void run() {gameLoop();}
        });
    }

    public void GameLoop() {
        repaint();

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        gameLoop();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent();
        g.drawText("Hello World", 10, 10);
    }
}
    Font font = null;

    try {
       font = Font.createFont(Font.TRUETYPE_FONT, new File(getClass().getResource("/DroidSans-Bold.ttf").getFile()));
       font = font.deriveFont(32f); // Set size to 32
    } catch (FontFormatException | IOException e) {
       e.printStackTrace();
    }

    JFrame jf = new JFrame();
    jf.setSize(800, 600);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);

    Graphics2D g = (Graphics2D)jf.getGraphics();

    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g.setFont(font);
    g.drawString("Hello", 100, 100);