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

Astuces de l’Infobrol (Java)Article publié le 21/01/2008 10:43:35


ComboBox 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).

  1. package be.mil.cccis.atdl3.util.renderer;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Component;
  5. import java.awt.Dimension;
  6. import java.awt.Font;
  7.  
  8. import javax.swing.BoxLayout;
  9. import javax.swing.JLabel;
  10. import javax.swing.JList;
  11. import javax.swing.JPanel;
  12. import javax.swing.ListCellRenderer;
  13.  
  14. import be.mil.cccis.atdl3.domain.generic.Catalog;
  15. /**
  16.  * Provides custom display for ‹code›be.mil.cccis.atdl3.domain.generic.Catalog‹/code›.
  17.  * Paints it contents in two columns CODE and DESCRIPTION.
  18.  * @author gaudry.s
  19.  */
  20. public class CatalogComboBoxRenderer extends JLabel implements ListCellRenderer {
  21.  
  22. /**
  23. *
  24. */
  25. private static final long serialVersionUID = 162343178097966067L;
  26. private JPanel rendererPanel;
  27. private JLabel codeLabel;
  28. private JLabel descriptionLabel;
  29. /**
  30. * Creates new renderer with first column default size of 50
  31. *
  32. */
  33. public CatalogComboBoxRenderer(){
  34. this(50);
  35. }
  36. /**
  37. * Creates a new renderer with custom first column width
  38. * @param codeColumnWidth width of the first column
  39. */
  40. public CatalogComboBoxRenderer(int codeColumnWidth)
  41. {
  42. rendererPanel = new JPanel();
  43. rendererPanel.setLayout(new BoxLayout(rendererPanel, BoxLayout.X_AXIS) );
  44.  
  45. codeLabel = new JLabel(" ");
  46. Dimension d = codeLabel.getPreferredSize();
  47. d.width = codeColumnWidth;
  48. codeLabel.setMaximumSize(d);
  49. codeLabel.setOpaque(true);
  50. codeLabel.setHorizontalAlignment(LEFT);
  51. codeLabel.setVerticalAlignment(CENTER);
  52.  
  53. descriptionLabel = new JLabel();
  54. descriptionLabel.setForeground(Color.gray);
  55. descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.ITALIC));
  56. descriptionLabel.setOpaque(true);
  57. descriptionLabel.setHorizontalAlignment(LEFT);
  58. descriptionLabel.setVerticalAlignment(CENTER);
  59.  
  60. rendererPanel.add(codeLabel );
  61. rendererPanel.add(descriptionLabel );
  62. }
  63.  
  64. /* (non-Javadoc)
  65. * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean)
  66. */
  67. public Component getListCellRendererComponent(JList list, Object value,
  68. int index, boolean isSelected, boolean cellHasFocus) {
  69. if(value==null){
  70. codeLabel.setText("");
  71. descriptionLabel.setText("");
  72. }
  73. else {
  74. if(value instanceof Catalog){
  75. Catalog item = (Catalog)value;
  76. codeLabel.setText( item.getCode() );
  77. descriptionLabel.setText( (index›0 && item.getDescription()!=null)?item.getDescription():"" );
  78. }
  79. else{
  80. codeLabel.setText(value.toString());
  81. descriptionLabel.setText("");
  82. }
  83. }
  84. codeLabel.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
  85. codeLabel.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
  86. descriptionLabel.setBackground(list.getBackground());
  87. descriptionLabel.setForeground(list.getForeground());
  88. return rendererPanel;
  89. }
  90.  
  91. }


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 :
  1. 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.

  1. package be.mil.cccis.atdl3.util.gui;
  2.  
  3. import javax.swing.JComboBox;
  4. import java.util.Date;
  5. import be.mil.cccis.atdl3.domain.generic.Catalog;
  6. import be.mil.cccis.atdl3.util.renderer.CatalogComboBoxRenderer;
  7. import be.mil.cccis.atdl3.util.renderer.DateComboBoxRenderer;
  8.  
  9. /**
  10.  * Provides an unique point to custom all ATDL comboboxes
  11.  * All objects in the ‹code›ComboBox‹/code› ‹b›must have the same type‹/p›
  12.  *
  13.  * TODO :
  14.  * To manage other items classes in the combobox, create a new xxxComboBoxRenderer and
  15.  * set in the decore method the renderer to use for the combobox's items
  16.  * @author gaudry.s
  17.  */
  18. public class JComboBoxDecorator {
  19.  
  20. /**
  21. * Set comboboxrenderer
  22. * @param comboBox ‹code›JComboBox‹/code› to decore
  23. */
  24. public static void decore(JComboBox comboBox){
  25. if(comboBox.getItemCount()›0){
  26. //
  27. // Get the first object to test
  28. //
  29. Object firstItem = comboBox.getItemAt(0);
  30. //
  31. // Set one of the renderers
  32. //
  33. if(firstItem instanceof Catalog){
  34. comboBox.setRenderer(new CatalogComboBoxRenderer());
  35. }
  36. else if(firstItem instanceof Date){
  37. comboBox.setRenderer(new DateComboBoxRenderer());
  38. }
  39. }
  40. }
  41. }


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 :
  1. @SuppressWarnings("unchecked")
  2. public void initData() {
  3. List‹Operation› operations = taskerRepository.getOperations();
  4. MVCComboBoxModel‹Operation› operationModel = new MVCComboBoxModel‹Operation›(operations);
  5. getView().jComboBoxOperation.setModel(operationModel);
  6. JComboBoxDecorator.decore(getView().jComboBoxOperation);
  7. getView().jComboBoxOperation.setSelectedIndex(-1);
  8.  
  9. List‹ExecutingAgency› executingAgencies = taskerRepository.getExecutingAgencies();
  10. MVCComboBoxModel‹ExecutingAgency› executingAgencyModel = new MVCComboBoxModel‹ExecutingAgency›(executingAgencies);
  11. getView().jComboBoxExecutingAgency.setModel(executingAgencyModel);
  12. JComboBoxDecorator.decore(getView().jComboBoxExecutingAgency);
  13. getView().jComboBoxExecutingAgency.setSelectedIndex(-1);
  14. }


