# update()-Methode für Canvas



## new michi (6. Jul 2005)

Ich habe einen Funktions-Plotter geschrieben.
Damit die canvas-Komponente nicht neu-gezeichnet wird sondern nur ergänzt (die alten Funktionen also eingezeichnet bleiben) habe ich sie mit:


```
public void update(Graphics g)
     {
          paint(g);
      }
```

ergänzt. Wie kann ich es jetzt so machen, dass die Canvas-Komponente nur ergänzt wird, wenn die boolean-Variable b1 "true" ist?


----------



## L-ectron-X (6. Jul 2005)

new michi hat gesagt.:
			
		

> wenn die boolean-Variable b1 "true" ist?


Na wenn die Bedingung erfüllt ist. :wink: 
Einfach in die entsprechende Methode eine Abfrage mit if-Anweisung einbauen.
Wenn die Bedingung erfüllt wird, neu zeichnen, wenn nicht überspringen oder return.


----------



## new michi (21. Jul 2005)

Tja...
So schlau waer ich auch, allerdings wird bei return die Canvas nicht neu gezeichnet!


----------



## mic_checker (21. Jul 2005)

du hast es so gemacht wie von L-ectron-X beschrieben und es klappt nicht - obwohl du haargenau danach fragst ?


----------



## new michi (21. Jul 2005)

Ja!?!


----------



## new michi (31. Aug 2005)

Hallo!?
Kommt hier irgent wann noch mal was,
denn das Problem besteht weiterhin....
Danke


----------



## Beni (31. Aug 2005)

Also ich finde diesen Ansatz sehr gefährlich. Das Bild auf der Canvas kann jederzeit gelöscht werden (da reicht es, wenn ein anderes Fenster mal über dein Canvas fliegt).

Ich würde ein Image (z.B. BufferedImage) nehmen, und in das Image die Funktion(en) zeichnen. Das Image wird garantiert nie gelöscht, du kannst also immer mehr einzeichnen. Das Image selbst kannst du dann immer wieder in "paint" auf die Canvas zeichnen.


----------



## new michi (31. Aug 2005)

Klingt schlau, ich versteh aber nix, bin noch kein Profi wie ihr...           ???:L
Kanst du das genauer erklähren???


Hier einmahl der Code:

