Licgbrechnugsprogramm

T

Torreto

Gast
Hallo,

ich muss ein Lichbrechungsberechnungs Programm realisieren. Hier im Link einmal das Bild wie das aussehen soll:
ImageShack® - Online Photo and Video Hosting

Hier is der Quellcode den ich bisher habe:

Java:
import java.awt.*;
import java.awt.event.*;


public class LWLB extends Frame implements ItemListener, AdjustmentListener
{
  // Attribute
  Label l1      = new Label("Brechungsindex   n1=");
  Label l2      = new Label("Brechungsindex   n2=");
  Label l3      = new Label("Einfallswinkel in Grad");
  Label l4      = new Label("Brechungswinkel in Grad");
  Label l5      = new Label("1.0");
  Label l6      = new Label("Vakuum");
  TextField tf1 = new TextField("", 5);
  TextField tf2 = new TextField("", 5);
  TextField tf3 = new TextField("", 5);
  Choice c1     = new Choice();
  Scrollbar s1  = new Scrollbar(Scrollbar.HORIZONTAL, 45, 10, 0, 100);


    
  public static void main (String args[])
  {
      LWLB mywindow = new LWLB();
    } 
  
    public LWLB()
    { 
      setSize(500,550);
      setVisible(true);
      setTitle("BrechungsDarstellung");
      //Schließfunktion
      addWindowListener(new WindowAdapter()
      {
           public void windowClosing(WindowEvent event)
           {
                System.exit(0);
             }
      });
      //Layout-Manager
        setLayout(null);
      //Bounden der Oberflächen-Elemente
        l1.setBounds  (20, 50,  150, 20);
        l2.setBounds  (20, 80,  150, 20);
        l3.setBounds  (20, 110, 150, 20);
        l4.setBounds  (20, 140, 150, 20);
        l5.setBounds  (200, 50, 50,  20);
        l6.setBounds  (270, 50, 100, 20);
        tf1.setBounds (200, 80, 50,  20);
        tf2.setBounds (200, 110, 50, 20);
        tf3.setBounds (200, 140, 50, 20);
        c1.setBounds  (270, 80, 100, 20);
        s1.setBounds (270, 110, 150, 20);
        
        
        c1.add("Vakuum");
        c1.add("Wasser");
        c1.add("Quarzglas");
        c1.add("Diamant");
        
      //Hinzufügen zum Frame
        add(l1);
        add(l2);
        add(l3);
        add(l4);
        add(l5);
        add(l6);
        add(tf1);
        add(tf2);
        add(tf3);
        add(c1);
        add(s1);
    
    }
  
    public void paint (Graphics g)
  {
     g.drawRect(10,200,400,140);   //Rechteck oben
     g.setColor(Color.lightGray);
     g.fillRect(10,340,400,140);   //Rechteck unten füllen
     g.setColor(Color.black);
     g.drawRect(10,340,400,140);   //Rechteck unten
     
  }
  
  // Methode für Scrollbar
  public void adjustmentValueChanged(AdjustmentEvent e)
  {
  
  }
  // Methode für Choice
  public void itemStateChanged(ItemEvent e)
  {


  
  }
}

Nun weiss ich nicht wie ich wenn ich beim Choice etwas auswähle ein bestimmter wert im obersten Textfeld ist... wenn ich die scrollbar bewege das da ein wert zwischen 0 und 90 erscheint und dabei unten der graph sich zeichnet....
 

Gravian

Mitglied
Du kannst eine Endlosschleife in die Main-Methode einbauen, die prüft ob sich was ändert.
Für die Wasser könnte das so aussehen:

Java:
while (true){
       if (mywindow.c1.getSelectedItem() == "Wasser"){
        mywindow.l5.setText("1.33");
}

Statt dem while(true) könntest du natürlich irgendeine sinnvolle Abbruchbedingung einfügen.

Für die Scrollbar wird das ganz ähnlich sein. Du musst in der Main-Methode die Position der Scrollbar abfragen und dann das Label dementsprechend ändern.

In der Main-Methode kannst du auch die Routine einbauen, die deine Grafik zeichnet.
 
Zuletzt bearbeitet:

diggaa1984

Top Contributor
ich empfehle da eher etwas mit listener .. wenn sich die Auswahl aendert wird ein .. lass mich lügen "...SelectionListener" wach, der dich darüber informiert das was passiert ist, innerhalb dieses Listeners kannst du dann entsprechend reagieren und Teile deiner Oberfläche umgestalten, sprich Texte setzen oder dergleichen.

was die scrollbar angeht .. ich vemute diese hat min und max-werte welche sie besitzen kann und ein stepping, was einstellbar ist .. was du dann brauchst ist, bei änderung der scrollbar einfach den aktuellen wert auslesen und in das entsprechende feld eintragen.
 

antrox

Mitglied
so wie hier

Java:
        Objekt.addChangeListener(new ChangeListener(){
 
            @Override
            public void stateChanged(ChangeEvent e) {
                System.out.println("Klick");
                System.out.println();
            }
            
        });
 
T

Torreto

Gast
hab es mit der Choice mittlerweile hinbekommen über ein ItemListener...

nur jezz komme ich bei der Scrollbar nicht weiter... soll das mit einem AdjustmentListener machen aber weiss nicht wie ich den status abfragen soll...
 
T

Torreto

Gast
solle es so klappen wenn ich es in die methode des AdjustmentListener einfüge?
...
tf2.setValue(s1.getValue());
...
 

Gravian

Mitglied
Muss noch in nen String umgewandelt werden:

Java:
tf2.setText(String.valueOf(s1.getValue()));

alternativ auch

Java:
tf2.setText(""+s1.getValue());
 
T

Torreto

Gast
vielen dank hat geklappt :D

so nun habe ich, damit wenn ich die choice ändere sich unter der text zu der jewahligen auswahl ändert, dies hier geschrieben...

g.drawString("Medium: "+c1.getItem(c1.getSelectedIndex()),20,360);

der ItemListener wurde zu c1 geaddet... wenn ich das programm starte kommt alles nur wenn ich die choice ändere beibt der string wie er war...
 
T

Torreto

Gast
Java:
import java.awt.*;
import java.awt.event.*;


public class LWLB extends Frame implements ItemListener, AdjustmentListener
{
  // Attribute
  Label l1      = new Label("Brechungsindex     n1 =");
  Label l2      = new Label("Brechungsindex     n2 =");
  Label l3      = new Label("Einfallswinkel  in Grad");
  Label l4      = new Label("Brechungswinkel in Grad");
  Label l5      = new Label("1.0");
  Label l6      = new Label("Vakuum");
  Label l7      = new Label("Medium: Vakuum");
  Label l8      = new Label("Lot");
  TextField tf1 = new TextField("1.00", 5);
  TextField tf2 = new TextField("45", 5);
  TextField tf3 = new TextField("", 5);
  Choice c1     = new Choice();
  Scrollbar s1  = new Scrollbar(Scrollbar.HORIZONTAL, 45, 10, 0, 100);


    
  public static void main (String args[])
  {
      LWLB mywindow = new LWLB();
    } 
  
    public LWLB()
    { 
      setSize(500,550);
      setVisible(true);
      setTitle("BrechungsDarstellung");
      setFont(new Font("Courier", Font.BOLD, 14));
      //Schließfunktion
      addWindowListener(new WindowAdapter()
      {
           public void windowClosing(WindowEvent event)
           {
                System.exit(0);
             }
      });
      //Layout-Manager
        setLayout(null);
      //Bounden der Oberflächen-Elemente
        l1.setBounds  ( 20, 50,190, 20);
        l2.setBounds  ( 20, 80,190, 20);
        l3.setBounds  ( 20,110,190, 20);
        l4.setBounds  ( 20,140,190, 20);
        l5.setBounds  (230, 50, 50, 20);
        l6.setBounds  (300, 50,100, 20);
        l7.setBounds  ( 12,205,115, 20);
        l8.setBounds  (180,205, 25, 20);
        tf1.setBounds (230, 80, 50, 20);
        tf2.setBounds (230,110, 50, 20);
        tf3.setBounds (230,140, 50, 20);
        c1.setBounds  (300, 80,100, 20);
        s1.setBounds  (300,110,150, 20);

        
        
        c1.add("Vakuum");
        c1.add("Wasser");
        c1.add("Quarzglas");
        c1.add("Diamant");
        
      //Hinzufügen zum Frame
        add(l1);
        add(l2);
        add(l3);
        add(l4);
        add(l5);
        add(l6);
        add(l7);
        add(l8);
        add(tf1);
        add(tf2);
        add(tf3);
        add(c1);
        add(s1);
        c1.addItemListener(this);
        s1.addAdjustmentListener(this);
    }
  
    public void paint (Graphics g)
  {
     g.drawRect(10,200,400,140);   //Rechteck oben
     g.setColor(Color.lightGray);
     g.fillRect(10,340,400,140);   //Rechteck unten füllen
     g.setColor(Color.black);
     g.drawRect(10,340,400,140);   //Rechteck unten
     g.drawLine(210,210,210,470);  //Horizontale Linie
     //Label das sich mit der Choice ändert
     g.drawString("Medium: "+c1.getItem(c1.getSelectedIndex()),20,360);
  }
  
  // Methode für Scrollbar
  public void adjustmentValueChanged(AdjustmentEvent e)
  {
       tf2.setText(""+s1.getValue());
  }
  // Methode für Choice
  public void itemStateChanged(ItemEvent e)
  {

      if (c1.getSelectedItem()=="Vakuum")
      {
         tf1.setText("1.00");
      }
      if (c1.getSelectedItem()=="Wasser")
      {
         tf1.setText("1.33");
      }
      if (c1.getSelectedItem()=="Quarzglas")
      {
         tf1.setText("1.46");
      }
      if (c1.getSelectedItem()=="Diamant")
      {
         tf1.setText("2.42");
      }
  }
}
 
T

Torreto

Gast
richtig das geht ja aber in der grafik im grauen bereich steht: Medium: Vakuum
und dieses Vakuum sollte sich dementsprechend zu Wasser oder Quarzglas ändern wenn ich das choice ändere
 

Gravian

Mitglied
Das liegt dadran, das die paint() Methode nur einmal aufgerufen wird.
Theoretisch kann man das jetzt wieder fixen indem man folgendes in der Main-Methode macht:

Java:
while(true){
       mywindow.paint(mywindow.getGraphics());
      }

Das geht aber bestimmt auch wieder mit irgendwelchen Listenern oder so vielleicht eleganter, besonders weil du dich jetzt hier um einen Doublebuffer kümmern musst.

Ich würde aber vorschlagen, du nimmst einfach ein Label (l9 z.B.) für den Text und machst dann folgendes:

Java:
  public void itemStateChanged(ItemEvent e)
  {

      if (c1.getSelectedItem()=="Vakuum")
      {
         tf1.setText("1.00");
         l9.setText("Medium: Vakuum");
      }
      if (c1.getSelectedItem()=="Wasser")
      {
         tf1.setText("1.33");
         l9.setText("Medium: Vakuum");
      }
      if (c1.getSelectedItem()=="Quarzglas")
      {
         tf1.setText("1.46");
         l9.setText("Medium: Quarzglas");
      }
      if (c1.getSelectedItem()=="Diamant")
      {
         tf1.setText("2.42");
         l9.setText("Medium: Diamant");
      }
  }
 

XHelp

Top Contributor
@Gravian, ein klaren: NEIN
- Strings werden mit equals vergliechen
-
Code:
while(true)
ergibt kein Sinn
- wenn, dann schon
Code:
repaint
 

Gravian

Mitglied
Ja du hast Recht, repaint sollte man statt paint nehmen und Strings per equals vegleichen.
Anstatt while(true) sollte man natürlich eine entsprechende Abbruchbedingung nehmen aber das hatte ich ja weiter oben schon gesagt.
 
T

Torreto

Gast
hat auch geklappt...

so letzte frage: wie mache ich textfelder so das man sie nicht verändern kann...
und den gesamten frame beim aufmachen des programms auf die koordinaten 100,100 und das ich den gesamten frame nicht mit der maus unten rechts durch ziehen vergrößern kann?
 

kirax

Bekanntes Mitglied
Das ganze if-Geraffel ließe sich viel schöner über eigene Mediumsklassen lösen:

Java:
public interface Medium {
  public String getName();
  public double getBrechIndex();
}

public class Vakuum implements Medium {
  @Override
  public String getName() {
    return "Vakuum";
  }
  @Override
  public double getBrechIndex() {
    return 1.0;
  }
}

// usw.

Und dann halt keine Choice sondern z.B. ne JComboBox. Da kann man die Dinger schön einfügen.
 
T

Torreto

Gast
kann sowas nicht benutzer ist mit if vorgegeben...

wie mache ich textfelder so das man sie nicht verändern kann...
und den gesamten frame beim aufmachen des programms auf die koordinaten 100,100 und das ich den gesamten frame nicht mit der maus unten rechts durch ziehen vergrößern kann?
 
T

Torreto

Gast
setLocation und setResizable geht nun auch...

wie mach ich das aber das ich die TextFelder nicht verändert werden können?
 
T

Torreto

Gast
ach vielen dank... habt mir sehr geholfen!

jezz ist das einzige nur noch das ich diese daten zeichnen muss...
fals das noch einer erzklären kann super wenn nicht kein ding...
hier nocheinmal der aktuelle quellcode...

Java:
import java.awt.*;
import java.awt.event.*;


public class LWLB extends Frame implements ItemListener, AdjustmentListener
{
  // Attribute
  Label l1      = new Label("Brechungsindex     n1 =");
  Label l2      = new Label("Brechungsindex     n2 =");
  Label l3      = new Label("Einfallswinkel  in Grad");
  Label l4      = new Label("Brechungswinkel in Grad");
  Label l5      = new Label("1.0");
  Label l6      = new Label("Vakuum");
  Label l7      = new Label("Medium: Vakuum");
  Label l8      = new Label("Lot");
  TextField tf1 = new TextField("1.00", 5);
  TextField tf2 = new TextField("45", 5);
  TextField tf3 = new TextField("", 5);
  Choice c1     = new Choice();
  Scrollbar s1  = new Scrollbar(Scrollbar.HORIZONTAL, 45, 10, 0, 100);
  
  double ew=45.0, bw, bi1=1.0, bi2=1.0;

  public static void main (String args[])
  {
      LWLB mywindow = new LWLB();
    } 
  
    public LWLB()
    {
      setSize(500,550);
      setVisible(true);
      setTitle("BrechungsDarstellung");
      setFont(new Font("Courier", Font.BOLD, 14));
      setLocation(100,100);
      setResizable(false);
      tf1.setEditable(false);
      tf2.setEditable(false);
      tf3.setEditable(false);
      
      //Schließfunktion
      addWindowListener(new WindowAdapter()
      {
           public void windowClosing(WindowEvent event)
           {
                System.exit(0);
             }
      });
      
      //Layout-Manager
        setLayout(null);
        
      //Bounden der Oberflächen-Elemente
        l1.setBounds  ( 20, 50,190, 20);
        l2.setBounds  ( 20, 80,190, 20);
        l3.setBounds  ( 20,110,190, 20);
        l4.setBounds  ( 20,140,190, 20);
        l5.setBounds  (230, 50, 50, 20);
        l6.setBounds  (300, 50,100, 20);
        l7.setBounds  ( 12,205,115, 20);
        l8.setBounds  (180,205, 25, 20);
        tf1.setBounds (230, 80, 50, 20);
        tf2.setBounds (230,110, 50, 20);
        tf3.setBounds (230,140, 50, 20);
        c1.setBounds  (300, 80,100, 20);
        s1.setBounds  (300,110,150, 20);

        
        
        c1.add("Vakuum");
        c1.add("Wasser");
        c1.add("Quarzglas");
        c1.add("Diamant");
        
      //Hinzufügen zum Frame
        add(l1);
        add(l2);
        add(l3);
        add(l4);
        add(l5);
        add(l6);
        add(l7);
        add(l8);
        add(tf1);
        add(tf2);
        add(tf3);
        add(c1);
        add(s1);
        c1.addItemListener(this);
        s1.addAdjustmentListener(this);
    }

    public void paint (Graphics g)
  {
     g.drawRect(10,200,400,140);   //Rechteck oben
     g.setColor(Color.lightGray);
     g.fillRect(10,340,400,140);   //Rechteck unten füllen
     g.setColor(Color.black);
     g.drawRect(10,340,400,140);   //Rechteck unten
     g.drawLine(210,210,210,470);  //Horizontale Linie
     
     //Label das sich mit der Choice ändert
     g.drawString("Medium: "+c1.getItem(c1.getSelectedIndex()),20,360);
     
     tf3.setText(String.valueOf(bw));

     //Berechnung
     double w = Math.toRadians(ew);
     bw = Math.asin((bi1/bi2)*Math.sin(w));
     bw = (double)((int)(Math.toDegrees(bw)*100+0.5))/100.;


  }
  
  // Methode für Scrollbar
  public void adjustmentValueChanged(AdjustmentEvent e)
  {
       ew = (double)s1.getValue();
       tf2.setText(""+s1.getValue());
       repaint();
  }
  // Methode für Choice
  public void itemStateChanged(ItemEvent e)
  {

      if (c1.getSelectedItem()=="Vakuum")
      {
         tf1.setText("1.00");
         bi2=1.00;
      }
      if (c1.getSelectedItem()=="Wasser")
      {
         tf1.setText("1.33");
         bi2=1.33;
      }
      if (c1.getSelectedItem()=="Quarzglas")
      {
         tf1.setText("1.46");
         bi2=1.46;
      }
      if (c1.getSelectedItem()=="Diamant")
      {
         tf1.setText("2.42");
         bi2=2.42;
      }
      repaint();
  }
}
 

Gravian

Mitglied
Naja du kannst ja vom Koordinatenursprung ne Gerade mit g.drawLine() in der paint() Methode zeichnen.
Der Winkel ist ja durch Benutzereingabe gegeben, sodass du nen zweiten Punkt für die Gerade berechnen kannst.

Für die "abgelenkte Gerade" musst du dann noch nen dritten Punkt mit dem Brechungswinkel berechnen, der dann auch mit dem Koordinatenursprung verbunden wird.
 

kirax

Bekanntes Mitglied
er verwendet kein swing :)
Ja sehe auch grad. Wobei sich die Frage nach dem Warum stellt :D
Dann müsste man es halt über ne separate Liste lösen.

