JDialog repaint() funktioniert nicht wie gewünscht.

Joew0815

Bekanntes Mitglied
Guten Abend,

ich würde gerne einen Punkt innerhalb eines JDialog (später innerhalb eines JPanel) bewegen.

Der Punkt soll sich jedoch nur alle 20ms weiterbewegen.

Ich habe versucht Thread.sleep() in einem Thread zu starten, was nicht funktioniert hat. Dann habe ich dasselbe mit dem JDialog versucht, mit dem gleichen Ergebniss.Dann versuchte ich es mit dem Timer....was auch nicht funktionierte.

Ohne repaint() funktioniert es wunderbar, jedoch werden die Punkte dann nur übereinander gemalt.

Java:
import java.awt.event.ActionEvent;
import javax.swing.JDialog;
import javax.swing.Timer;

class gui {
    int y;
    JDialog d = new JDialog();

    gui() {
        d.setSize(100, 100);
        d.setVisible(true);
    }

    void updater() {
        if (y == 100) {y = 0;}
        else {y++;}
        //d.repaint();
        d.getGraphics().fillOval(y, 50, 25, 25);
    }
}

public class test2 {
    public static void main(String[] args) {
        gui gu = new gui();
        new Timer(20, (ActionEvent e) -> {gu.updater();}).start();
    }

}
 
Wenn ich ein JPanel hinzufüge funktioniert es, aber ich finde es etwas unschön, dass der ganze JDialog jedes mal neu gezeichnet wird.

Java:
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.Timer;

class gui {

    int y;
    JDialog d;
    JPanel p;

    gui() {
        d = new JDialog();
        p = new JPanel() {
            public void paint(Graphics g) {
                g.fillOval(y, 50, 25, 25);
            }
        };
        d.setSize(200, 200);
        d.add(p);
        d.setVisible(true);

    }

    void updater() {
        if (y == 200) {
            y = 0;
        } else {
            y++;
        }
        d.repaint();
        p.repaint();
    }
}

public class test2 {

    public static void main(String[] args) {
        gui gu = new gui();
        new Timer(20, (ActionEvent e) -> {
            gu.updater();
        }).start();
    }

}
 
Zuletzt bearbeitet:
Hallo also im Punkto Animationen gibt es einige zu beachten.
Zeichne deine Animation auf einen eigene Compoent z.b. ein JLabel dies kannst du dann bequem über label.repaint(); neu zeichnen lassen. Und ich würde empfehlen einen Swing Timer zu nutzen da musst du nicht irgendwelche Threads schlafen legen sondern hast einen schönen überblick.

Ich habe dir hier mal eine kleine Animation gemacht ein Punkt der über einen JDialog fährt so wie gefragt. (Der JDialog beendet nicht das Programm du musst es danach noch Separate wieder beenden.)
Java:
package PunktimJDialog;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.Timer;

public class Punkt extends JDialog implements ActionListener{

	private Timer timer=new Timer(20,this);
	private Point point=new Point(100,100);
	private Point vec=new Point(1,1);
	private JLabel label;
	
	public static void main(String[] args) {
		Punkt dialog = new Punkt();
	}

	public Punkt() {
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setSize( 300, 300);
		setLocationRelativeTo(null);
		getContentPane().setLayout(new BorderLayout());
		
		label = new JLabel(){
			@Override
			protected void paintComponent(Graphics g) {
				g.fillOval(point.x-2, point.y-2, 5, 5);
			}
		};
		getContentPane().add(label, BorderLayout.CENTER);
		setVisible(true);
		timer.start();
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		System.out.println(point.x+"/"+point.y);
		if(point.x>=200)
			vec.x=-1;
		else if(point.x<=100)
			vec.x=1;
		if(point.y>=200)
			vec.y=-1;
		else if(point.y<=100)
			vec.y=1;
		
		point.x+=vec.x;
		point.y+=vec.y;
		label.repaint();
	}

}
 

Zurück
Oben