viernes, 8 de abril de 2011

El Look and Feel (L&F) de Swing, cambiar el look and feel de la aplicación

Tal y como está diseñado Swing, puedes cambiar el "look and feel" (L&F) de nuestras interfaces. "Look" se refiere a la apariencia de los componentes, "feel" se refiere a la manera en que se comportan estos.


Cada componente Swing se divide en dos clases distintas, una subclase de JComponent y otra subclase de ComponentUI. Por ejemplo un JButton tiene una implementación concreta de ButtonUI.


Veamos ahora varios ejemplos de como cambiar el look and feel de nuestra aplicación:


Programáticamente

 Para especificarlo haremos uso del método UIManager.setLookAndFeel() con el nombre completo de una subclase de LookAndFeel y los argumentos apropiados. P ej.
public static void main(String[] args) {
try {
// Establecemos el look and feel "Metal"
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} 
catch (UnsupportedLookAndFeelException e) {
// manejar excepción
}
catch (ClassNotFoundException e) {
// manejar excepción
}
catch (InstantiationException e) {
// manejar excepción
}
catch (IllegalAccessException e) {
// manejar excepción
}

new SwingApplication(); //Creamos y mostramos la interfaz de usuario
}

Por línea de comandos

Podemos especificar el L&F por línea de comandos usando el flag -D para establecer la propiedad swing.defaultlaf: P ej.

java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel MyApp

Archivo swing.properties

Otra manera es cambiar el swing.properties, es posible que tengamos que crear este archivo. Suele estar ubicado en la carpeta lib de nuestro intérprete de Java.

# Swing properties
swing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel

Despues del inicio de la aplicación

Se puede cambiar el aspecto de la aplicación incluso despues de haber hecho visible la ventana. Para ahcer efectivo el cambio, deberemos llamar al método updateComponentTreeUI de SwingUtilities por cada contenedor de alto nivel. P ej.

UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();

Para hacer esto algo más gráfico aquí os dejo el código de una aplicación de ejemplo para cambiar el Look and Feel tras iniciar la aplicación.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LookAndFeelDemo {

 static JFrame frame;
 JLabel label;
 JComboBox combo;

 public Component createComponents() {

  label = new JLabel("Selecciona un L&F");
  combo = new JComboBox();

  // Añado elementos al combo
  combo.addItem("Metal");
  combo.addItem("Nimbus");
  combo.addItem("Windows");
  combo.addItem("Motif");

  combo.addActionListener(new ActionListener() {

   @Override
   public void actionPerformed(ActionEvent e) {
    initLookAndFeel(combo.getSelectedItem().toString());
   }
  });

  label.setLabelFor(combo);

  JPanel pane = new JPanel(new GridLayout(0, 1));
  pane.add(label);
  pane.add(combo);
  pane.setBorder(BorderFactory.createEmptyBorder(30, // top
  30, // left
  10, // bottom
  30) // right
  );

  return pane;
 }

 private static void initLookAndFeel(String LaF) {
  String lookAndFeel = null;

  if (LaF != null) {
   if (LaF.equals("Metal")) {
    lookAndFeel = "javax.swing.plaf.metal.MetalLookAndFeel";
   } else if (LaF.equals("Nimbus")) {
    lookAndFeel = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";
   } else if (LaF.equals("Windows")) {
    lookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
   } else if (LaF.equals("Motif")) {
    lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
   } else {
    lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
   }

   try {
    UIManager.setLookAndFeel(lookAndFeel);
    SwingUtilities.updateComponentTreeUI(frame);
    frame.pack();
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   } catch (UnsupportedLookAndFeelException e) {
    e.printStackTrace();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

 /**
  * Create the GUI and show it. For thread safety,
  * this method should be invoked from the
  * event dispatch thread.
  */
 private static void createAndShowGUI() {
  // Make sure we have nice window decorations.
  JFrame.setDefaultLookAndFeelDecorated(true);

  // Create and set up the window.
  frame = new JFrame("Look And Feel Demo");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  LookAndFeelDemo app = new LookAndFeelDemo();
  Component contents = app.createComponents();
  frame.getContentPane().add(contents, BorderLayout.CENTER);

  // Display the window.
  frame.pack();
  frame.setLocationByPlatform(true);
  frame.setVisible(true);
 }

 public static void main(String[] args) {
  // Schedule a job for the event dispatch thread:
  // creating and showing this application's GUI.
  javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    createAndShowGUI();
   }
  });
 }
}

3 comentarios:

Anónimo dijo...

excelente encontrar ayuda por este tema, estoy comenzando a programar en java
Saludos
Arturo

Unknown dijo...

Muchas gracias Arturo.
Me alegro de que te haya sido de ayuda.

Saludos

Unknown dijo...

quisiera saber si se puede perzonalizar con algun codigo como CCS

Publicar un comentario