```
// Datei CFunkPlotter2.java

// Ein Funktionenplotter
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

// Hauptfenster von Swing-Klasse JFrame ableiten
public class CFunkPlotter2 extends JFrame
{
int aktFunktion = 0;    // diese Variable bestimmt die 
                        // zu zeichnende Funktion;
                        // Startwert 0 = keine Funktion
CMeineCanvas m_malflaeche;
JTextField t1;
JTextField t2;
JTextField t3;
JTextField t4;
JTextField t5;
JCheckBox cb1;

   public static CFunkPlotter2 Fenster =  new CFunkPlotter2("Funktionenplotter");

public static void main(String[] args)
   {
   Fenster.pack();
   Fenster.setSize(485,585);
   Fenster.setResizable(true);
   Fenster.show();
   }

// Im Konstruktor werden die Canvas-Malfläche und 
// Schalter zur Auswahl der Funktionen angelegt
CFunkPlotter2(String titel)
   {
   super(titel);

   // Einen Layout Manager einrichten
   getContentPane().setLayout(new FlowLayout());

   // Die Malfläche aufnehmen
   m_malflaeche = new CMeineCanvas();
   getContentPane().add(m_malflaeche);
 
   // Panel-Container für Schalter anlegen
   JPanel panel = new JPanel();
   JPanel panel_Button = new JPanel();
   JPanel panel_Werte = new JPanel();
    panel.add(panel_Button);
    panel.add(panel_Werte);

     // Gitter mit 3 Zeilen, 4 Spalten
     panel_Button.setLayout(new GridLayout(3,4,10,20));     
     panel_Werte.setLayout(new GridLayout(3,3,0,0));     
     panel.setLayout(new GridLayout(2,1,10,20));     
  
     // Schalter anlegen und in Panel aufnehmen
     JButton f1 = new JButton("tan(x)");
     JButton f2 = new JButton("sin(x)");
     JButton f3 = new JButton("cos(x)");
     JButton f11 = new JButton("log(x)");
     JButton f4 = new JButton("x^2");
     JButton f5 = new JButton("x^3");
     JButton f6 = new JButton("x^z");
     JButton f7 = new JButton("x^z+s");
     JButton f8 = new JButton("a*(x^z)+s");
     JButton f9 = new JButton("a*[(x-c)^z]+s");
     JButton f10 = new JButton("a*x^z+b*x+c");
     JPanel panel_Z = new JPanel();
     JPanel panel_S = new JPanel();
     JPanel panel_A = new JPanel();
     JPanel panel_C = new JPanel();
     JPanel panel_B = new JPanel();
     JLabel l1 = new JLabel("Z:");
     t1 = new JTextField("2", 2);
     JLabel l2 = new JLabel("S:");
     t2 = new JTextField("0", 2);
     JLabel l3 = new JLabel("A:");
     t3 = new JTextField("1", 2);
     JLabel l4 = new JLabel("C:");
     t4 = new JTextField("0", 2);
     JLabel l5 = new JLabel("B:");
     t5 = new JTextField("0", 2);
     cb1 = new JCheckBox("Ergänzen");
     panel_Button.add(f1);
     f1.setMnemonic('t');
     panel_Button.add(f2);
     f2.setMnemonic('i');
     panel_Button.add(f3);
     f3.setMnemonic('o');
     panel_Button.add(f11);
     f11.setMnemonic('l');
     panel_Button.add(f4);
     f4.setMnemonic('2');
     panel_Button.add(f5);
     f5.setMnemonic('3');
     panel_Button.add(f6);
     f6.setMnemonic('z');
     panel_Button.add(f7);
     f7.setMnemonic('s');
     panel_Button.add(f8);
     f8.setMnemonic('a');
     panel_Button.add(f9);
     f9.setMnemonic('c');
     panel_Button.add(f10);
     f10.setMnemonic('b');
     panel_Werte.add(panel_Z);
     panel_Z.setLayout(new FlowLayout());
     panel_Z.add(l1);
     panel_Z.add(t1);
     panel_Werte.add(panel_S);
     panel_S.setLayout(new FlowLayout());
     panel_S.add(l2);
     panel_S.add(t2);
     panel_Werte.add(panel_A);
     panel_A.setLayout(new FlowLayout());
     panel_A.add(l3);
     panel_A.add(t3);
     panel_Werte.add(panel_C);
     panel_A.setLayout(new FlowLayout());
     panel_C.add(l4);
     panel_C.add(t4);
     panel_Werte.add(panel_B);
     panel_B.setLayout(new FlowLayout());
     panel_B.add(l5);
     panel_B.add(t5);
     panel_Werte.add(cb1);
  
   getContentPane().add(panel);


   class CMeinWindowAdapter extends WindowAdapter
      {
      public void windowClosing(WindowEvent e)
         {
         System.exit(0);
         }
      }
    
   // Das Event-Handling für die Schalter
   class CMeinActionLauscher implements ActionListener
      {
      public void actionPerformed(ActionEvent e)
         {
          String label;

          label = e.getActionCommand();
       
          if(label.equals("tan(x)"))
               aktFunktion = 1;
          if(label.equals("sin(x)"))

	aktFunktion = 2;
          if(label.equals("cos(x)"))

	aktFunktion = 3;
          if(label.equals("x^2"))
	aktFunktion = 4;
          if(label.equals("x^3"))
	aktFunktion = 5;
          if(label.equals("x^z"))
	aktFunktion = 6;
          if(label.equals("x^z+s"))
	aktFunktion = 7;
          if(label.equals("a*(x^z)+s"))
	aktFunktion = 8;
          if(label.equals("a*[(x-c)^z]+s"))
	aktFunktion = 9;
          if(label.equals("a*x^z+b*x+c"))
	aktFunktion = 10;
          if(label.equals("log(x)"))
	aktFunktion = 11;
         
         // Neuzeichnen veranlassen
         m_malflaeche.repaint();
         }
    }

   class CMeinMausMoutionLauscher implements MouseMotionListener
      {
       public void mouseMoved(MouseEvent me)
	{
	double x1 = me.getX();
	double x = Math.round( (x1 / 50 -3) * 100 ) / 100.;
	double y1 = me.getY();
	double y = Math.round( (y1 / 50 -3) * 100 ) / 100.;
	               y = y * (-1);
	CFunkPlotter2.Fenster.setTitle("Funktionenplotter - (" + x + "; " + y + ")");
	}
       public void mouseDragged(MouseEvent me)
	{
	}
      }

   // Die Lausch-Objekte anlegen
   f1.addActionListener(new CMeinActionLauscher());
   f2.addActionListener(new CMeinActionLauscher());
   f3.addActionListener(new CMeinActionLauscher());
   f4.addActionListener(new CMeinActionLauscher());
   f5.addActionListener(new CMeinActionLauscher());
   f6.addActionListener(new CMeinActionLauscher());
   f7.addActionListener(new CMeinActionLauscher());
   f8.addActionListener(new CMeinActionLauscher());
   f9.addActionListener(new CMeinActionLauscher());
   f10.addActionListener(new CMeinActionLauscher());
   f11.addActionListener(new CMeinActionLauscher());
   m_malflaeche.addMouseMotionListener(new CMeinMausMoutionLauscher());
   addWindowListener(new CMeinWindowAdapter());
   }


class CMeineCanvas extends Canvas
  {
  public void update(Graphics g)
     {
      if(cb1.isSelected())
          paint(g);

      else{
	//return; - oder was soll ich hier machen ???
               }
      }

  // Konstruktor
  CMeineCanvas() {
     // den Hintergrund auf schwarz setzen
     setBackground(Color.black);

     // Vordergrund (=Zeichenfarbe) auf blau setzen
     setForeground(Color.green);
     }

  // Die wichtigste Methode: hier wird gezeichnet!
  public void paint(Graphics g) {
    double x,y;
    int xpos,ypos;

    // Ursprung umsetzen
    g.translate(150,150);

    // Koordinatenachsen einzeichnen
    g.setColor(Color.red);
    g.drawLine(0,-150,0,150);
    g.drawLine(-150,0,150,0);
    g.drawString("-3",-150,12);
    g.drawString("-3",4,147);
    g.drawString("+3",135,12);
    g.drawString("+3",4,-140);

    // Farbe zum Zeichnen der Funktion
    g.setColor(new Color(255,255,0));
        
    // Wenn keine Funktion ausgewählt ist, nichts tun
    if(aktFunktion == 0)
	return;

    for(x= -3.0; x<=3; x += 0.005)
      {
       y = 0;
       if(aktFunktion == 1)
          y = Math.tan(x);
       if(aktFunktion == 2)
          y = Math.sin(x);
       if(aktFunktion == 3)
          y = Math.cos(x);
       if(aktFunktion == 4)
          y = Math.pow(x,2);
       if(aktFunktion == 5)
          y = Math.pow(x,3);
       if(aktFunktion == 6)
          {
          int z = Integer.parseInt(t1.getText());
          y = Math.pow(x,z);
          }
       if(aktFunktion == 7)
          {
          int z = Integer.parseInt(t1.getText());
         double s = Double.parseDouble(t2.getText());
          y = Math.pow(x,z);
          y = y + s;
          }
       if(aktFunktion == 8)
          {
          int z = Integer.parseInt(t1.getText());
         double s = Double.parseDouble(t2.getText());
         double a = Double.parseDouble(t3.getText());
          y = Math.pow(x,z);
          y = a * y;
          y = y + s;
          }
       if(aktFunktion == 9)
          {
          int z = Integer.parseInt(t1.getText());
         double s = Double.parseDouble(t2.getText());
         double a = Double.parseDouble(t3.getText());
         double c = Double.parseDouble(t4.getText());

         double x_tmp = x + c;
          y = Math.pow(x_tmp,z);
          y = a * y;
          y = y + s;
          }
       if(aktFunktion == 10)
          {
          int z = Integer.parseInt(t1.getText());
         double s = Double.parseDouble(t2.getText());
         double a = Double.parseDouble(t3.getText());
         double c = Double.parseDouble(t4.getText());
         double b = Double.parseDouble(t5.getText());
         double x_tmp1 = Math.pow(x,z);
         double x_tmp2 = b * x;
          y = a * x_tmp1 + x_tmp2 + c;
          }
       if(aktFunktion == 11)
          y = Math.log(x);

       xpos = (int) (x*50); 
       ypos = (int) (-y*50); 
       
       g.fillOval(xpos,ypos,1,1);
       }  
    }

  // Diese Methode liefert die minimale Größe der Canvas
  public Dimension getMinimumSize() {
    return new Dimension(300,300);
    }

  // Die Lieblingsgröße setzen wir auf die Minimalgröße
  public Dimension getPreferredSize() {
    return getMinimumSize();
    }
  }


} // Ende der Klasse CFunkPlotter
```


