View Single Post
Old 09-02-2010, 16:10   #5
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Una soluzione è quella che ti ho già proposto. Posso farti un esempio:

Codice:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.LinkedList;
import java.util.Random;

public class Main {

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				new Main().execute();
			}
		});
	}
	
	private void execute() {
		final int WIDTH = 500;
		final int HEIGHT = 500;
		final long DURATIONMS = 10000;
		final int RESOLUTIONMS = 25;
		final PCanvas CANVAS = new PCanvas();
		final Parametric PARAMETRIC = new Sinusoid(CANVAS, WIDTH, HEIGHT);
		final Generator GENERATOR = new Generator(PARAMETRIC, DURATIONMS, RESOLUTIONMS);
		final JFrame WINDOW = new JFrame("Test");
		final JButton START = new JButton(new AbstractAction("Start") {
			public void actionPerformed(ActionEvent e) {
				GENERATOR.start();
			}
		});
		
		CANVAS.getComponent().setPreferredSize(new Dimension(WIDTH, HEIGHT));
		CANVAS.getComponent().setBackground(Color.WHITE);
		WINDOW.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		WINDOW.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				GENERATOR.stop();
			}
		});
		WINDOW.add(CANVAS.getComponent());
		WINDOW.add(START, BorderLayout.SOUTH);
		WINDOW.pack();
		WINDOW.setVisible(true);
	}
}

class Sinusoid implements Parametric {
	private final Random RANDOM = new Random(0);
	private final PCanvas CANVAS;
	private final int WIDTH;
	private final int HEIGHT;
	
	public Sinusoid(PCanvas canvas, int width, int height) {
		CANVAS = canvas;
		WIDTH = width;
		HEIGHT = height;
	}

	public void apply(Double t) {
		final double Y = HEIGHT / 2 * Math.sin(t * 2 * Math.PI) + HEIGHT / 2;
		final double X = WIDTH * t; //(0 ~ WIDTH)
		final double RAY = 5;
		final Color FILL = new Color(RANDOM.nextInt(255), RANDOM.nextInt(255), RANDOM.nextInt(255));
		final Bubble BUBBLE = new Bubble(X, Y, RAY, FILL);
		CANVAS.push(BUBBLE);
	}	
}

class Generator {
	private final TimeLine TIMELINE = new TimeLine();
	private final Parametric FUNCTION;
	private final javax.swing.Timer TIMER;
	private final long DURATION;
	
	public Generator(Parametric fun, long durationMs, int resolutionMs) {
		FUNCTION = fun;
		DURATION = durationMs;
		TIMER = new javax.swing.Timer(resolutionMs, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				applyParametric();
			}
		});
	}
	
	private void applyParametric() {
		double t = (double)TIMELINE.get() / (double) DURATION;
		TIMELINE.update();
		if(t >= 1) {
			t = 1;
			FUNCTION.apply(t);
			stop();
		} else {
			FUNCTION.apply(t);
		}
	}
	
	public void start() {
		TIMELINE.start();
		TIMER.restart();
	}
	
	public void stop() {
		TIMER.stop();
	}
}

class TimeLine {
	private final long MILLION = 1000000;
	private long then;
	private long time;
	
	public void start() {
		then = System.nanoTime();
		time = 0;
	}
	
	public void update() {
		long now = System.nanoTime();
		long dTimeNanos = now - then;
		then = now;
		time += dTimeNanos / MILLION;
	}
	
	public long get() {
		return time;
	}
}

interface Parametric {
	
	public void apply(Double t);
}

interface Paintable {
	
	void paint(Graphics g);
}

class PCanvas {
	private final LinkedList<Paintable> PAINTABLES = new LinkedList<Paintable>();
	
	private final JPanel PANEL = new JPanel() {
		@Override
		protected void paintComponent(Graphics graphics) {
			super.paintComponent(graphics);
			for(Paintable p : PAINTABLES) {
				p.paint(graphics);
			}
		}
	};
	
	public void push(Paintable p) {
		PAINTABLES.push(p);
		PANEL.repaint();
	}
	
	public void clear() {
		PAINTABLES.clear();
		PANEL.repaint();
	}
	
	public Component getComponent() {
		return PANEL;
	}
}

class Bubble implements Paintable {
	private final Color FILL;
	private final Shape SHAPE;
	
	public Bubble(double x, double y, double ray, Color fill) {
		FILL = fill;
		SHAPE = new Ellipse2D.Double(x - ray, y - ray, 2 * ray, 2 * ray);
	}
	
	public void paint(Graphics g) {
		Graphics2D graphics = (Graphics2D) g;
		graphics.setPaint(FILL);
		graphics.fill(SHAPE);
	}
}
Comunque il problema del tuo codice è che esprime un'idea di disegno che presuppone un Graphics "stateful" mentre Graphics è "stateless". Detto altrimenti lo stato di Graphics viene azzerato tra due invocazioni di repaint successive. Così se disegni una bolla in 10, 10 e la volta seguente disegni una bolla in 20, 20 a video appare una sola bolla, in 20,20. Se vuoi farle apparire tutte e due la prima volta disegni la bolla (10,10), la seconda volta disegni la bolla (10,10) e la bolla (20,20).
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso