我对使用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();
}
}
我希望代码有意义...,如果我忘记提任何事情,我感到抱歉。随时问我是否需要什么。
答案 0 :(得分:1)
我认为addNotify
是您的问题。该方法已经可以执行某些操作,而您覆盖它的方式似乎并没有执行其文档说明应执行的任何操作。只需摆脱它,然后将其代码移至其他位置即可。
这似乎对我有用。我也将您的计时器降低到100毫秒,因为我从经验中知道Java Swing确实没有那么快的更新能力。 100 ms至250 ms是更新Swing的合适范围。
我还摆脱了revalidate
,因为这仅适用于添加或删除组件或更改大小的情况。您只需要重新绘画,因为图像不会改变大小。
(气垫船指出,代码确实应该覆盖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();
}
}