# Brauche Hilfe bei Simulation einer Flugkurve .



## Kussefar (23. Apr 2006)

Hi,

muss für morgen^^ ein Prog schreiben, was den Schiefen Wurf in echtzeicht simuliert.....
Hab damit so noch nix gemacht also irgendwas zu simulieren....
Hab mir erstmal gedacht machste erstma dass es immer neu gezeichnet wird auf kopfdruck...so dass klappt auch schonmal nciht warum...frag mich nicht....

hier mla der Quelltext :

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
  *
  * <Beschreibung>
  *
  * @version 1.0 vom 23.04.2006
  * @author  Das ist die Vorlage
  */

public class schiefer_wurf_simulation extends JFrame {
  // Anfang Variablen
  
  double y = 0;
  double vy = 0;
  double x = 0;
  double vx = 0;
  double v0 = 5;
  double t = 0;
  double dt = 0.01;
  

  
  private JSlider Winkel = new JSlider();
  private JSlider Geschw = new JSlider();
  private JButton jButton1 = new JButton();
  private JPanel jPanel1 = new JPanel(null)
   {
     public void paint(Graphics g)
     {
      g.drawLine(0,0,0,getHeight());
      g.drawString("y",5,5);
      g.drawLine(0,getHeight()-1,getWidth(),getHeight()-1);
      g.drawString("x",getWidth()-5,getHeight()-5);

      //berechnen


      vy = b * Math.sin(a*Math.PI/180);
      vx = b * Math.cos(a*Math.PI/180);

      while ( y >= 0)
       {
         g.setColor(Color.red);

         y = y + vy + dt;
         vy = vy - 9.81*dt;
         x = x + vx + dt;

         g.fillOval((int)x,getHeight()-(int)y,2,2);

       }
     }
   };
   
   int a = 45;
   int b = 5;
  // Ende Variablen

