[swing] jak uzyc obiektow Graphics w timerze

0

Mam cos takiego:

	public void rysuj( final Graphics g){
		........
                        tu rozne operacje rysowania na g dzialaja
                        ........
		timerobroty = new Timer();
		timerobroty.schedule(new TimerTask(){
		 public void run(){
		        g.fillOval(640, 170, 10, 10);
		        System.out.println("beep");
		  migaj = false;
		    }
		        },0, 1000);
		.....
	}

a obiekt g bierze sie z tad :

private void paint(){
		BufferStrategy bf = this.getBufferStrategy();
		Graphics g = null;
		
		try {
			g = bf.getDrawGraphics();
			v.rysuj(g);
		} finally {
			g.dispose();
		}
		
		bf.show();
	    Toolkit.getDefaultToolkit().sync();	
	}

Funkcja paint wykonuje sie 30 razy na sekunde jezeli to istotne.
Sam timer dziala, czyli wypisuje "beep" na konsole co 1 sekunde ale nie rysuje. Eclipse nie zglasza bledow ale chcial zeby g bylo finalne, wiec jest. Czemu nie chce rysowac tego kolka ?

0

Nie tak. To że coś narysujesz w Graphics to nie oznacza, ze się pokaże. Musisz jeszcze wywołać repaint().

0

nie musze uzywac repaint() i tez nie mam go jak za bardzo uzyc, nie chodzi o to ze ogolnie nie rysuje, bo rysuje i pokazuje. funkcja paint wykonuje sie 30 razy na sekunde i za kazdym razem od nowa rysuje. Chodzi o to ze w srodku timera to nie chodzi. W funcji rysuje(final Graphics g) tam gdzie sa .......... rysuje kreski i tekst ktory sie zmienia w zaleznosci od przycinkanych klawiszy:

	g.setColor(Color.red);
g.drawString("M "+Integer.toString((int)bieg), 410, 133);
double x2 = 647 + 110*Math.cos(Math.PI*stopnie/180);
double y2 = 195 + 110*Math.sin(Math.PI*stopnie/180);
g.drawLine(647, 195, (int)x2, (int)y2);

i to dziala, nastepnie jest timer i w nim rysowanie nie dziala.

0

Najpierw najważniejsze jest określenie czy zamierzasz robić grafikę w Swingu czy SWT?
Bo od tego zależy jak się to robi.
Co do Twojego Timera, to umieściłeś go w takim miejscu, że co odrysowanie, to tworzysz kolejnego nowego Timera z poleceniem rysowania figury co 33 milisekundy (za każdym razem z innego wątku - czyli AWT musi sama synchronizować te wywołania). To nie ma prawa działać.

Natomiast, jak ma działać, to zależy czy chcesz pracować w Swingu czy SWT lub ewentualnie robić grafikę w trybie pełnoekranowym. W każdym przypadku robi się to inaczej.

0
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

class Zdarzenie implements ActionListener{
	public Zdarzenie(Panel p){
		_p = p;
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		_p.repaint();
	}
	private Panel _p;
}

class Panel extends JPanel{
	public Panel(){
		super();
		int delay = 100;
	
		timer = new javax.swing.Timer(delay, new Zdarzenie(this));
		timer.start();
	}
	public void paint(Graphics g){
		Graphics2D g2 = (Graphics2D)g;
		if(kolor){
			g2.setColor(Color.BLUE);
			kolor = false;
		}else{
			g2.setColor(Color.RED);
			kolor = true;
		}			
		g2.fillRect(10, 10, 20, 20);
	}
	private javax.swing.Timer timer;
	private boolean kolor = false;
}

class Ramka extends JFrame{
	public Ramka(){
		super();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 300);
		getContentPane().add(new Panel());
		setVisible(true);
	}
}

public class Timer {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Ramka r = new Ramka();
	}

}

No następny kod w ramach treningu. Rysuje wypełniony kwadrat i zmienia jego kolor co 100ms. Poczytaj, zrozumiesz. W razie pytań pisz.

0

aha i klasa Zdarzenie możę być jako klasa anonimowa (czy jak to się dokładnie nazywa) czyli definicja klasy wewnątrz klasy Panel. Wtedy klasa wewnętrzna ma pełny dostęp do składowych klasy nadrzędnej. Ale tak jak jest to myślę że jest bardziej czytelnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1