Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo liebe Forenmitglieder!
Ich habe folgendes Problem: Ich möchte eine simple Ballengine schreiben, jedoch hapert es gerade am "Zeichnen" des Balles.
Der Ball wird nicht auf das JFrame gezeichnet und wenn, dann blitzt es nur kurz auf und verschwindet sofort wieder. Ich habe dies in einem Tutorial gesehen, habe den Quellcode 1 zu 1 kopiert, jedoch klappt es bei mir einfach nicht wie bei ihm im Video! Ich habe ein wenig recherchiert und habe herausgefunden, dass die GUI blockiert werden könnte, wenn man den "main-Thread" mittels sleep() pausiert.
Hoffe auf schnelle Hilfe, danke im Voraus! :bahnhof:
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
public class BouncingBall extends JFrame implements Runnable {
private float x,y;
private float velocityY, velocityX;
private float radius;
public BouncingBall(String title) {
super(title);
//Variablen
x = 400;
y = 150;
radius = 20;
velocityY = 5.0f;
}
public void paint(Graphics gr) {
super.paintComponents(gr);
//Ball
gr.setColor(Color.red);
gr.fillOval( (int) x, (int) y, (int) radius*2, (int) radius*2);
}
@Override
public void run() {
while(true) {
try {
//Code
//Ball Movement
y *= velocityY;
repaint();
//Code
Thread.sleep(20);
} catch (InterruptedException ex) {
System.out.println("Error: " + ex);
}
}
}
public static void main(String[] args) {
BouncingBall main = new BouncingBall("Physik-Ball");
new Thread(main).start();
main.setSize(800, 800);
main.setVisible(true);
}
}
Ja ich habe dies auch zum ersten mal ausprobiert. Zumindest es so zu kopieren
Ich habe nun folgendes probiert: Ich habe jeweils den Ball, das Fenster und den Thread in eigene Klassen gepackt. Dies wiederum in ein Package. Jedoch weiß ich nicht, wie ich den Ball nun auf mein Fenster bekomme.
Quellcode Fenster:
Java:
package Engine;
import javax.swing.JFrame;
public class Fenster extends JFrame {
public Fenster(String title) {
super(title);
}
public static void main(String[] args) {
Fenster main = new Fenster("Physik-Ball");
main.setSize(800, 800);
main.setVisible(true);
}
}
Quellcode Ball:
Java:
package Engine;
import java.awt.Color;
import java.awt.Graphics;
public class Ball extends Fenster {
private float x,y;
private float velocityY, velocityX;
private float radius;
public Ball(String title) {
super(title);
//Variablen
x = 400;
y = 150;
radius = 20;
}
public void paint(Graphics gr) {
super.paintComponents(gr);
//Ball
gr.setColor(Color.red);
gr.fillOval( (int) x, (int) y, (int) radius*2, (int) radius*2);
}
}
Ich habe ehrlich gesagt auch nicht verstanden, was Gucky mit seinem etwas kryptischen Hinweis sagen wollte.
Nu aber zu deinem Code:
Um in Java selbst etwas zu zeichnen, packt man seine Zeichenlogik normalerweise in die paintComponent() einer selbst geschriebenen JComponent, nicht in einen JFrame. Ausserdem rufst du in deiner überschriebenen paint-methode super.paintComponents auf. Keine Ahnung, was das soll. Weiterhin gibt es elegantere Methoden, etwas zu animieren, als Threads schlafen zu legen, nämlich Timer. Schliesslich sind die Parameter deiner Animationsmethode nicht sehr sinnvoll: der Ausdruck
Code:
y *= velocityY;
ist bereits nach dem ersten Durchgang, also noch bevor der Thread zum ersten mal schlafen gelegt wird, 750, und die y-Koordinate liegt ausserhalb des Zeichenbereiches.
Hier mal ein funktionierendes Beispiel:
Java:
public class BouncingBall extends JComponent implements ActionListener {
private float x, y;
private float velocityY, velocityX;
private float radius;
public BouncingBall(String title) {
JFrame frame = new JFrame(title);
super.setPreferredSize(new Dimension(500, 500));
frame.setContentPane(this);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x = 400;
y = 5;
radius = 20;
velocityY = 1.5f;
Timer timer = new Timer(100, this);
timer.start();
//Variablen
}
public void paintComponent(Graphics gr) {
super.paintComponent(gr);
//Ball
gr.setColor(Color.red);
gr.fillOval((int) x, (int) y, (int) radius * 2, (int) radius * 2);
}
public void actionPerformed(ActionEvent ae) {
y *= velocityY;
repaint();
}
public static void main(String[] args) {
BouncingBall main = new BouncingBall("Physik-Ball");
}
}
Ich habe das Ganze einfach mal per Copy and Paste in Eclipse gepackt und bekomme sehr sehr viele Fehlermeldungen am rechten Rand. Ich kann zwar compilieren, jedoch sagt er mir dass es extrem viele Fehler gäbe.
Dort steht immer:
<objectname> cannot be resolved to a variable/type
Ich meinte damit, dass der Ball sich selbst zeichnet, indem er das Graphics Objekt vom JFrame übergeben bekommt.
Also das sich das GUI nicht um den Ball kümmert sondern nur den Raum zum Zeichnen zur Verfügung stellt. Den Rest besorgen Thread und Ball.
Sorry, wenn das zu kryptisch war.
Die ganzen Fehler sind darauf zurückzuführen, dass du sämtliche Importe nicht im Code hast. Eigentlich müssten unter der Fehlermeldung Importvorschläge stehen.
Ich meinte damit, dass der Ball sich selbst zeichnet, indem er das Graphics Objekt vom JFrame übergeben bekommt.
Also das sich das GUI nicht um den Ball kümmert sondern nur den Raum zum Zeichnen zur Verfügung stellt. Den Rest besorgen Thread und Ball.
Bei mehreren Bällen oder noch allgemeiner: Objekten, die man rumspringen/sich bewegen lassen möchte, ist es natürlich besser, wenn jedes Objekt seine Koordinaten, Geschwindigkeit und Beschleuningung selbst speichert.
Ich sehe aber nicht, daß das bei einem so simplen Beispiel sinnvoll ist, noch kann ich erkennen, inwiefern dieser Ansatz die Probleme des TE hätte lösen können.
Er wäre nicht mehr Gefahr gelaufen den GUI Thread lahmzulegen und da er eine "Ballengine" schreiben möchte, liegt der Schluss nahe, dass noch mehr Bälle hinzukommen. Aber ist jetzt ja auch egal.