L'apparence et le comportement ("look and feel" en anglais) des composants Swing d'une application sont modifiables et configurables par le gestionnaire d'apparence et de comportement.
L'apparence et le comportement varient plus largement pour les boîtes de dialogue standards telle celle de l'ouverture de fichiers où les composants utilisés diffèrent :
Apparence de l'application.
Les composants Swing ont une apparence et un comportement ("look and feel" en anglais) modifiables définis par le gestionnaire d'apparence et de comportement.
L'apparence peut ensuite être modifiée pour chaque composant en appelant les méthodes communes :
Les méthodes codice_5 correspondantes existent également permettant d'obtenir la valeur courante.
Le gestionnaire d'apparence et de comportement par défaut est Metal, disponible quel que soit la plateforme.
La classe codice_6 permet de changer l'apparence et le comportement en appelant la méthode codice_7 et en lui passant le nom de la classe implémentant l'apparence et le comportement voulus.
Si l'application effectue un changement, il faut le faire avant la création des fenêtres concernées.
Par exemple dans la méthode main :
protected static String laf_selected = null;
// Sélection par nom de classe
private static boolean selectClass(String classname)
 try
 UIManager.setLookAndFeel(classname);
 laf_selected = classname;
 return true;
 catch (Exception e)
 e.printStackTrace();
 return false;
// Sélection par nom d'affichage, recherche parmi les looks & feels disponibles.
public static boolean select(String name)
 for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels() )
 if (name.equalsIgnoreCase(laf.getName()))
 return selectClass(laf.getClassName());
 return false;
public static void main(String[] args)
 // Choisir l'apparence avant de créer une fenêtre
 select("Nimbus");
 //selectClass(UIManager.getSystemLookAndFeelClassName()); // Apparence de l'OS
 //selectClass(UIManager.getCrossPlatformLookAndFeelClassName()); // Apparence cross-plateforme (Metal)
 EventQueue.invokeLater(new Runnable()
 public void run()
 DemonstrationApparence frame = new DemonstrationApparence();
 frame.setVisible(true);
 });
Si l'application effectue le changement après création des fenêtres, la mise à jour doit se faire explicitement en appelant la méthode statique codice_8 pour chaque fenêtre à mettre à jour en argument.
Aperçu.
Les copies d'écran ci-dessous montrent l'apparence de divers composants Swing selon l'apparence sélectionnée.
Les apparences disponibles dépendent du système d'exploitation sous lequel tourne l'application Java.
L'apparence peut modifier les couleurs, la police de caractère par défaut, la taille, les marges des différents composants.
Par contre, l'apparence du bord de la fenêtre ne change pas.
Sous windows 7 :
L'aspect de tous les composants changent, mais celui du bord de la fenêtre ne change pas par défaut.
Le changement de l'aspect du bord de fenêtre n'est pas supporté par toutes les apparences.
La seule apparence à le supporter est le look&feel Metal.
Pour activer le changement d'apparence de décoration des fenêtres et boîtes de dialogue, il faut appeler ces méthodes (les deux en général) :
JDialog.setDefaultLookAndFeelDecorated(true);
JFrame.setDefaultLookAndFeelDecorated(true);
Ces deux méthodes doivent être appelées avant la création des fenêtres et boîtes de dialogue.
On peut obtenir le même effet sur une fenêtre individuelle :
JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
Pour une boîte de dialogue :
JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
La personnalisation de l'apparence des bords de fenêtres est effectivement géré par JRootPane, dans une fenêtre sans décoration.
Si le changement d'apparence de décoration des fenêtres et boîtes de dialogue est activé avec une apparence qui ne le supporte pas, la fenêtre n'a plus de bord.
L'apparence peut être configurée avant la création de fenêtre.
Par exemple, il est possible de désactiver les polices en gras de l'apparence Metal :
UIManager.put("swing.boldMetal", Boolean.FALSE);
Code source.
Le code source ci-dessous est celui de l'application ayant permis les captures d'écrans de ce chapitre.
package org.wikibooks.fr.swing;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 * Démonstration du changement d'apparence. 
 * @author fr.wikibooks.org
