Verschönerungen II – Icons

Um Icons verwenden zu können müssen wir zunächst welche haben. Eine schöne Seite für freie Icons ist das Tango Icon Project von Wiki-Commons.  Hier der direkte Link zum Download des Iconpakets.
Sobald wir das das Iconpaket entpackt haben, finden wir darin Ordner mit den Icons in verschiedenen Größen. Wir benötigen den Ordner 16×16. Bevor wir den Inhalt nutzen können, müssen wir in Eclipse einen sogenannten Resource-Ordner hinzufügen. Wir gehen dabei wie folgt vor:
– rechter Mausklick auf unser Projekt „MiniMalen“
– Neu->Ordner
– als Name geben wir „bilder“ ein
– rechter Mausklick auf den gerade erstellten Ordner->importieren wählen
– Dateisystem wählen, dann Weiter klicken
– oben rechts auf durchsuchen klicken
– den gewünschten ordner mit den ressourcen wählen, in unserem Fall ist das der 16×16 Ordner des Tango Icon Themes, dann Ok.
– Die gewünschten Bilder abhaken -> Fertigstellen

Die gewünschten Bilder befinden sich nun in unserem Ordner bilder. Das Bild was wir benötigen heißt system-shutdown.png. Diesem geben wir einen anderen passenden Namen, z.B. schalter.png. Außerdem kopieren und spiegeln es vertikal  (z.B. mit Photoshop oder IrfanView). Dann geben wir ihm den Namen schalterselected. Ich hab das schon für euch erledigt. Nachfolgend könnt ihr die beiden Grafiken downloaden:
schalter.png
schalterselected.png

Jetzt wollen wir unserem fuellen-JRadionButton mit einem Icon versehen. Hierzu benötigen wir zwei Schritte:
– Wir erstellen ein Objekt vom Typ ImageIcon und laden die Ressource.
– Wir setzen die Größe des ImageIcon fest.

ImageIcon fuellenIcon = new ImageIcon( getClass().getResource("bilder/schalter.png" ) );
fuellenIcon.setImage( fuellenIcon.getImage().getScaledInstance( 16, 16, Image.SCALE_SMOOTH ) );

getClass() gibt den Pfad unseres MiniMalen-Pakets zurück. In diesem Pfad müssen wir dann noch mit getResource() die Ressource auswählen. Da sich das Icon im Ordner bilder befindet müssen wir bilder/ vor den Dateinamen schreiben.

Da wir auch ein Icon für den selektierten Zustand unseres Icons haben wollen, benötigen wir diesen Code nochmal nur mit einem ImageIcon fuellenIconAktiviert, also:

ImageIcon fuellenIconAktiviert = new ImageIcon( getClass().getResource("bilder/schalterselected.png" ) );
fuellenIconAktiviert.setImage( fuellenIconAktiviert.getImage().getScaledInstance(16, 16,Image.SCALE_SMOOTH) );

statt dem Text geben wir bei der Erstellung der JCheckBox einfach unser Icon an:
fuellen = new JCheckBox(fuellenIcon);
Ausserdem müssen wir der Checkbox noch ein Icon zuweisen welches im selektiertem Zustand gezeigt wird: fuellen.setSelectedIcon(fuellenIconAktiviert);

Jetzt müssen wir noch dafür sorgen das der Füllen-Schalter eine Auswirkung auf die Werkzeugspitzen hat, das diese dementsprechend auch dargestellt werden. Also gefüllt oder ungefüllt. Hier dürfen wir nicht vergessen unserer CheckBox noch einen ActionListener hinzuzufügen: fuellen.addActionListener(this);
Dann ergänzen wir die ActionPerformed:

if ( fuellen.isSelected() ) {
kreisBtn.setText( "\u25cf" );
quadratBtn.setText( "\u25a0" );
} else {
kreisBtn.setText( "\u25cb" );
quadratBtn.setText( "\u25a1" );
}

Voila! Sieht doch schon besser aus!

Nun machen wir dasselbe noch mit dem Pinsel und dem Radierer. Wobei wir die JToggleButtons in JRadioButtons umwandeln. Diese eignen sich besser für Icons.
Hier die Grafiken:
pinsel.png
pinselselect.png
radierer.png
radiererselected.png

Dann sollte unsere StartFenster.java ungefähr so aussehen:

package miniMalen;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
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 Tafel tafel;

  private JMenuBar menuBar;
  private JMenu menuDatei;
  private JMenuItem mneu, mladen, mspeichern, mBeenden;

  private JToolBar topmenu;
  private JToolBar seitenleiste;

  JToggleButton kreisBtn;
  JToggleButton quadratBtn;
  JCheckBox fuellen;
  private JSpinner linienstaerke;

  private JRadioButton pinselBtn;
  private JRadioButton radiererBtn;
  private JButton farbwaehlerIcon;
  private JButton farbwaehlerIconHG;

  private Color vgfarbe = Color.BLACK;
  private Color hgfarbe = Color.WHITE;
  private 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());

    menuBar = new JMenuBar();
    this.setJMenuBar(menuBar);

    menuDatei = new JMenu();
    menuDatei.setText("Datei");
    menuDatei.setMnemonic('d');
    menuDatei.addActionListener(this);
    menuBar.add(menuDatei);

    mneu = new JMenuItem();
    mneu.setText("Neu");
    mneu.setMnemonic('n');
    mneu.setToolTipText("Neues Bild erstellen");
    mneu.setIcon(null);
    mneu.addActionListener(this);
    menuDatei.add(mneu);

    JSeparator sep1 = new JSeparator();
    menuDatei.add(sep1);

    mladen = new JMenuItem();
    mladen.setText("Laden");
    mladen.setMnemonic('l');
    mladen.setToolTipText("Datei laden");
    mladen.setIcon(null);
    mladen.addActionListener(this);
    menuDatei.add(mladen);

    mspeichern = new JMenuItem();
    mspeichern.setText("Speichern");
    mspeichern.setMnemonic('s');
    mspeichern.setToolTipText("Bild speichern");
    mspeichern.setIcon(null);
    mspeichern.addActionListener(this);
    menuDatei.add(mspeichern);

    JSeparator sep2 = new JSeparator();
    menuDatei.add(sep2);

    mBeenden = new JMenuItem();
    mBeenden.setText("Beenden");
    mBeenden.setMnemonic('e');
    mBeenden.setToolTipText("Programm beenden");
    mBeenden.setIcon(null);
    mBeenden.addActionListener(this);
    menuDatei.add(mBeenden);

    topmenu = new JToolBar();
    topmenu.setPreferredSize(new Dimension(300, 30)); // PreferredSize = bevorzugte Größe
    topmenu.setFloatable(false);

    kreisBtn = new JToggleButton("\u25cf");
    kreisBtn.setSelected(true);
    kreisBtn.addActionListener(this);
    kreisBtn.setFocusable(false);
    kreisBtn.setMaximumSize(new Dimension(30, 30));
    kreisBtn.setMinimumSize(new Dimension(30, 30));

    quadratBtn = new JToggleButton("\u25a0");
    quadratBtn.addActionListener(this);
    quadratBtn.setFocusable(false);
    quadratBtn.setMaximumSize(new Dimension(30, 30));
    quadratBtn.setMinimumSize(new Dimension(30, 30));
    topmenu.add(kreisBtn);
    topmenu.add(quadratBtn);

    ImageIcon fuellenIcon = new ImageIcon(getClass().getResource("bilder/schalter.png"));
    fuellenIcon.setImage(fuellenIcon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));
    ImageIcon fuellenIconAktiviert = new ImageIcon(getClass().getResource("bilder/schalterselected.png"));
    fuellenIconAktiviert.setImage(fuellenIconAktiviert.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));

    fuellen = new JCheckBox(fuellenIcon);
    fuellen.setSelectedIcon(fuellenIconAktiviert);
    fuellen.setSelected(true);
    fuellen.addActionListener(this);
    topmenu.add(fuellen);

    seitenleiste = new JToolBar();
    seitenleiste.setPreferredSize(new Dimension(30, 200)); // PreferredSize = bevorzugte Größe
    seitenleiste.setSize(24, 200);
    seitenleiste.setMinimumSize(new Dimension(24, 200));
    seitenleiste.setMaximumSize(new Dimension(24, 200));
    seitenleiste.setFloatable(false);
    seitenleiste.setOrientation(JToolBar.VERTICAL);
    seitenleiste.setBorder(null);
    seitenleiste.setBorderPainted(false);
    Insets nullMargin = new Insets(0, 0, 0, 0);
    seitenleiste.setMargin(nullMargin);

    ImageIcon pinselIcon = new ImageIcon(getClass().getResource("bilder/pinsel.png"));
    pinselIcon.setImage(pinselIcon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));
    ImageIcon pinselIconAktiviert = new ImageIcon(getClass().getResource("bilder/pinselselect.png"));
    pinselIconAktiviert.setImage(pinselIconAktiviert.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));

    pinselBtn = new JRadioButton(pinselIcon, true); // in RadioButton umgewandelt
    pinselBtn.setIcon(pinselIcon);
    pinselBtn.setSelectedIcon(pinselIconAktiviert);
    pinselBtn.setAlignmentX(CENTER_ALIGNMENT);
    pinselBtn.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
    pinselBtn.setPreferredSize(new Dimension(16, 16));
    pinselBtn.addActionListener(this);
    pinselBtn.setMargin(nullMargin);

    ImageIcon radiererIcon = new ImageIcon(getClass().getResource("bilder/radierer.png"));
    radiererIcon.setImage(radiererIcon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));
    ImageIcon radiererIconAktiviert = new ImageIcon(getClass().getResource("bilder/radiererselected.png"));
    radiererIconAktiviert.setImage(radiererIconAktiviert.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH));

    radiererBtn = new JRadioButton(radiererIcon, false); // radioButton
    radiererBtn.setIcon(radiererIcon);
    radiererBtn.setSelectedIcon(radiererIconAktiviert);
    radiererBtn.setAlignmentX(CENTER_ALIGNMENT);
    radiererBtn.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
    radiererBtn.setPreferredSize(new Dimension(16, 16));
    radiererBtn.addActionListener(this);
    // radiererBtn.setMargin(nullMargin);

    farbwaehlerIcon = new JButton() {
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(vgfarbe);
        g.fillRect(20, 20, 20, 20);
      }
    };

    farbwaehlerIcon.setBackground(vgfarbe);
    farbwaehlerIcon.setForeground(vgfarbe);
    farbwaehlerIcon.setPreferredSize(new Dimension(20, 20));
    farbwaehlerIcon.setAlignmentX(CENTER_ALIGNMENT);
    // farbwaehlerIcon.setMargin(ohne);
    // farbwaehlerIcon.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
    farbwaehlerIcon.addActionListener(this);

    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, 50));
    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

    topmenu.add(linienstaerke);
    this.add(topmenu, BorderLayout.PAGE_START);
    this.add(seitenleiste, BorderLayout.WEST);

    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() {
    System.out.println(this.aktuelleFarbe);
    return this.aktuelleFarbe;
  }

  public Color getHGfarbe() {
    return this.hgfarbe;
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    System.out.println(source);
    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;
    }
    if (source == kreisBtn) {
      kreisBtn.setSelected(true);
      quadratBtn.setSelected(false);
    }

    if (source == quadratBtn) {
      quadratBtn.setSelected(true);
      kreisBtn.setSelected(false);
    }

    if (fuellen.isSelected()) {
      kreisBtn.setText("\u25cf");
      quadratBtn.setText("\u25a0");
    } else {
      kreisBtn.setText("\u25cb");
      quadratBtn.setText("\u25a1");
    }

    if (source == mneu)
      tafel.neuesBild();

    if (source == mladen)
      loadPicture();

    if (source == mspeichern)
      savePicture(erstelleIMG(tafel));

    if (source == mBeenden)
      this.dispose();

  }

  public BufferedImage erstelleIMG(Component bild) // gibt ein img der zeichenfläche an die Funktion savePicture
                            // zurück
  {
    BufferedImage img = new BufferedImage(bild.getWidth(), bild.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D g = img.createGraphics();
    bild.paintAll(g);
    g.dispose();
    return img;
  }

  private void loadPicture() {
    JFileChooser chooser = new JFileChooser();
    chooser.setDialogType(JFileChooser.OPEN_DIALOG);

    int rueckgabeWert = chooser.showOpenDialog(this);

    if (rueckgabeWert == JFileChooser.APPROVE_OPTION) {
      File file = chooser.getSelectedFile();
      try {
        tafel.image = ImageIO.read(file);
      } catch (IOException e) {
        e.printStackTrace();
      }
      tafel.bildGeladen = true;
      tafel.repaint();
    }

  }

  public void savePicture(BufferedImage img) //
  {
    JFileChooser chooser = new JFileChooser();
    chooser.setDialogType(JFileChooser.SAVE_DIALOG);

    int rueckgabeWert = chooser.showSaveDialog(this);

    if (rueckgabeWert == JFileChooser.APPROVE_OPTION) {

      File file = chooser.getSelectedFile();
      // String bildpfad = file.getAbsolutePath();

      try {
        ImageIO.write(img, "png", file);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  public void dispose() {
    System.out.println("Tschüß");
    System.exit(0);
  }

}

Fertig!
Nun sind wir am Ende dieses Tutorials angekommen. Wenn es euch gefallen hat, freue ich mich um einen Like. Auch konstruktive Kritik bzw. Verbesserungsvorschläge sind gern gesehen.