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
English translation
You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.
Thank you in advance.
Document created the 13/09/2004, last modified the 26/10/2018
Source of the printed document:https://www.gaudry.be/en/ast-rf-428.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.