public class DemonstrationApparence extends JFrame
 private String[] laf_classnames;
 private String[] laf_names;
 private int index_cross_platform = -1;
 private int index_system = -1;
 private int index_selected = -1;
 private void changerApparence(int index)
 if (index != index_selected)
 index_selected = index;
 if (selectClass(laf_classnames[index]))
 SwingUtilities.updateComponentTreeUI(this);
 else
 JOptionPane.showMessageDialog(this,
 "Impossible de changer l'apparence à "+laf_names[index],
 "Erreur", JOptionPane.ERROR_MESSAGE);
 public DemonstrationApparence()
 // Lister les apparences disponibles
 UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
 laf_classnames = new String[lafs.length];
 laf_names = new String[lafs.length];
 String laf_system = UIManager.getSystemLookAndFeelClassName();
 String laf_cross_platform = UIManager.getCrossPlatformLookAndFeelClassName();
 index_selected = -1;
 for(int i=0 ; i<lafs.length ; i++)
 UIManager.LookAndFeelInfo laf = lafs[i];
 String classname = laf.getClassName();
 laf_classnames[i] = classname;
 laf_names[i] = laf.getName();
 if (laf_selected!=null && laf_selected.equals(classname))
 index_selected = i;
 if (laf_system.equals(classname))
 index_system = i;
 if (laf_cross_platform.equals(classname))
 index_cross_platform = i;
 if (laf_selected==null) index_selected = i;
 // Création de la fenêtre
 setTitle("Démonstration de l'apparence des composants Swing");
 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 Dimension d = new Dimension(450, 440);
 setMinimumSize(d);
 setSize(d);
 Container c = getContentPane();
 c.setLayout(new BorderLayout());
 JPanel p_main = new JPanel();
 p_main.setLayout(new BoxLayout(p_main, BoxLayout.Y_AXIS));
 p_main.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
 c.add(p_main, BorderLayout.WEST);
 JLabel l_apparence = new JLabel("Choisissez l'apparence :");
 p_main.add(l_apparence);
 // Un seul bouton radio appartenant au groupe ne pourra être sélectionné
 ButtonGroup group = new ButtonGroup();
 JRadioButton rb_sel = null;
 for(int i=0 ; i<lafs.length ; i++)
 String name = laf_names[i];
 if (i==index_cross_platform) name = name+" (Cross-platform)";
 if (i==index_system) name = name+" (System)";
 JRadioButton rb = new JRadioButton(name);
 p_main.add(rb);
 group.add(rb);
 if (i == index_selected) rb_sel = rb;
 final int rb_index = i;
 rb.addItemListener(new ItemListener()
 @Override
 public void itemStateChanged(ItemEvent e)
 if (rb.isSelected())
 changerApparence(rb_index);
 });
 if (rb_sel!=null) rb_sel.setSelected(true);
 JPanel p_comp = new JPanel();
 p_comp.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
 p_comp.setLayout(new BoxLayout(p_comp, BoxLayout.Y_AXIS));
 c.add(p_comp, BorderLayout.CENTER);
 // Quelques composants pour montrer leur apparence
 // espacés de 10 pixels verticalement
 p_comp.add(new JCheckBox("Case à cocher"));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JSpinner(new SpinnerNumberModel(50, 0, 100, 1)));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JComboBox<String>(new String[]{"Choix 1", "Choix 2", "Choix 3"}));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JTextField("Champ de saisie"));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JScrollPane(new JTextArea("Zone de saisie\nSur plusieurs lignes\n1 2 3 4 5 6 7 8 9\n...")));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JButton("Un bouton"));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JToggleButton("Un bouton basculable"));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(new JScrollPane(new JTable(
 new Object[][]
 { "pi", 3.14159, true },
 { "phi", 1.61803, false },
 { "e", 2.71828, true },
 { "square root of 2", 1.41421, false },
 { "square root of 3", 1.73205, false },
 { "square root of 5", 2.23607, false },
 { "square root of 7", 2.64575, false },
 new Object[]{ "Nom", "Valeur", "Utiliser" })));
 p_comp.add(Box.createVerticalStrut(10));
 p_comp.add(Box.createVerticalGlue());
 protected static String laf_selected = null;
 private static boolean selectClass(String classname)
 try
 UIManager.setLookAndFeel(classname);
 laf_selected = classname;
 return true;
 catch (Exception e)
 e.printStackTrace();
 return false;
 public static boolean select(String name)
 for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels() )
 if (name.equalsIgnoreCase(laf.getName()))
 return selectClass(laf.getClassName());
 return false;
 public static void main(String[] args)
 // Choisir l'apparence avant de créer une fenêtre
 select("Nimbus");
 //selectClass(UIManager.getSystemLookAndFeelClassName());
 //selectClass(UIManager.getCrossPlatformLookAndFeelClassName());
 EventQueue.invokeLater(new Runnable()
 public void run()
 DemonstrationApparence frame = new DemonstrationApparence();
 frame.setVisible(true);
 });