2009-06-25 4 views
0

Ich habe eine Liste von Customer Objekte, die ich auswählbar von einer JComboBox haben muss. Von dem, was ich lese, muss ich einen benutzerdefinierten Renderer implementieren, um die Felder zu haben, die ich in der Liste anzeigen möchte.Java JComboBox Custom Renderer und GTK

Ich möchte meine JComboBox Einträge als solche formatiert haben:

+----------------------------------------------+ 
| Customer Name - Contact - City, State V | 
+==============================================+ 
| Customer #2 Name - Contact - City, State | 
| Customer #3 Name - Contact - City, State | 
| Customer #4 Name - Contact - City, State | 
| Customer #5 Name - Contact - City, State | 
+----------------------------------------------+ 

ich diesen Code verwendet:

public class CustomerListCellRenderer DefaultListCellRenderer erstreckt {

@Override 
public Component getListCellRendererComponent(
     JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 
    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
    if (value instanceof Customer) { 
     Customer c = (Customer) value; 

     StringBuffer sb = new StringBuffer(); 
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getCompany()); 
     } 
     sb.append(" - "); 
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getContact()); 
     } 
     sb.append(" - "); 
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getCity()); 
      sb.append(", "); 
     }    
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getState()); 
     } 

     setText(sb.toString()); 
    } 
    return this; 
    } 
} 

Das ist nicht richtig funktioniert unter Solaris/Unix/Linux mit dem System GTKLookAndFeel. Der Hintergrund des Eingabebereichs der Combobox wird nicht gezeichnet und es wird kein Rahmen um ihn gezeichnet. (Siehe Screenshot unten). Gibt es einen anderen Weg, dies zu erreichen, der auf den 3 Hauptplattformen (Win/Mac/GTK) korrekt funktioniert? Kann ich einen Konverter dafür machen und nur die Daten manipulieren, nicht die GUI?

Meine aktuelle Problemumgehung besteht darin, toString() auf meinem Customer-Objekt zu überschreiben, um jeden Datensatz im gewünschten Format anzuzeigen, aber nach anderen Ideen suchen.

alt text http://i40.tinypic.com/5dw1hd.jpg

Nick

+0

Ich sehe keinen Grund, warum Sie einen benutzerdefinierten Renderer für dieses Beispiel benötigen würden. –

+1

@ammoQ: Sie benötigen es, weil Sie einen Kunden in Ihrem ComboBoxModel speichern möchten, und kein String. Also, wenn Sie tun: getSelectedItem(), erhalten Sie einen Kunden und keine Zeichenfolge. –

Antwort

2

gleiches Problem, ich tat dies, um es zu zeigen Symbole anpassen:

private static class CustomComboBoxRenderer extends DefaultListCellRenderer 
{ 
    private final ListCellRenderer backend; 

    public CustomComboBoxRenderer(ListCellRenderer backend) 
    { 
     this.backend = backend; 
    } 

    @Override 
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
    { 
     Component component = backend.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
     if(component instanceof JLabel == false) 
      component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
     JLabel label = (JLabel)component; 
     label.setIcon(Icons.COMPONENT); 
     return label; 
    } 
} 

Dann die Renderer wie folgt zugewiesen:

comboBox.setRenderer(new CustomComboBoxRenderer(comboBox.getRenderer())); 

Das ist für mich in Ordnung heraus gearbeitet hat, so weit .

0

Die DefaultListCellRenderer erstreckt JLabel und sieht aus wie JLabel. Wenn Sie eine nicht editierbare ComboBox haben, dann wird der Renderer, der über getRenderer zurückgegeben wird, zum Zeichnen des Dropdown-Listenbereichs und auch für den Bereich "Eingabe" verwendet. Versuchen Sie, mit den Rahmen-/Vordergrund-/Hintergrundeinstellungen für ComboBox und Renderer zu spielen.

1

Versuchen Sie folgendes:

public Component getListCellRendererComponent(
     JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 
    if (value instanceof Customer) { 
     Customer c = (Customer) value; 

     StringBuffer sb = new StringBuffer(); 
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getCompany()); 
     } 
     sb.append(" - "); 
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getContact()); 
     } 
     sb.append(" - "); 
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getCity()); 
      sb.append(", "); 
     }    
     if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getState()); 
     } 

     value = sb.toString(); 
    } 
    return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
    } 
} 

auch einen String verwendet kein String (dies ist eine Single-Threaded-Situation).

Auch auch sieht es aus wie Sie abgeschnitten haben und Fehler im Code zum Beispiel einfügen:

 if (c.getCompany() != null && c.getCompany().length() > 0) { 
      sb.append(c.getState()); 
     } 

ist das Unternehmen Mitglied überprüft und den Staat Element verwendet.