  public schiefer_wurf_simulation (String title) {
    // Frame-Initialisierung
    super (title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) { System.exit(0); }
    });
    int frameWidth = 300;
    int frameHeight = 300;
    setSize(frameWidth, frameHeight);
    Container cp = getContentPane();
    cp.setLayout(null);
    // Anfang Komponenten

    jPanel1.setBounds(32, 24, 225, 169);
    jPanel1.setBackground(Color.YELLOW);
    cp.add(jPanel1);
    Winkel.setBounds(32, 216, 81, 17);
    Winkel.setValue(5);
    Winkel.setOrientation(Scrollbar.HORIZONTAL);
    Winkel.setMaximum(10);
    cp.add(Winkel);
    Geschw.setBounds(144, 216, 89, 17);
    Geschw.setValue(45);
    Geschw.setOrientation(Scrollbar.HORIZONTAL);
    Geschw.setMaximum(90);
    cp.add(Geschw);
    jButton1.setBounds(96, 256, 81, 17);
    jButton1.setText("zeichnen");
    cp.add(jButton1);
    jButton1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        jButton1ActionPerformed(evt);
      }
    });

    // Ende Komponenten

    setResizable(false);
    setVisible(true);
  }

  // Anfang Ereignisprozeduren
  public void jButton1ActionPerformed(ActionEvent evt) {

    
    a = Winkel.getValue();
    b = Geschw.getValue();
    
    jPanel1.repaint();

  }

  // Ende Ereignisprozeduren

  public static void main(String[] args) {
    new schiefer_wurf_simulation("schiefer_wurf_simulation");
  }
}
```

 hoffe mir kann jemand helfen...

 mfg


----------



## Illuvatar (23. Apr 2006)

Kussefar hat gesagt.:
			
		

> klappt auch schonmal nciht



Juhu, meine Kristallkugel kriegt mal wieder Arbeit  :?  :roll:


----------



## Kussefar (23. Apr 2006)

super antwort ....   :!:  :?:  :!:


----------



## Illuvatar (23. Apr 2006)

Was ich damit sagen wollte:


			
				Vor dem ersten Posten bitte lesen! hat gesagt.:
			
		

> 7.) Es hilft uns nichts wenn du sagst du hast eine Exception oder sonstigen Fehler, du aber weder den Fehler postest, noch Code (wir können nicht hellsehen).
> 
> 8.) Informationen über deinen Compiler, IDE und Betriebssystem sind auch hilfreich (bei UnsatisfiedLinkError überhaupt).


----------



## Kussefar (23. Apr 2006)

?? Hab doch den Quellcode gepostet !?!
Und den Fehler finde ich ja selbst nicht...lässt sich alles compilieren aber
muss halt irgendwas im Prog flasch sein dass er es halt nicht nue zeichnet...

was is daran falsch bitte?


----------



## Leroy42 (24. Apr 2006)

Kussefar hat gesagt.:
			
		

> Und _den Fehler_ finde ich ja selbst nicht...



Davon reden wir doch die ganze Zeit  :shock: Was ist denn der Fehler?

Du sagst das Programm kompiliert und läuft (hab's nicht selbst geprüft, aber glaube dir),
sagst aber nicht was _es falsch macht_

Was mir auffällt, ist, daß du die gesamte Bewegung auf einmal zeichnest, keinerlei
Pausen (geschweige dann Echtzeitpausen) einlegst und nur einmal repaint aufrufst.
 :shock:  :shock:  :shock: 
Also erklär erst mal was nun falsch ist.


----------



## Kussefar (3. Mai 2006)

ok, also die idee von mir war einfach dass ich den winkel und die anfangsgeschwindigkeit mit den beiden slidern vorher einstellen kann und dann auf den button drücke und er mir die neue Kurve zeichnet.

Das macht das prog halt leider nicht und ich finde nicht warum es nicht geht.


----------



## Leroy42 (3. Mai 2006)

1. Du überschreibst paint statt paintComponent
2. Als erste Anweisung von paintComponent muß stehen super.repaintComponent(g);

Damit ist zum einen der gelbe Hintergrund zu sehen. Zum zweiten verwurschtelt die Ausgabe nicht mehr.

3. Du setzt x und y nicht bei jedem Durchlauf deiner Zeichenroutine vorher auf 0 zurück
4. Du vertauschst die Bedeutung von a und b (Geschwindigkeit und Winkel). Mit einer vernünftigen
    Namenswahl (z.B.: v und w) wär das nicht passiert.

Desweiteren noch ein paar Hinweise:

- Warum machst du dir die Mühe, die Größe und Position aller Komponenten selbst zu setzen
   anstatt Layoutmanager zu benutzen?
- Woher weiß man, welcher Slider was verändert?
- Es wäre hilfreich die aktuellen Werte (Geschwindigkeit, Winkel) irgendwo anzuzeigen
- Da die Variablen x, y, vx und vy nur innerhalb der Zeichenroutine gebraucht werden,
   sollten sie auch dahin verlagert werden. _dt_ kann eine Instanzvariable bleiben, da
   diese ja die Zeichenroutine steuert.
- Klassennamen sollten groß geschrieben werden


----------



## Kussefar (3. Mai 2006)

na das ist doch mal ne gute Antowrt ...  

Erstmal danke und mal schaun was ich mit den Tips anfangen kann ....

Was für ein LayoutManager würde sich denn eignen? Kenn mich da nicht so aus...

achso und was meinst du mit paintComponent?


----------



## Leroy42 (3. Mai 2006)

Du mußt paintComponent statt paint überschreiben

```
public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawLine(0,0,0,getHeight());
      ...
```

Das BorderLayout. Da es default ist mußt du es nicht extra setzen.
Im CENTER-Bereich kommt dein Zeichenpanel.
Im NORTH-(oder, je nach Geschmack,  SOUTH)-Bereich deine Steuerelemente,
die widerum in ein FlowLayout gepackt werden. Also


```
JPanel north = new JPanel();
north.add(Winkel);
north.add(Geschwindigkeit);
north.add(jButton1);

