27.5.2 Spätes Binden
 
Downlaod:
JDemoQuadrat Kreis.java
Der Quelltext von JDemoQUadratKreis.java:
mport java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import tauglichkeitstester.figur.*;

public class JDemoQuadratKreis extends JFrame
                               implements ActionListener {
    // Konstanten
    private static final int BREITE = 200, HOEHE = 200;
    private static int xMitte, yMitte, b=0;;

    //Attribute
    private JPanel myPanel, westPanel;
    private JButton bQuadrat, bKreis;
    private JLabel textLabel, copyRight;
    private ButtonGroup bgFarbe;
    private JRadioButton rbRot, rbGruen, rbBlau, rbSchwarz;
    private ZeichenPanel zeichenFlaeche;
    private Figur dieFigur;
    private JTextField textFeld;
    private Color farbe;

    //Konstruktor
    public JDemoQuadratKreis(String titel){
      super(titel);

      // Zum ordentlichen Beenden des Programms
      setDefaultCloseOperation(EXIT_ON_CLOSE);
    
      // Anfangswerte festlegen
      xMitte = BREITE/2; 
      yMitte = HOEHE/2; 
      b = Math.min(BREITE, HOEHE)*9/10;

      myPanel = new JPanel(new BorderLayout(15, 5));
      getContentPane().add(myPanel);
    
      westPanel = new JPanel();
      westPanel.setLayout(new BoxLayout(westPanel, 
                              BoxLayout.Y_AXIS));
      myPanel.add(westPanel,BorderLayout.WEST);

      textLabel = new JLabel("TestProgramm ", 
                             SwingConstants.CENTER);
      textLabel.setFont(new Font("MS Sans Serif", Font.BOLD, 30));
      myPanel.add(textLabel, BorderLayout.NORTH);

      textFeld = new JTextField("Durchmesser bzw. Seite 
                               in Pixel (Zahl!)",20);
      westPanel.add(textFeld);

      bgFarbe = new ButtonGroup();
    
      rbSchwarz = new JRadioButton("schwarz",true);
      rbSchwarz.addActionListener(this);
    
      rbGruen = new JRadioButton("grün",false);
      rbGruen.addActionListener(this);
    
      rbRot = new JRadioButton("rot",false);
      rbRot.addActionListener(this);
    
      rbBlau = new JRadioButton("blau",false);
      rbBlau.addActionListener(this);
    
      bgFarbe.add(rbSchwarz);
      bgFarbe.add(rbGruen);
      bgFarbe.add(rbRot);
      bgFarbe.add(rbBlau);
    
      westPanel.add(rbSchwarz);
      westPanel.add(rbGruen);
      westPanel.add(rbRot);
      westPanel.add(rbBlau);
    
      bKreis = new JButton("zeichne Kreis");
      bKreis.addActionListener(this);
      westPanel.add(bKreis);

      bQuadrat = new JButton("zeichne Quadrat");
      bQuadrat.addActionListener(this);
      westPanel.add(bQuadrat);
    
      zeichenFlaeche = new ZeichenPanel(BREITE, HOEHE);
      zeichenFlaeche.setFigur(dieFigur);               
      myPanel.add(zeichenFlaeche, BorderLayout.CENTER);

      copyRight = new JLabel("Multiplikatorengruppe 
              Informatik SII, \u00a9 2002", SwingConstants.LEFT);
      copyRight.setFont(new Font("SansSerif", Font.PLAIN, 11));
      myPanel.add(copyRight,BorderLayout.SOUTH);

      // Erscheinungsbild festlegen
      pack();
      setResizable(false);
      // Auf dem Bildschirm zentrieren und sichtbar machen
      Dimension screenSize = 
              Toolkit.getDefaultToolkit().getScreenSize();
      setLocation((screenSize.width - this.getSize().width)/2,
                (screenSize.height - this.getSize().height)/2);
      setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        // Welches Objekt hat das Ereignis ausgelöst?
        Object obj = e.getSource();
        // Kreis wurde gewählt
        if (obj == bKreis) {
            b = Integer.parseInt(textFeld.getText())/2;
            System.out.println("Figur hat Farbe: "+farbe);
            dieFigur = new Kreis(xMitte,yMitte,b,farbe);
            zeichenFlaeche.setFigur(dieFigur);
        }
        // Quadrat wurde ausgewählt
        if (obj == bQuadrat) {
            b = Integer.parseInt(textFeld.getText());
            System.out.println("Figur hat Farbe: "+farbe);
            dieFigur = new Quadrat(xMitte, yMitte,b,farbe);
            zeichenFlaeche.setFigur(dieFigur);
        }
        //schwarz wurde gewählt
        if (obj == rbSchwarz){
          farbe = Color.black;
          System.out.println("Schwarz");
        }
        //grün wurde gewählt
        if (obj == rbGruen){
          farbe = Color.green;
          System.out.println("Grün");
        }
        //rot wurde gewählt
        if (obj == rbRot){
          farbe = Color.red;
          System.out.println("Rot");
        }
        //blau wurde gewählt
        if (obj == rbBlau){
          farbe = Color.blue;
          System.out.println("Blau");
        }
        
        repaint();
    }

    //Main-Methode
    public static void main(String args[]){
        new JDemoQuadratKreis("Quadrat- und Kreis-Tester");
    }
}
  Der Quelltext zeigt über weite Strecken Bekanntes. Was ist neu? Zunächst erkennt man, dass bei den Attributen mit

        private Figur dieFigur;

ein Variable vom Typ Figur deklariert wird.  Instanziiert wird dieFigur erst in der Methode actionPerformed:

        if (obj == bKreis) {
            b = Integer.parseInt(textFeld.getText())/2;
            System.out.println("Figur hat Farbe: "+farbe);
            dieFigur = new Kreis(xMitte,yMitte,b,farbe);
            zeichenFlaeche.setFigur(dieFigur);
        }

bzw.

        if (obj == bQuadrat) {
            b = Integer.parseInt(textFeld.getText());
            System.out.println("Figur hat Farbe: "+farbe);
            dieFigur = new Quadrat(xMitte, yMitte,b,farbe);
            zeichenFlaeche.setFigur(dieFigur);
        }

Die Entscheidung, ob dieFigur als Quadrat oder als Kreis instanziiert wird, wird erst zur Laufzeit entschieden. Wir sprechen deshalb von einer späten Bindung als eine weitere Form von Polymorphie. Die Zeichenfläche ist in einer eigenen Klasse, nämlich ZeichenPanel implementiert. Interessant ist nun, was die Methode setFigur(Figur, dieFigur), die hier für die Instanz zeichenFlaeche aufgerufen wird (grün unterlegt) tut.

Wir schauen uns dazu den Quelltext von ZeichenPanel.java an.

 

Download:
ZeichenPanel. java
import java.awt.*;
import javax.swing.*;
import tauglichkeitstester.figur.*;

class ZeichenPanel extends JPanel{
  private int width, height;
  private Figur dieFigur;
   
  public ZeichenPanel(int width, int height){
    super();
    this.width = width;
    this.height = height;
    setPreferredSize(new Dimension (width, height));
    setBorder(BorderFactory.createLineBorder(Color.darkGray,2));
    setBackground(Color.white);
  }
    
  public void setFigur(Figur dieFigur) {
    this.dieFigur = dieFigur;           
  }                                     


  public void paintComponent(Graphics g){
    super.paintComponent(g);
    // Nur wenn ein Test instanziiert ist, soll gezeichnet werden.
    if (dieFigur != null)
      dieFigur.zeigeDich(g);
    else {
      g.setColor(getBackground());
      g.drawRect(0, 0, getSize().width, getSize().height);
    }
  }
}
  Wieder ist ein Objekt, nämlich dieFigur als Figur deklariert und wird beim Aufruf der setFigur(Figur dieFigur) gebunden, d.h.  es handelt sich um ein Quadrat oder ein Kreis (gelb unterlegt). 
 
  Interessant ist die Methode paintComponent(Graphiucs g). Sie wurde von JPanel geerbt und wird hier überschrieben. Dass sie auf jeden Fall ihre geerbte Funktionalität behält, garantiert

super.paintComponent(g);

Im weitern Code bekommt diese Methode eine weitere Funktionalität. Falls dieFigur eine Referenz hat, wird dieFigur gezeichnet, also die Methode zeigeDich(Graphics g) für dieFigur aufgerufen (grün unterlegt) . Jetzt wird noch mal deutlich, warum das Zeichnen in Figur organisiert wurde. Je nach Bindung von dieFigur ruft zeigeDich(Graphics g) nachdem sie die Zeichenfarbe gesetzt hat die Methode zeichne(Graphics g) von der Tochterklasse Kreis oder Quadrat auf.

Es bleibt noch zu klären was paintComponent(Graphics g) eigentlich macht und wer sie aufruft. Die Java-Dokumentation gibt darüber Auskunft. Sobald bei einer grafischen Applikation etwas verändert wurde, ruft die VM paintComponent(Graphics g) auf, die ihrerseits die Methode paint() aufruft.

   
zu 27.6 Übungen
zur Startseite www.pohlig.de  (C) MPohlig 2004