Werkzeugspitzen

Unsere zwei Werkzeugspitzen müssen wir zunächst im Quellcode von Startfenster.java einfügen. Dies verwirklichen wir durch zwei Radio-Buttons. Hierbei müssen wir sowohl die zwei Buttons deklarieren wie auch ein Gruppierungswerkzeug namens ButtonGroup welches alle anderen Buttons in dieser Gruppe deaktiviert sobald ein Button selektiert wurde.

Startfenster.java

package miniMalen1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JToolBar;
import javax.swing.SpinnerNumberModel;

public class StartFenster extends JFrame {

  public static void main(String[] s) {
    new StartFenster();
  }

  private ArrayList<Grafikobjekt> virtuellerBildschirm = new ArrayList<Grafikobjekt>();
  private JPanel panel;
  private int x = -10;
  private int y = -10;
  JRadioButton kreisBtn;
  JRadioButton quadratBtn;
  ButtonGroup werkzeugspitzen = new ButtonGroup();
  JSpinner linienstaerke;
  private JToolBar auswahl;

  public StartFenster() {
    initialisiereStartFenster();
  }

  private void initialisiereStartFenster() {
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setBounds(0, 0, 500, 500);
    this.setLocationRelativeTo(null);
    this.setAlwaysOnTop(true);
    this.setBackground(Color.white);
    this.setTitle("Tafel");
    this.setLayout(new BorderLayout());

    auswahl = new JToolBar();
    auswahl.setPreferredSize(new Dimension(300, 30)); // PreferredSize = bevorzugte Größe
    auswahl.setFloatable(true);
    
    kreisBtn = new JRadioButton("Kreis");
    quadratBtn = new JRadioButton("Quadrat");
    werkzeugspitzen.add(kreisBtn);
    werkzeugspitzen.add(quadratBtn);
    
    auswahl.add(kreisBtn);
    auswahl.add(quadratBtn);
  
    SpinnerNumberModel nummern = new SpinnerNumberModel(10, 1, 99, 1); // ( default, Minimum, Maximum, Schrittweite
                                      // )
    linienstaerke = new JSpinner(nummern);
    linienstaerke.setMinimumSize(new Dimension(50, 30)); // setzt die Mindestgröße ( Breite, Höhe )
    linienstaerke.setMaximumSize(new Dimension(50, 30)); // setzt die Maximalgröße

    auswahl.add(linienstaerke);
    this.add(auswahl, BorderLayout.PAGE_START);
    
    Tafel tafel = new Tafel(this);
    this.add(tafel);

    sichtbar();
  }

  private void sichtbar() {
    this.setVisible(true);

  }
  
  public int getLinienstaerke() {
    int staerke = (int) this.linienstaerke.getValue();
    return staerke;
  }
}

Nach der Deklaration (Zeile 25- 27), werden die RadioButtons in Zeile 48und 49und anschließend der Buttongroup werkzeugspitzen in den Zeilen 50 und 51 hinzugefügt. Anschließend werden beide Buttons dem Auswahlobjekt in Zeile 53 und 54 hinzugefügt.

Da ButtonGroup kein Container ist, der die Buttons beinhaltet sondern lediglich dafür sorgt das die Buttons als RadioButton-Gruppe behandelt werden, braucht und kann die ButtonGroup auch nicht der auswahl hinzugefügt werden.

Als nächstes müssen wir das Grafikobjekt modifizieren, wobei wir hier nur eine neue Variable deklarieren und den Konstruktor entsprechend anpassen müssen:

Grafikobjekt.java

package miniMalen1;

import java.awt.Point;

class Grafikobjekt {

  Point koordinaten;
  int stiftdicke;
  int stifttyp;

  public Grafikobjekt(Point p, int sd, int st) {
    this.koordinaten = p;
    this.stiftdicke = sd;
    this.stifttyp = st;
  }

  public Point getKoordinaten() {
    return koordinaten;
  }

  public void setKoordinaten(Point koordinaten) {
    this.koordinaten = koordinaten;
  }

  public int getStiftdicke() {
    return stiftdicke;
  }

  public void setStiftdicke(int stiftdicke) {
    this.stiftdicke = stiftdicke;
  }
}

Zuletzt die Tafel.java

package miniMalen1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JPanel;

public class Tafel extends JPanel implements MouseListener, MouseMotionListener {

  private ArrayList<Grafikobjekt> virtuellerBildschirm = new ArrayList<Grafikobjekt>();

  private int x = -10;
  private int y = -10;
  private StartFenster auswahl;