Aber warum reg ich mich überhaupt auf. Es fruchtet ja eh nicht ;(

Ersetze mal deine itemStateChanged in folgende:
Java:
public void itemStateChanged(ItemEvent e)
  {
 
      if (c1.getSelectedItem().equals("Vakuum"))
      {
         tf1.setText("1.00");
         bi2=1.00;
      }
      if (c1.getSelectedItem().equals("Wasser"))
      {
         tf1.setText("1.33");
         bi2=1.33;
      }
      if (c1.getSelectedItem().equals("Quarzglas"))
      {
         tf1.setText("1.46");
         bi2=1.46;
      }
      if (c1.getSelectedItem().equals("Diamant"))
      {
         tf1.setText("2.42");
         bi2=2.42;
      }
      repaint();
  }
 

Gravian

Mitglied
Ich hab jetzt mal aus Spaß die paint() Methode fertig geschrieben:

Java:
public void paint (Graphics g)
  {

     tf3.setText(String.valueOf(bw));

     //Berechnung (an den Anfang, da Werte beim Zeichnen gebraucht werden)
     double w = Math.toRadians(ew);
     bw = Math.asin((bi1/bi2)*Math.sin(w));
     bw = (double)((int)(Math.toDegrees(bw)*100+0.5))/100.;

     g.drawRect(10,200,400,140);   //Rechteck oben
     g.setColor(Color.lightGray);
     g.fillRect(10,340,400,140);   //Rechteck unten füllen
     g.setColor(Color.black);
     g.drawRect(10,340,400,140);   //Rechteck unten
     g.drawLine(210,210,210,470);  //Horizontale Linie

     //Meine Ergänzung
     double alpha = Math.toRadians(Integer.parseInt(tf2.getText()));
     double beta = Math.toRadians(Double.parseDouble(tf3.getText()));
     
     if (Math.toDegrees(alpha) <= 34){
      g.drawLine(210,340,10,(int)(340-Math.tan(alpha)*200));
     }else{
      g.drawLine(210,340,(int)(210-(140/Math.tan(alpha))),200);
     }

     if (Math.toDegrees(beta) <= 34){
       g.drawLine(210,340,410,(int)(340+Math.tan(beta)*200));
      }else{
       g.drawLine(210,340,(int)(210+(140/Math.tan(beta))),480);
      }
     //Label das sich mit der Choice ändert
     g.drawString("Medium: "+c1.getItem(c1.getSelectedIndex()),20,360);

  }

Viel Spaß damit ^^

edit: Kleinen Bug noch beseitigt
 
Zuletzt bearbeitet:

muckelzwerg

Bekanntes Mitglied
[ot]Soll jetzt kein Angriff sein, aber irgendwie ist dieses Forum hier seltsam. Wenn man Fragen zu "langweiligen" Themen hat, kommen die Standardantworten oder der Spruch "Mach Deine Hausaufgaben selbst, damit Du was lernst.".
Aber kaum geht es um ein bisschen Grafik oder eine nicht ganz gängige Darstellung, schon muss irgendwer sich selbst und der virtuellen Welt beweisen, dass er es kann?
Ist wirklich nicht böse gemeint, irritiert mich nur.[/ot]
 

Gravian

Mitglied
Ich fand die Aufgabenstellung hier interessant und da ich selber in Java noch nicht so fit bin habe ich das jetzt als schöne Übung gesehen, wo ist das Problem, wenn ich dem Fragesteller dann meine Lösung gebe, damit er was hat, falls er nicht weiterkommt?

Wenn er das einfach kopiert und so abgibt ist es sein eigener Schaden. Moralaposteln gibt ist in der Welt schon genug. Und das hier irgendjemand was beweisen möchte kann ich auch nicht nachvollziehen, immerhin "laufen" hier sicherlich zahllose Java Experten rum die über die hier diskutierten Probleme allerhöchstens schmunzeln können.
 

Neue Themen


Oben