Info complémentaire


Pour info, voici la classe Catalog (bien que ce qui nous intéresse soit seulement code et description) :
  1. package be.mil.cccis.atdl3.domain.generic;
  2.  
  3. import org.hibernate.validator.NotNull;
  4.  
  5. /**
  6.  * Abstract generalization of all catalogues which have a code and a
  7.  * descritpion.‹br›
  8.  * Implements Serializable to permit use through the network (eg http)
  9.  */
  10. public abstract class Catalog extends AbstractDTO implements LogicalDeletionOnly {
  11. /**
  12. * code of the catalogue item (if it is not specific, it will be equal to
  13. * the description). for the extending class CallSign, this attribute has
  14. * max 8 chars for the extending class CreditCode, this attribute has max 3
  15. * chars for the extending class FreightType, this attribute has max 6 chars
  16. * for the extending class Icao, this attribute has exact 4 chars for the
  17. * extending class VIPStatus, this attribute has max 4 chars
  18. */
  19. protected String code;
  20.  
  21. /**
  22. * description of the catalogue item. for the extending class Icao, this
  23. * attribute has 50 chars for the extending class RequestAndLegPurpose, this
  24. * attribute has 50 chars for the extending class RequestAndLegType, this
  25. * attribute has 50 chars for the extending class VIPStatus, this attribute
  26. * has 50 chars
  27. */
  28. protected String description;
  29.  
  30. /**
  31. * boolean for logical delete (=false)
  32. */
  33. @NotNull
  34. protected Boolean inUse;
  35.  
  36. public Catalog() {
  37. inUse = true;
  38. }
  39.  
  40. /**
  41. * @param code
  42. * @param description
  43. */
  44. public Catalog(String code, String description) {
  45. this();
  46. this.code = code;
  47. this.description = description;
  48. }
  49.  
  50. /**
  51. * @return the boolean inUse (false : item deleted)
  52. */
  53. public Boolean isInUse() {
  54. return inUse;
  55. }
  56.  
  57. /**
  58. * sets the boolean inUse (false : deleted)
  59. *
  60. * @param newInUse
  61. */
  62. public void setInUse(Boolean newInUse) {
  63. inUse = newInUse;
  64. }
  65.  
  66. public abstract String getCode();
  67.  
  68. /**
  69. * sets the code of the catalogue item
  70. *
  71. * @param newCode
  72. */
  73. public void setCode(String newCode) {
  74. code = newCode;
  75. }
  76.  
  77. /**
  78. * @return the description of the catalogue item
  79. */
  80. public abstract String getDescription();
  81.  
  82. /**
  83. * sets the description of the catalogue item
  84. *
  85. * @param newDescription
  86. */
  87. public void setDescription(String newDescription) {
  88. description = newDescription;
  89. }
  90.  
  91. public int hashCode() {
  92. if (getId() != null) return getId();
  93.  
  94. final int PRIME = 31;
  95. int result = 1;
  96. result += PRIME * ((code == null) ? 0 : code.hashCode());
  97.  
  98. return (result == 1) ? System.identityHashCode(this): result;
  99. }
  100.  
  101. public String toString() {
  102. if (inUse)
  103. return code;
  104. return "‹html›‹strike›" + code + "‹/strike›‹/html›";
  105. }
  106. }


Avatar :: Steph Un article de Steph

Source : indéterminée


Sélection, tri et recherche d'articles
FILTRER :
TRIER :1er critère : 2e critère :
CHERCHER : Dans les titres Dans le contenu


[Afficher les liens en fonction des critères du formulaire ci-dessus]

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.