miércoles, 25 de marzo de 2009

Substance, JComboBox, Problema al colocar una fuente en JComboBox

En cierta aplicacion de swing me asignaron implementar el evento enter del teclado para que al dar enter se cambiara de componente en componente de acuerdo a un orden establecido, bien esto lo solucione con keyListeners en los respectivos objetos que se despliegan en la pantalla, pero con el JComboBox tuvimos algunos problemas.
Para empezar un JComboBox esta compuesto por otros objetos (una lista desplegable y una caja de texto), cuando queria agregar el keyLystener lo hacia directo a mi objeto JComboBox y cuando lo ejecutaba pues no se realizaba la accion del enter ya que no estaba dando enter al JComboBox sino a su campo de texto, entonces para solucionar esto añadi el listener a el campo de texto, asi:

JTextComponent editor;
//myJcomboBox es el objeto JComboBox
editor = (JTextComponent) myJcomboBox.getEditor().getEditorComponent();
final ComboBoxEditor cmboxEditor = this.getEditor();
editor.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("KeyAdapter keypressed " + e.getKeyCode() );
}
});

como la aplicacion usa substance para hacer mas amigable la intefaz, cuando la aplicacion despliega algunos JComboBox les coloca un tipo de fuente y al hacer eso y estar utilizando substance podemos decir que se rehacia ese objeto por lo cual los listeners que le colocaba desaparecian, bien para solucionar esto debemos añadir un PropertyChangeListener a el JComboBox :

JComboBox myComboBox = new MyComboBox();
//al colocar la fuente los listeners se pierden
myComboBox.setFont(new Font("Arial",Font.BOLD,12));
//Se coloca final para poder utilizar esta variable dentro de la clase anonima
final JComboBox mycmb = myComboBox;
//Se agrega un PropertyChangeListener para añadir el listener del teclado
myComboBox.addPropertyChangeListener( new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
String property = propertyChangeEvent.getPropertyName();
System.out.println("En property changer " + property);
if ("editor".equals(property)) {
// Si queremos obtener la propiedad editor en este punto
// Obtenemos un nullpointer exception
System.out.println("Entra en property changer " + property);
}
if ("UI".equals(property)) {
System.out.println("Entra en property changer " + property);
System.out.println(mycmb);
//aqui es donde se agrega el listener del teclado
mycmb.getEditor().getEditorComponent()
.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("KeyAdapter keypressed " + e.getKeyCode() );
}
});
}
}
} );

Y asi los listeners que le agrego al combobox ya no se pierden y esta resuelto el problema

Les dejo el codigo que estuve probando pero necesitaran substance aqui esta su link https://substance.dev.java.net/

Y el codigo es el siguiente :

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;import javax.swing.*;
import javax.swing.text.JTextComponent;

public class ExampleJComboBox extends JFrame {
MyComboBox myComboBox;
public ExampleJComboBox() {
String[] names = { "hemanth", "Shawn", "Hunter", "Undertaker", "Big Show" }; myComboBox = new MyComboBox();
myComboBox.setFont(new Font("Arial",Font.BOLD,12));
getContentPane().add(myComboBox, BorderLayout.NORTH);

JButton jbnOk = new JButton("Ok");
getContentPane().add(jbnOk, BorderLayout.SOUTH);
JTextComponent editor;
editor = (JTextComponent) myComboBox.getEditor().getEditorComponent();
final JTextComponent jedit = editor;
editor.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("KeyAdapter keypressed " + e.getKeyCode() ); } });
// Print Name of the Selected Combo Box Item to Console when OK button is pressed
jbnOk.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println( myComboBox.getSelectedItem() ); }
});
// Print Name of the Selected Combo Box Item to Console when Enter is pressed myComboBox.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println( myComboBox.getSelectedItem() );
}
});
final MyComboBox mycmb = myComboBox;
myComboBox.addPropertyChangeListener( new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
String property = propertyChangeEvent.getPropertyName();
System.out.println("En property changer " + property);
if ("editor".equals(property)) {
System.out.println("Entra en property changer " + property);
System.out.println(mycmb);
}
if ("UI".equals(property)) {
System.out.println("Entra en property changer " + property);
System.out.println(mycmb);
mycmb.getEditor().getEditorComponent()
.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("KeyAdapter keypressed " + e.getKeyCode() );
}
});
}
}
}
);
}
class MyComboBox extends JComboBox {
public MyComboBox(){
super( new Object[] {"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
// has to be editable
this.setEditable(true);
// JTextComponent editor;
// editor = (JTextComponent) this.getEditor().getEditorComponent();
// final ComboBoxEditor cmboxEditor = this.getEditor();
// editor.addKeyListener(new KeyAdapter() {
// public void keyPressed(KeyEvent e) {
// System.out.println("KeyAdapter keypressed " + e.getKeyCode() );
// }
// });
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceMistAquaLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
ExampleJComboBox frame = new ExampleJComboBox();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack(); frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
});
}
}

Nota: no olviden agregar substance.jar a su classpath