Я пытаюсь создать забавную игру, в которую входит Колесо, мяч. Каждый раз, когда пользователь нажимает на кнопку, шар катится и случайным образом приземляется на один слот в колесе. Все в порядке, чтобы создать Колесо, я помещаю изображение и шар (Овальный объект) на отдельном JPanel
. Функциональное поведение хорошо, как я ожидаю. Однако каждый раз, когда я запускаю программу, процессор звучит громко, и использование Java-приложения часто занимает до 25%.
Это довольно ужасно. Через некоторое время, выполняя некоторые тесты, кажется, что ошибка находится внутри моих painComponent()
переопределенных методов, поскольку Java неоднократно вызывает этот метод без остановки. Более подробное исследование показывает, что проблема заключается в методе getScaledInstance
, который используется для масштабирования изображения внутри панели. Мне кажется, что если я удалю этот метод, paintComponent()
не будет вызываться повторно.
Однако, я не знаю, как сделать масштабированное изображение без getScaledInstance
. Обратите внимание, что я попытался сделать копию на основе образца MadProgrammer Java: поддержание соотношения сторон фонового изображения JPanel
Итак, что вы думаете об этом? Есть ли способ установить фоновое изображение, сохранить соотношение сторон и не вызывать метод 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 вызывается без остановок.