gpt4 book ai didi

java - 更改变量时重绘不起作用

转载 作者:行者123 更新时间:2023-12-02 09:34:54 26 4
gpt4 key购买 nike

我对使用 java 进行开发非常陌生,但我有一些一般的编码经验。我知道想用我创建的函数绘制“图片/分形”。我完成了所有代码,我想通过添加到函数 XOFF 来自动移动“分形”,(我有一个计时器)现在我希望变量自动增加,以便它在图片中滚动。我尝试使用重绘和重新验证,但它不起作用:(

我知道我写了 MandelBrotSet,尽管它与它没有任何关系 ^^

package Pack1;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.Timer;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Main extends JComponent implements ActionListener {
public static void main(String[] args) {
new Main();
}

public static final int WIDTH = 1000;
public static final int HEIGHT = 800;
public int XOFF = 0;
public int YOFF = 0;

private BufferedImage buffer;
private Timer timer;

public Main(){

buffer = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
timer = new Timer(10, this);
renderMandelBrotSet();

JFrame frame = new JFrame("Mandelbrot Set");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.getContentPane().add(this);
frame.pack();
frame.setVisible(true);
}

@Override
public void addNotify() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
timer.start();
}

public void renderMandelBrotSet() {
System.out.println(XOFF);
int vx = 0;
int vy = 0;
int zoom = 1;

for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++) {
vx = ((x - WIDTH/2));
vy = ((y - HEIGHT/2));
vx = vx + XOFF;
vy = vy + 0;
int color = (int) (Math.abs(vx)/Math.sqrt(Math.abs(vy))*(vx/zoom)); //calculatePoint((x - WIDTH/2), (y - HEIGHT/2) );

buffer.setRGB(x, y, color);
}
}


@Override
public void paint(Graphics g) {
g.drawImage(buffer, 0, 0, null);
}

@Override
public void actionPerformed(ActionEvent e) {
XOFF++;
renderMandelBrotSet();
revalidate();
repaint();
}
}

我希望代码有意义...,如果我忘记提及任何内容,我很抱歉。如果您需要什么,请随时问我。

最佳答案

我认为 addNotify 是你的问题。该方法已经做了一些事情,并且您覆盖它的方式似乎没有执行其文档所说的任何操作。只需摆脱它,并将其代码移到其他地方即可。

这似乎对我有用。我还将计时器的速度减慢至 100 毫秒,因为根据经验我知道 Java Swing 的更新速度并不那么快。 100 毫秒到 250 毫秒是更新 Swing 的良好范围。

我还摆脱了revalidate,因为这只适用于添加或删除组件或更改大小时。您只需要重新绘制,因为您的图像大小不会改变。

(Hovercraft 指出代码确实应该重写 paintComponent,而不是 paint。他说得非常正确;教程中对此进行了解释:https://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html)

(当我修复问题时,我不妨指出 Swing is not thread safe, 和 GUI 创建(包括图像和计时器)确实需要在 GUI 线程上完成。)

package quicktest;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;

/**
*
* @author Brenden
*/
public class MandelbrotSet {

}


class Main extends JComponent implements ActionListener {

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

public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public int XOFF = 0;
public int YOFF = 0;

private BufferedImage buffer;
private Timer timer;


public Main(){
SwingUtilities.invokeLater( this::createGui );
}

private void createGui() {
buffer = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
timer = new Timer(100, this);
setPreferredSize( new Dimension( WIDTH, HEIGHT ) );
renderMandelBrotSet();

JFrame frame = new JFrame("Mandelbrot Set");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.getContentPane().add(this);
frame.pack();
frame.setVisible(true);
timer.start();
}

// @Override
// public void addNotify() {
// setPreferredSize(new Dimension(WIDTH, HEIGHT));
// timer.start();
// }

public void renderMandelBrotSet() {
System.out.println(XOFF);
int vx = 0;
int vy = 0;
int zoom = 1;

for(int x = 0; x < WIDTH; x++)
for(int y = 0; y < HEIGHT; y++) {
vx = ((x - WIDTH/2));
vy = ((y - HEIGHT/2));
vx = vx + XOFF;
vy = vy + 0;
int color = (int) (Math.abs(vx)/Math.sqrt(Math.abs(vy))*(vx/zoom)); //calculatePoint((x - WIDTH/2), (y - HEIGHT/2) );

buffer.setRGB(x, y, color);
}
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent( g );
System.err.println( "Repainting..." );
g.drawImage(buffer, 0, 0, null);
}

@Override
public void actionPerformed(ActionEvent e) {
System.err.println( "Timer: XOFF=" + XOFF );
XOFF++;
renderMandelBrotSet();
// revalidate();
repaint();
}

}

关于java - 更改变量时重绘不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57613705/

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