gpt4 book ai didi

java - 使用paintComponent()和高CPU使用率

转载 作者:行者123 更新时间:2023-12-02 01:28:39 24 4
gpt4 key购买 nike

我正在尝试创建一个有趣的游戏,其中包括一个轮子,一个球。每次用户单击按钮时,球都会滚动并随机落在轮子的一个槽上。一切正常,为了创建轮子,我将图像和球(椭圆形对象)放在单独的 JPanel 上。 。功能行为正如我所期望的那样好。但每次运行程序时,CPU 声音很大,Java 应用程序的使用率常常高达 25%。

这太可怕了。经过一段时间的测试,似乎错误出现在我的 painComponent() 内部。重写方法,因为 Java 不间断地重复调用此方法。更全面的调查表明问题在于方法getScaledInstance用于缩放面板内的图像。在我看来,如果我删除此方法,paintComponent()不会被重复调用。

但是,事情是我不知道如何在没有 getScaledInstance 的情况下缩放图像。请注意,我尝试根据 MadProgrammer Java: maintaining aspect ratio of JPanel background image 的示例制作副本

那么,你对此有何看法?有什么办法可以设置背景图片,保持宽高比而不过度调用paintComponent()方法?请注意,我确实尝试使用 Thread.sleep但效果不太好。

这对我来说是相当困难的。不管怎样,感谢您的阅读!

public class WheelPanel2 extends JPanel {

private BufferedImage image;
private int time = 0;
private Image scaled = null;
private int scaleWidth = 300;
private int scaleHeight = 300;

public WheelPanel2() {
try {
image = ImageIO.read(new File("img/Basic_roulette_wheel_1024x1024.png"));
scaled = image.getScaledInstance(scaleWidth, scaleHeight, Image.SCALE_SMOOTH);

} catch (IOException e) {
e.printStackTrace();
}
setSize(400, 400);
setPreferredSize(new Dimension(400, 400));
setBorder(BorderFactory.createLineBorder(Color.BLACK));


double scaleFactor = Math.min(1d, getScaleFactorToFit(new Dimension(image.getWidth(), image.getHeight()), getSize()));
int scaleWidth = (int) Math.round(image.getWidth() * scaleFactor);
int scaleHeight = (int) Math.round(image.getHeight() * scaleFactor);
Image scaled = image.getScaledInstance(scaleWidth, scaleHeight, Image.SCALE_SMOOTH);

}

/**
* The Paint Method - Create the image of the Wheel and the Ball
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
double scaleFactor = Math.min(1d, getScaleFactorToFit(new Dimension(image.getWidth(), image.getHeight()), getSize()));

//TRUE WIDTH AND HEIGHT
int scaleWidth = (int) Math.round(image.getWidth() * scaleFactor);
int scaleHeight = (int) Math.round(image.getHeight() * scaleFactor);
scaled = image.getScaledInstance(scaleWidth, scaleHeight, Image.SCALE_SMOOTH);
int width = getWidth() - 1;
int height = getHeight() - 1;
int x = (width - scaled.getWidth(this)) / 2;
int y = (height - scaled.getHeight(this)) / 2;

g.drawImage(scaled, x, y, this);
System.out.println("PAINT");

}



/**
* These two methods are used to automatically resize the wheelpanel and the ball
*/
private double getScaleFactorToFit(Dimension original, Dimension toFit) {

double dScale = 1d;

if (original != null && toFit != null) {

double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);

dScale = Math.min(dScaleHeight, dScaleWidth);

}

return dScale;
}

private double getScaleFactor(int iMasterSize, int iTargetSize) {

double dScale;
if (iMasterSize > iTargetSize) {

dScale = (double) iTargetSize / (double) iMasterSize;

} else {

dScale = (double) iTargetSize / (double) iMasterSize;

}

return dScale;

}
public static void main (String[] args) {
JFrame frame = new JFrame("HI THERE");
frame.setSize(1000, 1000);
frame.setLayout(new BorderLayout());
frame.add(new WheelPanel2(), BorderLayout.CENTER);
frame.setVisible(true);
frame.setDefaultCloseOperation(1);

}
}

如果你尝试运行该程序,你会知道paintComponent被不停地调用。

最佳答案

与其自己缩放图像,不如让 Graphics 来完成,通过调用 drawImage method which takes width and height arguments :

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

int width = image.getWidth(this);
int height = image.getHeight(this);
float scale = Math.min(
(float) getWidth() / width,
(float) getHeight() / height);

width = (int) (width * scale);
height = (int) (height * scale);

int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;

g.drawImage(image, x, y, width, height, this);
}

在大多数平台上,这将利用系统的图形加速来缩放图像。

如果您想确定使用 SCALE_SMOOTH 的等效项来缩放图像,set the appropriate RenderingHint :

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

((Graphics2D) g).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);

int width = image.getWidth(this);
int height = image.getHeight(this);
float scale = Math.min(
(float) getWidth() / width,
(float) getHeight() / height);

width = (int) (width * scale);
height = (int) (height * scale);

int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;

g.drawImage(image, x, y, width, height, this);
}

关于java - 使用paintComponent()和高CPU使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56459419/

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