Mini-Malprogramm

Jetzt werden wir auch schon das erste kleine Malprogramm schreiben: Wir legen ein neues Package an und erstellen darin eine Klasse mit Namen StartFenster:
package miniMalen;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Arc2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;

public class StartFenster extends JFrame {

  static int x = -10;
  static int y = -10;

  public static void main(String[] args) {
    
    StartFenster = new Fenster();

    fenster.setDefaultCloseOperation( EXIT_ON_CLOSE );
    fenster.setBounds( 0, 0, 900, 500 );
    fenster.setLocationRelativeTo( null );
    fenster.setAlwaysOnTop( true );
    fenster.setVisible( true );  
        
    JPanel panel = new JPanel() {

     public void paint( Graphics g ) {
     						 		
       g.fillOval(x, y, 10, 10);	    	
          	  
     }
    
    };
  
    panel.setBackground( new Color( 255, 255, 255 ) );
    JLabel label = new JLabel ("HalloWelt!", JLabel.CENTER);
    panel.add(label);
    fenster.add(panel);
             
    panel.addMouseMotionListener(new MouseAdapter() {
        public void mouseDragged(MouseEvent arg0) {
           System.out.println("Dragged");
               x = arg0.getX();
             y = arg0.getY();
             panel.repaint();
                  	
        }
    });
    
    panel.addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent arg0) { 
         System.out.println("Test");
             x = arg0.getX();
             y = arg0.getY();
             panel.repaint();
        }	
    });
            
  } 
}
Das besondere an diesem Beispiel ist, das es nur dann richtig funktioniert, wenn x und y als statische Variablen deklariert wurden und damit sofort verfügbar sind. Das ist deswegen so, weil wir uns in der Main-Methode befinden und diese statisch ist. Klassenvariable stehen normal nur zur Verfügung nachdem ein Objekt der Klasse gebildet wurde. Da wir aber aufgrund der Kürze des Programms darauf verzichten machen wir die Variablen einfach ebenfalls statisch. Dies ist wohlgemerkt nur bei kleinen Beispielen sinnvoll. Bei größeren Programmen sollte static nur gut überlegt eingesetzt werden. So würde das Programm ohne statische Variablen aussehen:
package start;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;

public class MiniMalprogramm2 extends JFrame {

  int x = -10;
  int y = -10;

  public static void main(String[] args) {		
    new MiniMalprogramm2();			      
  } 
  
  
  public MiniMalprogramm2() {
    initialisiereObjekte();
    zeige();
  }
  
  private void zeige() {
    this.setVisible( true ); 		
  }


  public void initialisiereObjekte() {
    this.setDefaultCloseOperation( EXIT_ON_CLOSE );
    this.setBounds( 0, 0, 900, 500 );
    this.setLocationRelativeTo( null );
    this.setAlwaysOnTop( true );
    this.getContentPane().setBackground(Color.white);
    this.setBackground(Color.white);

    
            
    JPanel panel = new JPanel() {
     public void paint( Graphics g ) {	
      // super.paint(g);
       g.fillOval(x, y, 10, 10);	    			    	  
     }
    
    };
  
    panel.setBackground( Color.WHITE );
    panel.setBounds(0, 0, 100, 100);

    
    this.add(panel);
             
    panel.addMouseMotionListener(new MouseAdapter() {
        public void mouseDragged(MouseEvent arg0) {
           System.out.println("Dragged");
               x = arg0.getX();
             y = arg0.getY();
             panel.repaint();
                  	
        }
    });
    
    panel.addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent arg0) { 
         System.out.println("Test");
             x = arg0.getX();
             y = arg0.getY();
             panel.repaint();
        }	
    });
  }
}
Das this in den Zeilen 32 – 34 ist nur der Vollständigkeit halber dort. Man könnte auch alle Befehle die den JFrame betreffen und ihn einstellen auch ohne this. schreiben. Dann müssten wir allerdings alle Befehle mit der Hand eingeben. Schreiben wir jedoch this. stellt uns Eclipse sofort in einer Auswahl alle Methoden zur Verfügung die das Objekt betreffen auf welches sich this bezieht, und das ist unsere Klasse, die ja auch ein JFrame ist, da wir sie mit extends dementsprechend erweitert haben. Hier sehen wir das die main-Methode im Konstruktor der Klasse zuerst die Methode  initialisiereObjekte() aufruft und danach die zeige-Methode die nur setVisible aufruft. Theoretisch kann man das this.setVisible( true ); auch in die initialisiereObjekte-Methode schreiben. Es ist aber vernünftig dies in eine eigene Methode zu schreiben da hierdurch gesichert ist das setVisible erst am Ende aufgerufen wird. Ansonsten kann es nach dem Kompilieren gerade bei größeren Programmen vorkommen das manche Komponenten und gewissen Umständen, z.B. vergrößern des Fensters nicht sichtbar sind – kurz gesagt, es zu grafischen Fehlern kommen kann. In diesem Beispiel machen wir uns zunutze das, wenn super.paint(g) fehlt, das Fenster die bereits gemalten Punkte behält. Bei komplexeren Programmen ist es allerdings nötig nach der Empfehlung von Oracle vorzugehen und super.paint(g) aufzurufen da es sonst zu unvorhersehbaren Seiteneffekten kommen kann. Selbst wenn es auf dem eigenen Rechner gut aussieht, kann es auf anderen Computern zu Darstellungsfehlern kommen. Da der super-Aufruf unsere alten Punkte löscht müssen wir uns also etwas anderes überlegen. Die Lösung ist: Wir malen kurz vor dem Aufruf der paint-Methode auf eine virtuelle Tafel der alle Punkte enthält die wir gemalt haben. In der Paint-Methode selbst, lesen wir dann nur einmal die Tafel aus und bringen sie komplett auf den Bildschirm. Wir aktualisieren einfach nur den Bildschirm mithilfe unserer virtuellen Tafel. Dies hat auch eine Menge weiterer Vorteile die wir nach und nach kennenlernen wollen. Auf gehts.