gpt4 book ai didi

Java:repaint() 不在 for 循环中调用paintComponent()

转载 作者:行者123 更新时间:2023-12-04 05:17:50 25 4
gpt4 key购买 nike

这是我在 stackoverflow 上的第一篇文章,我希望有人能帮助我解决我在这里遇到的问题。

我正在处理的问题是 repaint()问题,有些人会认为我只是没有在这些论坛上进行足够的搜索来解决我的问题,但我已经进行了广泛的调查,但没有任何效果。在下面的代码中,我尝试在 for 循环中调用 drawB,无论数组有多大,这段代码都能正常运行。 for 循环调用 drawB 大约 20 次。在 drawB 中,我希望设置一个图像(它会因数组中的数字而异)然后调用 repaint()然后调用 paintComponent()在子类 GameCanvas 中。

问题是paintComponant 根本没有在这个初始化中运行。然而repaint()确实在我制作的循环中运行 gameLoop() ,但我需要在 gameLoop() 之前进行初始化.

任何人都知道发生了什么,或者如何解决它?

package engine;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class GameMain extends JFrame // main class for the game as a Swing application
{

// Define constants for the game
static final int CANVAS_WIDTH = 800; // width and height of the game screen
static final int CANVAS_HEIGHT = 600;
static final int UPDATE_RATE = 4; // number of game update per second
static final long UPDATE_PERIOD = 1000000000L / UPDATE_RATE; // nanoseconds

String path;
BufferedImage image;

private GameCanvas canvas;

// Constructor to initialize the UI components and game objects
public GameMain()
{
gameInit();

image = null;
canvas = new GameCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
this.setContentPane(canvas);


this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setTitle("Blockcraft!");
this.setVisible(true);
}

public void gameInit()
{
dispArray();
gameStart();
}

public void dispArray()
{
int tempLevel[][] = new int[][] {{1,1,1,1},{6,2,2,2},{3,3,3,3},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4},{4,4,4,4}};
int widthTemp = tempLevel[0].length;
int heightTemp = tempLevel.length;

for(int i = 0; i < heightTemp; i++)
{
for(int j = 0; j < widthTemp; j++)
{
try
{
image = ImageIO.read(getFile());
}
catch (Exception e)
{
e.printStackTrace();
}
drawB(image);
}
}
}

public File getFile()
{
path = "images//1.jpg";
File file = new File(path);
return file;
}

public void drawB(BufferedImage imgTemp)
{
image = imgTemp;
repaint();
}

private void gameLoop()
{
long beginTime, timeTaken, timeLeft;
while (true)
{
repaint();

beginTime = System.nanoTime();

timeTaken = System.nanoTime() - beginTime;
timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000L; // in milliseconds
if (timeLeft < 10) timeLeft = 10; // set a minimum
try
{
Thread.sleep(timeLeft);
}
catch (InterruptedException ex)
{
//
}
}
}

// Refresh the display. Called back via repaint(), which invoke the paintComponent().
private void gameDraw(Graphics2D g2d)
{
g2d.drawImage(image, 0, 0, 15, 15, this);
}

public void gameKeyPressed(int keyCode)
{
//
}

public void gameKeyReleased(int keyCode)
{
//
}

public void gameKeyTyped(char keyChar)
{
//
}

class GameCanvas extends JPanel implements KeyListener
{
boolean paintAll;
int xPos, yPos;
Image img;

public GameCanvas()
{
setFocusable(true);
requestFocus();
addKeyListener(this);
}

// Override paintComponent to do custom drawing.
// Called back by repaint()... sometimes?
@Override
public void paintComponent(Graphics g)
{
System.out.println("repainting");
Graphics2D g2d = (Graphics2D)g;

// Draw the game objects
gameDraw(g2d);
}


// KeyEvent handlers
@Override
public void keyPressed(KeyEvent e)
{
gameKeyPressed(e.getKeyCode());
}

@Override
public void keyReleased(KeyEvent e)
{
gameKeyReleased(e.getKeyCode());
}

@Override
public void keyTyped(KeyEvent e)
{
gameKeyTyped(e.getKeyChar());
}
}

// To start and re-start the game.
public void gameStart()
{
// Create a new thread
Thread gameThread = new Thread()
{
// Override run() to provide the running behavior of this thread.
@Override
public void run()
{
gameLoop();
}
};
// Start the thread. start() calls run(), which in turn calls gameLoop().
gameThread.start();
}

// main
public static void main(String[] args)
{
// Use the event dispatch thread to build the UI for thread-safety.
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new GameMain();
}
});
}
}

最佳答案

由于初始化代码,在初始化期间没有响应是有道理的:

public void dispArray() {
int tempLevel[][] = new int[][] { { 1, 1, 1, 1 }, { 6, 2, 2, 2 },
{ 3, 3, 3, 3 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 },
{ 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 } };
int widthTemp = tempLevel[0].length;
int heightTemp = tempLevel.length;
for (int i = 0; i < heightTemp; i++) {
for (int j = 0; j < widthTemp; j++) {
try {
image = ImageIO.read(getFile());
} catch (Exception e) {
e.printStackTrace();
}
drawB(image);
}
}
}

public File getFile() {
path = "images//1.jpg";
File file = new File(path);
return file;
}

public void drawB(BufferedImage imgTemp) {
image = imgTemp;
repaint();
}

包括读入图像文件,都是在 Swing 事件线程上完成的,这是您永远不应该做的。

解决方案:不要这样做。而是为此使用后台线程,例如 SwingWorker 可用的线程。有关更多信息,请阅读 Concurrency in Swing .

关于Java:repaint() 不在 for 循环中调用paintComponent(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14027945/

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