----------



## Beni (31. Aug 2005)

Wenns Dir nichts ausmacht, schreibe ich das ganze nur Pseudocodeartig auf.


```
public class FunctionCanvas{
   // also wie die Reihenfolge jetzt genau ist... guck besser nochmal in der API nach. Jedenfalls
  // sollte das ein Bild mit Grösse 500/500 sein.
  private Image image = new BufferedImage( BufferedImage.TYPE_INT_RGB, 500, 500 );


  // Das Bild auf das Canvas zeichnen
  public void update( Graphics g ){
    paint( g );
  }

  public void paint( Graphics g ){
    g.drawImage( image, 0, 0, this );
  }


  // Irgendeine Funktion auf das Bild zeichnen
  public void drawFunctionSowieso(){
     // Graphics erzeugen und Farbe setzen
     Graphics g = image.getGraphics();
     g.setColor( Color.RED );

     // Zeichnen
     for( ... ){
        g.fillOval( x, f(x), 1, 1 );
     }

     // Das Canvas das Bild neu zeichnen lassen.
     repaint();
  }
}
```

P.S. für später, überleg dir mal mit einem Interface zu arbeiten:

```
public interface Function{
  public double f( double x );
}
```


```
public void drawFunction( Function fun ){
     ...
     for( ... ){
        g.fillOval( x, fun.f(x), 1, 1 );
     }
     ...
}

public void drawQuadrat(){
   drawFunction( new Function(){
      public double f( double x ){
        return x*x;
      }
   });
}
```
Das hat den Vorteil, dass du sehr einfach verschiedene Funktionen implementieren musst, ohne dieses riesige if-else-Ding das du jetzt noch hast.


----------



## new michi (31. Aug 2005)

Danke ich werds mal probiren...

obs klappt schreib ich dann das nächtse mal wenn ich ins internet komm!(dauert ne weile, so'n Monat oder so)


----------

