Wie lässt sich ein Schrift-Auswahldialog realisieren?

Auf Grundlage eines JDialog lässt sich ein Schrift-Auswahldialog realisieren, der auf die vorinstallierten Systemschriften zugreift.

Das Fenster des Dialogs wird durch ein Objekt des Typs JDialog realisiert. Es wird in der Methode createGUI() mit allen enthaltenen Komponenten initiiert. Die Erzeugung zweier JComboBox-Objekte zur Auswahl von Schriftfamilie und -größe wird dabei der Übersichtlichkeit halber in eine gesonderte Methode createLists() ausgelagert [39, 79].

Hier wird zunächst das lokale GraphicsEnvironment ermittelt [80]. Es stellt über seine Methode getAvailableFontFamilyNames() ein Array aller Namen der installierten, mit der lokalen Umgebung kompatiblen Schriften bereit [81]. Dieses Array kann direkt der JComboBox als Argument übergeben werden [82]. Um dort auch den Namen der im GUI verwendeten Schriftart anzuzeigen, wird dann die Standardschrift der ComboBox ermittelt und in der Instanzvariablen defaultFont gespeichert [83]. Die Schriftfamilie wird ausgelesen und an der ComboBox voreingestellt [84].
Ähnlich verhält es sich mit den Schriftgrößen. Das benötigte Array wird hier allerdings hart codiert und die Box editierbar gemacht, um die freie Wahl der Schriftgröße zu ermöglichen [90].
Beide ComboBoxen werden schließlich bei einem ItemListener angemeldet. Er ermöglicht es, Änderungen bei der Auswahl zu registrieren [85, 89].

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class Schriftauswahldialog implements ItemListener {

    private JDialog dialog;
    private JComboBox<String> familyList;
    private JComboBox<String> sizeList;
    private JCheckBox weightBox;
    private JCheckBox italicBox;
    private JTextPane textPane;

    private Font newFont;
    private Font defaultFont;

    public Schriftauswahldialog(JFrame frame) {
        createGUI(frame);
        newFont = defaultFont;
    }

    private void createGUI(JFrame frame) {
        dialog = new JDialog(frame, "Schriftauswahl", false);
        createLists();
        weightBox = new JCheckBox("fett");
        weightBox.addItemListener(this);
        italicBox = new JCheckBox("kursiv");
        italicBox.addItemListener(this);
        JButton okButt = new JButton("Ok");
        okButt.addActionListener((e) -> updateFont());
        JButton cancelButt = new JButton("Abbrechen");
        cancelButt.addActionListener((e) -> cancel());

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
        topPanel.add(familyList);
        topPanel.add(sizeList);
        topPanel.add(weightBox);
        topPanel.add(italicBox);

        textPane = new JTextPane();
        textPane.setText("Dies ist ein Beispieltext");
        textPane.setFont(newFont);
        textPane.setPreferredSize(new Dimension(200, 80));

        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
        bottomPanel.add(Box.createHorizontalGlue());
        bottomPanel.add(cancelButt);
        bottomPanel.add(okButt);

        dialog.getRootPane().setBorder(new EmptyBorder(5, 5, 5, 5));
        dialog.setLayout(new BorderLayout(5, 5));
        dialog.add(topPanel, BorderLayout.PAGE_START);
        dialog.add(textPane, BorderLayout.CENTER);
        dialog.add(bottomPanel, BorderLayout.PAGE_END);

        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.pack();
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
    }

    private void createLists() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fontFamilies = ge.getAvailableFontFamilyNames();
        familyList = new JComboBox<String>(fontFamilies);
        defaultFont = familyList.getFont();
        familyList.setSelectedItem(defaultFont.getFamily());
        familyList.addItemListener(this);
        String[] fontSizes = { "8", "9", "10", "11", "12", "13", "14", "16", "18", "20" };
        sizeList = new JComboBox<String>(fontSizes);
        sizeList.setSelectedItem(Integer.toString(defaultFont.getSize()));
        sizeList.addItemListener(this);
        sizeList.setEditable(true);
    }

    private void updateFont() {
        int style = defaultFont.getStyle();
        int size = defaultFont.getSize();
        String family = defaultFont.getFamily();
        if (weightBox.isSelected())
            style |= Font.BOLD;
        if (italicBox.isSelected())
            style |= Font.ITALIC;
        if (weightBox.isSelected() && italicBox.isSelected())
            style |= Font.BOLD & Font.ITALIC;
        if (sizeList.getSelectedItem() != null) {
            size = Integer.parseInt((String) sizeList.getSelectedItem());
        }
        if (familyList.getSelectedItem() != null) {
            family = (String) familyList.getSelectedItem();
        }
        newFont = new Font(family, style, size);
        textPane.setFont(newFont);
    }

    private void cancel() {
        newFont = defaultFont;
        ok();
    }

    private void ok() {
        dialog.setVisible(false);
        dialog.dispose();
        // remove
        System.exit(0);
    }

    public Font getFont() {
        return newFont;
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        updateFont();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Schriftauswahldialog(null));
    }
}

In createGUI() werden im Weiteren noch zwei JCheckBox-Komponenten, eine JTextPane zur Anzeige eines Beispieltextes und zwei Buttons zum Abbruch bzw. zur Bestätigung des Dialogs erzeugt und in einem BorderLayout angeordnet.
Die CheckBoxen werden wie oben beim ItemListener angemeldet, sodass bei Änderungen an diesen vier Komponenten ein neues Font-Objekt gebildet werden kann [109]. Hierzu werden die Auswahlen der Komponenten vorher in Variablen abgelegt. Das Font-Objekt wird an die Vorschaufläche übergeben, sodass der angezeigte Text in der neuen Schrift dargestellt werden kann.
Aus einer Hauptanwendung heraus kann durch getFont() auf die neue Schrift zugegriffen werden [125].

Der Dialog kann durch die zwei Buttons Abbrechen und Ok beendet werden. Der Unterschied besteht darin, dass das Font-Objekt beim Abbruch des Dialogs wieder auf die voreingestellte Schrift zurückgesetzt wird, während bei einer Bestätigung mit Ok das neu erzeugte Font-Objekt übernommen wird.
Die Beendigung der Anwendung durch System.exit(0); [122] ist der Testumgebung geschuldet und sollte vor Verwendung der Klasse in einer Anwendung entfernt werden, um nicht den Abbruch der gesamten Anwendung anzustossen.

Schrift-Auswahldialog

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.