Vous devez être membre et vous identifier pour publier un article.
Les visiteurs peuvent toutefois commenter chaque article par une réponse.
Swing multicolumns ComboBox
Article publié le 21/01/2008 10:43:35ComboBox multi colonnes
Le but de cette astuce est de proposer une boîte de sélection dont l'affichage se fait en plusieurs colonnes.Nous allons utiliser un Renderer qui implémente l’interface ListCellRenderer. Nous devrons donc implémenter la méthode getListCellRendererComponent qui permet de modifier la présentation de la ligne de la liste que comporte la ComboBox.
La solution proposée ici est de placer un Panel qui comportera deux Labels (un pour le code et un pour la description).
Code Java (91 lignes)
package be.mil.cccis.atdl3.util.renderer; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import javax.swing.BoxLayout; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import be.mil.cccis.atdl3.domain.generic.Catalog; /** * Provides custom display for ‹code›be.mil.cccis.atdl3.domain.generic.Catalog‹/code›. * Paints it contents in two columns CODE and DESCRIPTION. * @author gaudry.s */ /** * */ private static final long serialVersionUID = 162343178097966067L; /** * Creates new renderer with first column default size of 50 * */ public CatalogComboBoxRenderer(){ this(50); } /** * Creates a new renderer with custom first column width * @param codeColumnWidth width of the first column */ public CatalogComboBoxRenderer(int codeColumnWidth) { d.width = codeColumnWidth; codeLabel.setMaximumSize(d); codeLabel.setOpaque(true); codeLabel.setHorizontalAlignment(LEFT); codeLabel.setVerticalAlignment(CENTER); descriptionLabel.setOpaque(true); descriptionLabel.setHorizontalAlignment(LEFT); descriptionLabel.setVerticalAlignment(CENTER); rendererPanel.add(codeLabel ); rendererPanel.add(descriptionLabel ); } /* (non-Javadoc) * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean) */ int index, boolean isSelected, boolean cellHasFocus) { if(value==null){ codeLabel.setText(""); descriptionLabel.setText(""); } else { if(value instanceof Catalog){ Catalog item = (Catalog)value; codeLabel.setText( item.getCode() ); descriptionLabel.setText( (index›0 && item.getDescription()!=null)?item.getDescription():"" ); } else{ codeLabel.setText(value.toString()); descriptionLabel.setText(""); } } codeLabel.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground()); codeLabel.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); descriptionLabel.setBackground(list.getBackground()); descriptionLabel.setForeground(list.getForeground()); return rendererPanel; } }
Dans notre exemple, tous les éléments de la ComboBox sont de même type (Catalog) sur lequel nous pouvons demander le code et la description.
Si un des éléments de la ComboBox n’est pas de type Catalog, nous ne pouvons pas demander le code et la description, et nous afficherons donc le résultat de l’appel de la méthode toString() dans le label du code, et une chaîne de caractères vide dans la description.
Nous pouvons à présent déclarer que nous utilisons notre Renderer pour afficher les éléments de notre ComboBox :
Code Java (1 ligne)
myComboBox.setRenderer(new CatalogComboBoxRenderer());
Décorateur
Si nous utilisons une multitude de ComboBoxes dans notre application, nous pouvons utiliser un décorateur, qui effectuera les différentes modifications à apporter à nos ComboBoxes.
Code Java (41 lignes)
package be.mil.cccis.atdl3.util.gui; import javax.swing.JComboBox; import java.util.Date; import be.mil.cccis.atdl3.domain.generic.Catalog; import be.mil.cccis.atdl3.util.renderer.CatalogComboBoxRenderer; import be.mil.cccis.atdl3.util.renderer.DateComboBoxRenderer; /** * Provides an unique point to custom all ATDL comboboxes * All objects in the ‹code›ComboBox‹/code› ‹b›must have the same type‹/p› * * TODO : * To manage other items classes in the combobox, create a new xxxComboBoxRenderer and * set in the decore method the renderer to use for the combobox's items * @author gaudry.s */ public class JComboBoxDecorator { /** * Set comboboxrenderer * @param comboBox ‹code›JComboBox‹/code› to decore */ if(comboBox.getItemCount()›0){ // // Get the first object to test // // // Set one of the renderers // if(firstItem instanceof Catalog){ comboBox.setRenderer(new CatalogComboBoxRenderer()); } comboBox.setRenderer(new DateComboBoxRenderer()); } } } }
Dans l’exemple qui suit, il sert à assigner un Renderer à la boîte de sélection en fonction du type du premier élément contenu. Il est donc nécessaire de s’assurer que l’on fait appel au décorateur après avoir peuplé la ComboBox.
Voici un extrait de code qui montre comment décorer les ComboBoxes :
Code Java (15 lignes)
public void initData() { MVCComboBoxModel‹Operation› operationModel = new MVCComboBoxModel‹Operation›(operations); getView().jComboBoxOperation.setModel(operationModel); JComboBoxDecorator.decore(getView().jComboBoxOperation); getView().jComboBoxOperation.setSelectedIndex(-1); MVCComboBoxModel‹ExecutingAgency› executingAgencyModel = new MVCComboBoxModel‹ExecutingAgency›(executingAgencies); getView().jComboBoxExecutingAgency.setModel(executingAgencyModel); JComboBoxDecorator.decore(getView().jComboBoxExecutingAgency); getView().jComboBoxExecutingAgency.setSelectedIndex(-1); }
Info complémentaire
Pour info, voici la classe Catalog (bien que ce qui nous intéresse soit seulement code et description) :
Code Java (108 lignes)
package be.mil.cccis.atdl3.domain.generic; import org.hibernate.validator.NotNull; /** * Abstract generalization of all catalogues which have a code and a * descritpion.‹br› * Implements Serializable to permit use through the network (eg http) */ public abstract class Catalog extends AbstractDTO implements LogicalDeletionOnly { /** * code of the catalogue item (if it is not specific, it will be equal to * the description). for the extending class CallSign, this attribute has * max 8 chars for the extending class CreditCode, this attribute has max 3 * chars for the extending class FreightType, this attribute has max 6 chars * for the extending class Icao, this attribute has exact 4 chars for the * extending class VIPStatus, this attribute has max 4 chars */ /** * description of the catalogue item. for the extending class Icao, this * attribute has 50 chars for the extending class RequestAndLegPurpose, this * attribute has 50 chars for the extending class RequestAndLegType, this * attribute has 50 chars for the extending class VIPStatus, this attribute * has 50 chars */ /** * boolean for logical delete (=false) */ @NotNull public Catalog() { inUse = true; } /** * @param code * @param description */ this(); this.code = code; this.description = description; } /** * @return the boolean inUse (false : item deleted) */ return inUse; } /** * sets the boolean inUse (false : deleted) * * @param newInUse */ inUse = newInUse; } /** * sets the code of the catalogue item * * @param newCode */ code = newCode; } /** * @return the description of the catalogue item */ /** * sets the description of the catalogue item * * @param newDescription */ description = newDescription; } public int hashCode() { if (getId() != null) return getId(); final int PRIME = 31; int result = 1; result += PRIME * ((code == null) ? 0 : code.hashCode()); } if (inUse) return code; return "‹html›‹strike›" + code + "‹/strike›‹/html›"; } }
Un article de Steph
Source : indéterminée
Version en cache
21/11/2024 09:54:26 Cette version de la page est en cache (à la date du 21/11/2024 09:54:26) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.Document créé le 13/09/2004, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/ast-rf-428.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.