- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个有趣的游戏,其中包括一个轮子,一个球。每次用户单击按钮时,球都会滚动并随机落在轮子的一个槽上。一切正常,为了创建轮子,我将图像和球(椭圆形对象)放在单独的 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/
我是 Java 的新手。下面是两个类,一个类扩展JComponent,需要重写paintComponent方法。另一个类扩展了JPanel,同样需要重写paintComponent方法。 为什么Dra
我想知道 paintcomponent() 和 paintcomponents() 有什么不同? 当我从 paintcomponent 使用它时,它显示了我们想要的一切,但是 paintcompone
public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Gr
我稍后在我的主方法中使用这样的调用: public static void main(String[] args) { SwingUtilities.invokeLater(new Runna
所以我正在开发一款由两个网格组成的游戏。每个网格都是一个 JPanel,我在其中(可能)在网格中的每个空间上绘制一个对象。我发现绘制对象正在减慢应用程序的速度,我想知道是否有办法防止这种情况发生。 详
这个问题已经有答案了: paintComponent is not being called in JPanel (1 个回答) 已关闭 4 年前。 很抱歉,这个问题可能已经解决了,但我已经到处搜索但
我的问题非常简单:我有这个小程序,它只是没有显示我正在尝试制作的红框: 主要 public class Main { public static void main(String[] args
我正在尝试编写一个类似这样的应用程序: - 显示对话框 - 当用户单击“确定”时,关闭对话框,转到主应用程序 以下是相关代码片段: public class Owari extends JPanel
这应该是一个抽象类,可以扩展以绘制连接 JPanel 上某些坐标点的线。 但是,永远不会调用专门的 PaintComponents() 方法。我已经看到其他答案并尝试使用他们的解决方案,例如检查我是否
我有以下结构: method1 method2 ... methodn methodX 方法x包含: JFrame frame = new JFrame("Sample"); frame.setDef
我在使用矩形时遇到一些问题 这是我的代码: import java.awt.*; import javax.swing.*; import java.util.*; public class squa
我正在尝试制作西洋跳棋游戏,但以下架构没有在 JFrame 上显示我做错了什么 //基类 import java.awt.event.MouseEvent; import java.awt.event
问题涉及我项目中的 2 个类:主类和绘图类。主类创建 JFrame 并在其中放置 2 个 JPanel。第一个 JPanel 包含用于输入数字的 JTextFields 和用于选择不同选项的 JBut
我已经处理学校作业有一段时间了。但我无法真正理解我应该做什么。作业明天就要交了,我感觉压力很大。 任务是,我将获取一些图片,将它们放在窗口中,然后能够在它们周围移动并能够旋转。 最大的问题是我不知道如
我在使用 PaintComponent 绘制形状时遇到不清楚的问题。 public class Shape extends JPanel { private String shape; private
据我了解,Swing 将决定何时需要重新绘制,这可以解释为什么 paintComponent() 执行两次。但我制作了一个 hibernate 16 毫秒、重绘、 hibernate 16 毫秒、重绘
这是我的代码,它工作完美,并在 JFrame 中绘制形状。每个方法都通过其名称进行调用,在我的程序中我没有调用任何 paintComponent() 方法。那么paintComponent()方法的调
我正在尝试在 JPanel 上绘制一些内容,但似乎我遇到了 paint 和 paintComponent 方法的问题。可能与双缓冲有关,但我不确定。 public void PaintComponen
我是 Swing 新手,正在尝试将图像背景添加到我的 JFrame 中。但是我的 paintComponent 方法不起作用。您能否就如何修复我的代码以便在背景中绘制图像提供一些建议? 代码如下: /
我正在尝试编写简单的程序,当鼠标拖动时绘制圆圈,但paintComponent方法仅被调用一次(启动后)。 在这个类中,我有一些在拖动鼠标时绘制圆圈的方法。 import javax.swing.*;
我是一名优秀的程序员,十分优秀!