Für das 'Metal'-Look And Feel können verschiedene Themes, d.h. Farb- und Schrift-Zuweisungen bestimmt werden.

Um ein Maximum an Kompatibilität mit verschiedenen Plattformen zu gewährleisten und die Belange der Barrierefreiheit zu berücksichtigen empfiehlt Oracle, die Erscheinung des MetalTheme nicht ohne zwingenden Grund zu ändern. Dennoch kann es Gründe geben, die vorgegebene Erscheinungsweise abzuändern, etwa um nativen Farbvorgaben zu folgen oder auch um auf Notwendigkeiten der Handhabung (z.B. gesteigerte Lesbarkeit) einzugehen.
Die hier vorgestellten Themes dienen somit ausschließlich zu Demonstrationszwecken und sind nicht als ernsthafte Verwendungsalternative zu verstehen.

Der vorgestellte Quelltext orientiert sich am Beispiel swing/Look And Feel und ist nur um einen weiteren Button und die Methode updateTheme() erweitert. Die Methode updateLAF() wurde insofern angepasst, als bei Auswahl des Metal Look And Feel der Button zur Auswahl der Themes aktiviert wird und anschliessend der entsprechende Methodenaufruf zur Aktualisierung des Themes erfolgt.

Analog zur Auswahl des Look And Feel wird beim Klicken auf den Button zur Änderung des Themes eine int-Instanzvariable incrementiert. Die Methode updateTheme() liest diese aus und bildet entsprechende Theme-Objekte. Über die statische Methode MetalLookAndFeel.setCurrentTheme(MetalTheme theme) wird dem aktuellen Look And Feel das gewählte Theme übergeben und der Komponentenbaum des Frames durch SwingUtilities.updateComponentTreeUI(Component c) neu gezeichnet.

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.metal.DefaultMetalTheme;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.OceanTheme;

import swing.BonbonTheme;
import swing.DeepBlueTheme;

public class ThemeDemo implements ActionListener {

    private final JFrame frame;
    private JLabel label;
    private JButton lfButton, themeButton;
    private JTextArea area;
    private JScrollPane pane;
    private int lAF = 1, themeNr = 1;
    private DefaultMetalTheme theme;
    private JMenuItem exit;

    public ThemeDemo() {
        frame = new JFrame("Theme-Demo");
        initComponents();
        updateLAF();
    }

    private void initComponents() {
        if(frame == null) {
            System.err.println("Frame is not initialized");
            System.exit(1);
        }
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Datei");
        exit = new JMenuItem("exit");
        exit.addActionListener(this);
        menu.add(exit);
        menuBar.add(menu);
        lfButton = new JButton("L & F");
        lfButton.addActionListener(this);
        themeButton = new JButton("Theme");
        themeButton.addActionListener(this);
        label = new JLabel();
        area = new JTextArea();
        pane = new JScrollPane(area, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        JPanel buttPanel = new JPanel(new FlowLayout());
        buttPanel.add(lfButton);
        buttPanel.add(themeButton);

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30));

        mainPanel.add(label, BorderLayout.NORTH);
        mainPanel.add(pane, BorderLayout.CENTER);
        mainPanel.add(buttPanel, BorderLayout.SOUTH);

        frame.add(menuBar, BorderLayout.NORTH);
        frame.add(mainPanel, BorderLayout.CENTER);
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private void updateLAF() {
        try {
            String plaf = "";
            themeButton.setEnabled(false);
            label.setText(" L & F Nr.: " + new Integer(lAF).toString());
            if (lAF == 1) {
                themeButton.setEnabled(true);
                return;
            } else if (lAF == 2) {
                plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
            } else if (lAF == 3) {
                plaf = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
            } else if (lAF == 4) {
                plaf = UIManager.getSystemLookAndFeelClassName();
            }

            UIManager.setLookAndFeel(plaf);
            setText(UIManager.getLookAndFeel().getName());
            SwingUtilities.updateComponentTreeUI(frame);

        } catch (UnsupportedLookAndFeelException ue) {
            System.err.println(ue.toString());
        } catch (ClassNotFoundException ce) {
            System.err.println(ce.toString());
        } catch (InstantiationException ie) {
            System.err.println(ie.toString());
        } catch (IllegalAccessException iae) {
            System.err.println(iae.toString());
        }
    }

    private void updateTheme() {
        switch (themeNr) {
        case 1:
            theme = new DeepBlueTheme();
            break;
        case 2:
            theme = new BonbonTheme();
            break;
        case 3:
            theme = new DefaultMetalTheme();
            break;
        case 4:
            theme = new OceanTheme();
            break;
        }
        
        MetalLookAndFeel.setCurrentTheme(theme);
        try {
            UIManager.setLookAndFeel(new MetalLookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        setText(UIManager.getLookAndFeel().getName() + "\nTheme: "
                + theme.getName());
        SwingUtilities.updateComponentTreeUI(frame);

    }

    private void setText(String text) {
        area.setText(text);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == lfButton) {
            lAF++;
            if (lAF > 4)
                lAF = 1;
            updateLAF();
        }
        if (e.getSource() == themeButton) {
            themeNr++;
            if (themeNr > 4)
                themeNr = 1;
            updateTheme();
        }
        if (e.getSource() == exit) {
            System.exit(0);
        }
    }

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

Die folgende Abbildung zeigt 4 Themes des Metal Look And Feels unter Mac OS X.

4 Themes des Metal Look And Feels

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