Pinsel und Radierer

Die Idee ist, die Werkzeugspitzen nicht nur zum Malen, sondern auch zum Radieren zu verwenden. Zwar könnten wir standardmäßig die Farbe des Radierers auf Weiß stellen, es ist aber nicht viel Aufwand zusätzlich eine Hintergrundfarbe zu definieren und bei Wahl des Radierers die Hintergrundfarbe und bei Wahl des Pinsels die Vordergrundfarbe zu nehmen. Wir beginnen wieder in der:
StartFenster.java

package miniMalen1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SpinnerNumberModel;

public class StartFenster extends JFrame implements ActionListener
{
  public static void main(String[] s) {
    new StartFenster();
  }

  private JToolBar auswahl;
  private JToolBar seitenleiste;
  
  JRadioButton kreisBtn;
  JRadioButton quadratBtn;
  JCheckBox fuellen;
  JSpinner linienstaerke;
  ButtonGroup werkzeugspitzen = new ButtonGroup();

  JToggleButton pinselBtn;
  JToggleButton radiererBtn;
  private JButton farbwaehlerIcon;
  private JButton farbwaehlerIconHG;
  
  Color vgfarbe = Color.BLACK;
  Color hgfarbe = Color.WHITE;
  Color aktuelleFarbe = Color.BLACK;

  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(false);
    
    kreisBtn = new JRadioButton("Kreis");
    kreisBtn.setSelected(true);
    quadratBtn = new JRadioButton("Quadrat");
    werkzeugspitzen.add(kreisBtn);
    werkzeugspitzen.add(quadratBtn);
    auswahl.add(kreisBtn);
    auswahl.add(quadratBtn);
    
    fuellen = new JCheckBox("Füllen");
    auswahl.add(fuellen);
    
    seitenleiste = new JToolBar();
    seitenleiste.setPreferredSize(new Dimension(30, 200)); // PreferredSize = bevorzugte Größe
    seitenleiste.setFloatable(false);
    seitenleiste.setOrientation( JToolBar.VERTICAL );
      Insets nullMargin = new Insets( 5, 7, 5, 5 );
      seitenleiste.setMargin( nullMargin );
      
    pinselBtn = new JToggleButton("P") ;
    pinselBtn.setPreferredSize(new Dimension(20,20));
    pinselBtn.setSelected(true);
    pinselBtn.setAlignmentX(CENTER_ALIGNMENT);
    pinselBtn.setBorder( BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
    pinselBtn.setSelected(true);
    pinselBtn.addActionListener(this);

    radiererBtn = new JToggleButton("R");
    radiererBtn.setPreferredSize(new Dimension(20,20));
    radiererBtn.setSelected(false);
    radiererBtn.setAlignmentX(CENTER_ALIGNMENT);
    radiererBtn.setBorder( BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
    radiererBtn.addActionListener(this);

    
    farbwaehlerIcon = new JButton() {
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(vgfarbe);
        g.fillRect(20, 20, 20, 20);
      }
    };
    farbwaehlerIcon.setPreferredSize(new Dimension(20,20));
    farbwaehlerIcon.addActionListener(this);
    farbwaehlerIcon.setBackground(vgfarbe);
    farbwaehlerIcon.setForeground(vgfarbe);
    farbwaehlerIcon.setAlignmentX(CENTER_ALIGNMENT);
    
    farbwaehlerIconHG = new JButton() {
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(hgfarbe);
        g.fillRect(20, 20, 20, 20);
      }
    };
    farbwaehlerIconHG.setPreferredSize(new Dimension(20,20));
    farbwaehlerIconHG.addActionListener(this);
    farbwaehlerIconHG.setBackground(hgfarbe);
    farbwaehlerIconHG.setForeground(hgfarbe);
    farbwaehlerIconHG.setAlignmentX(CENTER_ALIGNMENT);

    seitenleiste.add(pinselBtn);
    seitenleiste.add(radiererBtn);
    seitenleiste.addSeparator();
    seitenleiste.add(farbwaehlerIcon);
    seitenleiste.add(farbwaehlerIconHG);

    SpinnerNumberModel nummern = new SpinnerNumberModel(10.0, 1.0, 99.0, 1.0); // 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);
    this.add(seitenleiste,BorderLayout.WEST);
    
    Tafel tafel = new Tafel(this);
    this.add(tafel);

    sichtbar();
  }

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

  }
  
  public double getLinienstaerke() {
    double staerke = (double) this.linienstaerke.getValue();
    return staerke;
  }
  public Color getFarbe() {
    return this.aktuelleFarbe;
  }

  @Override
  public void actionPerformed(ActionEvent e) {
      Object source = e.getSource();
      if(source == farbwaehlerIcon) {
      	vgfarbe = JColorChooser.showDialog(this, "Vordergrundfarbe wählen", vgfarbe);
      farbwaehlerIcon.setBackground(vgfarbe);
      aktuelleFarbe = vgfarbe;
      	farbwaehlerIcon.repaint();
      } else if(source == farbwaehlerIconHG) {
      	hgfarbe = JColorChooser.showDialog(this, "Hintergrundfarbe wählen", vgfarbe);
      farbwaehlerIconHG.setBackground(hgfarbe);
      aktuelleFarbe = hgfarbe;
      	farbwaehlerIconHG.repaint();
      }
      if ( source == pinselBtn ) {
      	pinselBtn.setSelected(true);
      	radiererBtn.setSelected( false );
      	aktuelleFarbe = vgfarbe;
      }

      if ( source == radiererBtn ) {
      	radiererBtn.setSelected(true);
      	pinselBtn.setSelected( false );
      	aktuelleFarbe = hgfarbe;
      }
  
  }
}

Zuerst deklarieren wir wieder die benötigten Variablen: Zwei JToggleButtons  (Zeile 41, 42) und einen weiteren JButton (Zeile 44). Ein JToggleButton ist ein normaler Button, der jedoch „einrasten“ kann. Diesen nehmen wir, weil JRadioButtons für die schmale Seitenleiste weniger geeignet sind. Ausserdem benötigen wir eine Variable für die aktuelleFarbe (Zeile 48) da wir unser Grafikobjekt so klein wie möglich halten wollen. Ansonsten müssten wir in der Tafel eine extra if-Abfrage machen, welches Werkzeug (Pinsel oder Radierer) gewählt ist und dementsprechend reagieren. Performanter ist es daher, gleich bei der Auswahl des Werkzeugs die aktuelleFarbe entsprechend einzustellen. Der Pinsel malt mit der Vordergrundfarbe vgfarbe, der Radierer mit der Hintergrundfarbe hgfarbe. Diese beiden Variablen deklarieren wir ebenfalls. Die alte Variable farbe wird gelöscht.

In den Zeilen 85-98 initialisieren wir die JToggleButtons.
setAlignmentX() und setBorder() sind notwendig um die Buttons zu zentrieren und kleiner darzustellen (der Rand ist ansonsten zu groß und zu globig für die schmale Seitenleiste).

In 114-125 erstellen wir einen neuen Farbwähler Button wie im vorherigen Kapitel.

In 127-131 wird das ganze an die Seitenleiste geheftet. Zeile 129 setzt zwischen den Werkzeugen und den Farben einen kleinen Abstand.

Schließlich müssen wir nur noch den Getter in Zeile 158 auf aktuelleFarbe umstellen.
Das wars!

Als nächstes wollen wir ein kleines Menü hinzufügen.