gpt4 book ai didi

java - 在进行任何绘图之前调用 setVisible 属性

转载 作者:行者123 更新时间:2023-12-02 09:03:08 27 4
gpt4 key购买 nike

我正在尝试在 Swing 中构建游戏,我知道我可以使用其他工具,但这仅用于学习目的。我面临的问题与线程有关。

基本上,在对 JPanel(GamePanel 类)进行任何绘制之前,主线程会运行 JFrame(Window 类)的 setVisible 属性。在我做了一些研究之后,我发现我可以使用 SwingUtilities.invokeLater() 方法解决这个问题,该方法应该给游戏线程一些时间来准备在 JPanel 上制作的绘图。

我还尝试将 setVisible (true) 属性放置在不同的线程中,并使该线程 hibernate 2、3 秒。这两种方法有时有效,有时无效。

我不知道这是否有什么不同,但我的操作系统是:macOS Catalina。

导致此线程问题的简单示例。

游戏启动器

public class GameLauncher {

public GameLauncher(){
new Window("MyGame");
}

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

}

窗口

public class Window extends JFrame {

public Window(String title){
setTitle(title);

setContentPane(new GamePanel(1280, 1280));
setLocationRelativeTo(null);
setIgnoreRepaint(true);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setVisible(true);
SwingUtilities.invokeLater(()->setVisible(true));
}
}

游戏面板

package com.progresso.games;

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

public class GamePanel extends JPanel implements Runnable {

public int width;
public int height;

private BufferedImage bufferedImage;

private Thread gameThread;
private boolean isRunning = false;

Graphics2D graphics2D = null;

public GamePanel(int width, int height){
this.width = width;
this.height = height;

setPreferredSize(new Dimension(width, height));
setFocusable(true);
requestFocus();
}

@Override
public void addNotify() {
super.addNotify();
if(gameThread == null){
gameThread = new Thread(this, "GameThread");
gameThread.start();
}
}

private void init(){
isRunning = true;

bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
graphics2D = (Graphics2D) bufferedImage.getGraphics();
}

@Override
public void run() {
init();

while (isRunning) {
update();
render(graphics2D);
draw();
}

}

private void update(){ }

private void render(Graphics2D g){
if(g != null){
g.setColor(Color.BLACK);
g.fillRect(0,0, width, height);
}
}

private void draw(){ }

}

最佳答案

对 JFrame 进行子类化并不是一个好主意。相反,扩展 JPanel,并在其 PaintCpomponent() 方法中绘制您的内容。尝试这样的事情(不完整的代码):

public class GamePanel extends JPanel {

public GamePanel() {
// Create panel content here
}

@Override
public void paintComponent( Graphics g ) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0,0, width, height);
}

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

@Override
public void run() {
JFrame frame = new JFrame();
// create the component to display in the frame
JPanel panel = new GamePanel();
;
frame.add(panel, BorderLayout.CENTER);

frame.pack();
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
});
}

});
}
}

关于java - 在进行任何绘图之前调用 setVisible 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60020128/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com