  public Tafel(StartFenster auswahl) {
    this.auswahl = auswahl;
    this.setBackground(Color.WHITE);
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    {
      for (int z = 0; z < virtuellerBildschirm.size(); z++) {
        Grafikobjekt go = virtuellerBildschirm.get(z);
        if(go.stifttyp == 2)
        g.fillRect(go.getKoordinaten().x, go.getKoordinaten().y, go.getStiftdicke(), go.getStiftdicke());
        else
        g.fillOval(go.getKoordinaten().x, go.getKoordinaten().y, go.getStiftdicke(), go.getStiftdicke());
      }
    }

  }

  @Override
  public void mouseDragged(MouseEvent e) {
    System.out.println("Dragged");
    x = e.getX();
    y = e.getY();

    int werkzeug;
    if ( auswahl.quadratBtn.isSelected() ) {
      werkzeug = 2;
    } else {
      werkzeug = 1;
    }
    virtuellerBildschirm.add(new Grafikobjekt(new Point(x, y), auswahl.getLinienstaerke(), werkzeug));

    this.repaint();
  }

  @Override
  public void mousePressed(MouseEvent e) {
    System.out.println("Pressed");
    x = e.getX();
    y = e.getY();
    
    int werkzeug;
    if ( auswahl.quadratBtn.isSelected() ) {
      werkzeug = 2;
    } else {
      werkzeug = 1;
    }
    virtuellerBildschirm.add(new Grafikobjekt(new Point(x, y), auswahl.getLinienstaerke(),werkzeug));

    this.repaint();
  }
}

Zunächst wird in Zeile 49 bzw. 66 eine if-Abfrage hinzugefügt die im Falle das der RadioButton quadratBtn selektiert ist der Variable werkzeug  den Wert 2 zuweist, andernfalls 1 ( zwar könnte man dies mit einem Boolean noch einfacher lösen, aber wir wollen ja letztendlich noch mehr Werkzeugspitzen hinzufügen können).
Anschließend müssen wir noch unserem virtuellem Bildschirm in Zeile 54 bzw. 71 die Variable werkzeug mitübergeben.
Schließlich fügen wir noch in der paint-Methode ab Zeile 33 eine if-Abfrage ein, die je nachdem ob der stifttyp des Grafikobjekts 1 oder 2 ist ein Quadrat oder einen Kreis zeichnet.

Wie ihr vielleicht schon bemerkt habt, können wir an dieser Stelle bereits die erste effektive Verbesserungen am Quellcode vornehmen. Bis jetzt müssen wir die Aktionen nach der Initialisierung der x und y Variablen in der MouseDragged und MousePressed Methode doppelt schreiben. Einfacher wäre es die x und y Variable an eine weitere Methode zeichenAufVirtuellenBildschirm(x, y) zu übergeben.
Der Quellcode würde dann (ohne die noch nicht verwendeten MouseListener-Methoden) folgendermaßen aussehen:

package miniMalen1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JPanel;

public class Tafel extends JPanel implements MouseListener, MouseMotionListener {

  private ArrayList<Grafikobjekt> virtuellerBildschirm = new ArrayList<Grafikobjekt>();

  private int x = -10;
  private int y = -10;
  private StartFenster auswahl;

  public Tafel(StartFenster auswahl) {
    this.auswahl = auswahl;
    this.setBackground(Color.WHITE);
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    {
      for (int z = 0; z < virtuellerBildschirm.size(); z++) {
        Grafikobjekt go = virtuellerBildschirm.get(z);
        if(go.stifttyp == 2)
        g.fillRect(go.getKoordinaten().x, go.getKoordinaten().y, go.getStiftdicke(), go.getStiftdicke());
        else
        g.fillOval(go.getKoordinaten().x, go.getKoordinaten().y, go.getStiftdicke(), go.getStiftdicke());
      }
    }

  }
  
  public void zeichneAufVirtuellenBildschirm(int x, int y) {
    int werkzeug;
    if ( auswahl.quadratBtn.isSelected() ) {
      werkzeug = 2;
    } else {
      werkzeug = 1;
    }
    virtuellerBildschirm.add(new Grafikobjekt(new Point(x, y), auswahl.getLinienstaerke(), werkzeug));

    this.repaint();
  }

  @Override
  public void mouseDragged(MouseEvent e) {
    System.out.println("Dragged");
    x = e.getX();
    y = e.getY();
    zeichneAufVirtuellenBildschirm(x,y);
  }

  @Override
  public void mousePressed(MouseEvent e) {
    System.out.println("Pressed");
    x = e.getX();
    y = e.getY();
    zeichneAufVirtuellenBildschirm(x,y);
  }

}

doch schon wesentlich kürzer oder?

Als nächstes wollen wir eine weitere Option hinzufügen: Gefüllt oder nicht gefüllt.
Kaffee gefällig?