cp.add(north, BorderLayout.NORTH);
cp.add(jPanel1, BorderLayout.CENTER);
```
und *kein* Aufruf von cp.setLayout(null) mehr.

Dann kannst du auch das setVisible(false) weglassen und den User 
damit nicht mehr ärgern. :wink: 

Übrigens: Warum benutzt du so aussage_un_kräftige Bezeichnungen
wie jPanel1 und jButton1? Nenne sie doch so, daß man ihnen gleich
ansieht, was sie darstellen.


----------



## Kussefar (3. Mai 2006)

das mit den scheiss bezeichnungen stimmt schon ... liegt aber daran, dass es ja nur so ein "Test-Prog" war und ich es mit nem Editor gemacht hat vo ich die sachen nur noch "reinsetzen" muss (wie den JSlider) und der Editor dann denn Quellcode direkt selbst schriebt deswgeen jButton1 und so ...
Wenn ich das selbst geschrieben hätte, würde ich andere Namen nehmen  :wink: 

Was ist denn das paintComponent ? Hab das noch nie gehört, bin ja auch noch ein "kleiner" Anfänger 

 

Ps.: Ich weiss dass es scheisse ist wenn der Editor den Code selbst schreibt (is ja auch langweilig und kein richtiges Proggn mehr :wink: )


----------



## Leroy42 (3. Mai 2006)

Der Ablauf des Zeichnens unter Swing ist folgendermaßen.

Du (oder das System) ruft repaint() auf. Dadurch weiß der *E*vent*D*ispatch*T*hread
daß die Komponente, sobald der EDT wieder _dran_ ist eine Neuzeichnung veranlaßt.

Dazu ruft der EDT erst die Methode update auf. Diese sorgt z.B. dafür, daß von dir
gesetzte Hintergrundfarben gezeichnet werden (Dein Gelb).

Dann wird die Methode paint() vom EDT aufgerufen. Diese zeichnet die eigentliche Komponente
und Sachen wie z.B. Rahmen.

Dann erfolgt der Aufruf von paintComponent(Graphics g) und in
Swing sollte *nur* diese überschrieben werden, nicht paint wie im AWT


----------



## Kussefar (3. Mai 2006)

alles klaro.

also ich muss jetzt so ein "Projekt" machen , was je nach asuwahl einen schiefen wurf , planetenbewegungen oder den freien Fall simulieren soll.

Kannst du mir da vllt nen Tipp geben wie ich das Graphisch gut darstellen kann...
... hab mir das so gedacht mit nem JTree oder JMenu oder nem popup wo ich dann halt auswählen kann was er simulieren soll 

mfg maddin


----------



## Kussefar (7. Mai 2006)

also das hat jetzt recht gut gefuntzt ...

aber jetzt nochma ne Frage ... Wie bekomm ich den "schiefen wurf" in ein panel rein, welches ich dann durch das BorderLayout in die mitte setzen will...?

hier der code:

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
  *
  * <Beschreibung>
  *
  * @version 1.0 vom 07.05.2006
  * @author  Das ist die Vorlage
  */

public class Schiefer_Wurf extends JFrame {
  // Anfang Variablen
  Graphics g;
  double v=3;
  int w=1;
  double vy = v * Math.sin(w*Math.PI/180);
  double vx = v * Math.cos(w*Math.PI/180);
  
  private JButton knopf = new JButton();
  private JSlider winkel = new JSlider();
  private JSlider geschw = new JSlider();
  JPanel north = new JPanel();
  JPanel zeichen_panel = new JPanel();

  // Ende Variablen

  public Schiefer_Wurf (String title) {
    // Frame-Initialisierung
    super (title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) { System.exit(0); }
    });
    int frameWidth = 800;
    int frameHeight = 800;
    setSize(frameWidth, frameHeight);
    Container cp = getContentPane();
    //cp.setLayout(null);

    // Anfang Komponenten
    g=getGraphics();


    knopf.setText("zeichnen");
    winkel.setMaximum(90);
    geschw.setMaximum(5);
    geschw.setValue(3);
    north.add(knopf);
    north.add(winkel);
    north.add(geschw);
    cp.add(north,BorderLayout.NORTH);
    cp.add(zeichen_panel,BorderLayout.CENTER);
    knopf.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        knopfActionPerformed(evt);
      }
    });

    // Ende Komponenten

    setResizable(false);
    setVisible(true);
  }

  // Anfang Ereignisprozeduren
  public void knopfActionPerformed(ActionEvent evt) {
        w = winkel.getValue();
        v = geschw.getValue();
        vy = v * Math.sin(w*Math.PI/180);
        vx = v * Math.cos(w*Math.PI/180);
        Kugel a = new Kugel(getGraphics(),vx,-vy);
        a.start();



  }

  // Ende Ereignisprozeduren

  public static void main(String[] args) {
    new Schiefer_Wurf("Schiefer_Wurf");
  }
}

class Kugel extends Thread {
    Graphics stift;
    int d;
    double vx, vy;
    public Kugel(Graphics g, double vx, double vy) {
        stift = g;
        d = 10;
        this.vx = vx;
        this.vy = vy;
    }
    void zeitschleife() {
        try { Thread.sleep(10); }
        catch(InterruptedException e) { return; }
    }
    public void run() {
        double x=10; double y=379;
        while (y<380){
            stift.setColor(Color.LIGHT_GRAY);
            stift.fillOval((int)x, (int)y, d, d);
            y=y+vy;
            vy=vy+0.02;
            x=x+vx;
            stift.setColor(Color.BLACK);
            stift.fillOval((int)x, (int)y, d, d);
            zeitschleife();
        }
    }
}
```


----------



## Leroy42 (8. Mai 2006)

Ich habe den Code nur überflogen...

Aber du hast doch bereits ein JPanel north. Bau dir einen JPanel center und 
übergib _dessen_ getGraphics() deinem Kugel-Thread.


----------

