JTable jCombobox erscheint erst nach Klick

Hallo Leute, liebe neue Gemeinde

Ich habe eine jTable wobei ich teilweise Columns mit jComboboxen gefüllt habe.

Es funktioniert alles, nur das Problem ist, dass die JComboboxen erst ersichtlich sind, nachdem man einmal drauf geklickt hat. Ich möchte aber gerne, dass die Columns sofort als jComboboxen ersichtlich sind. Wie funktioniert das bitte?

Ja das wars schon
Schönen Tag

Mfg
Paul

was hast du denn bisher alles an Editor/ Renderer gesetzt?
ist der Editor eine JComboBox, der Renderer JLabel, dann sicherlich verständlich

‘jtable jcombobox renderer’
liefert das alte Forum als 1. Suchergebnis…,
dahinter aber z.B.
http://www.coderanch.com/t/332156/GUI/java/JComboBox-Cell-renderer-JTable

oder auch
http://www.java2s.com/Tutorial/Java/0240__Swing/UsingaJComboBoxinaCellinaJTableComponent.htm
wobei das ein komisches Komplettbeispiel ohne JFrame ist,
mehrere Zeilen in der Table täten der Anschaulichkeit auch gut:

    public static void main(String[] argv) throws Exception {
      JTable table = new JTable();
      DefaultTableModel model = (DefaultTableModel) table.getModel();

      model.addColumn("A", new Object[] { "1", "2","3" });
      model.addColumn("B", new Object[] { "item2","item2","item2",  });

      String[] values = new String[] { "1", "2", "3" };

      TableColumn col = table.getColumnModel().getColumn(0);
      col.setCellEditor(new MyComboBoxEditor(values));
      col.setCellRenderer(new MyComboBoxRenderer(values));
      
      JFrame f = new JFrame();
      JScrollPane sp = new JScrollPane(table);
      f.add(sp);
      f.setSize(300,300);
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setVisible(true);
    }

Danke für die schnelle Antwort, natürlich habe ich mit komplett anderen Suchwörter bei google gesucht.

Also hier mal ein bisschen code:

    {
        Object data[][] = new Object[anzahlWertungsklassen][8];
        ArrayList<Object> faktorenEinerWertungsklasse = null;
        for(int i=0; i<anzahlWertungsklassen;i++)
        {
            String stringI = String.valueOf(i+1);
            faktorenEinerWertungsklasse = 
            controller.getSqlFunctions().getExecuteQueryArrayList(
            "select FAKTOR_GESAMT_WERTUNGSKLASSE".concat(stringI).concat("_Runde1")
            .concat(",FAKTOR_MINI_WERTUNGSKLASSE").concat(stringI).concat("_Runde1")
            .concat(",FAKTOR_KINDER_WERTUNGSKLASSE").concat(stringI).concat("_Runde1")
            .concat(",FAKTOR_JUNIOREN1_WERTUNGSKLASSE").concat(stringI).concat("_Runde1")
            .concat(",FAKTOR_JUNIOREN2_WERTUNGSKLASSE").concat(stringI).concat("_Runde1")
            .concat(",FAKTOR_ALLGK_WERTUNGSKLASSE").concat(stringI).concat("_Runde1")
            .concat(",EINHEITLICH_WERTUNGSKLASSE").concat(stringI).concat("_Runde1")
            .concat(",AUSGEWAEHLTEWERTUNGSKLASSE").concat("_Runde1")                    
            .concat(" from disziplinFaktoren where disziplin_name='")
            .concat(disziplin).concat("'"));        

            DecimalFormat f = new DecimalFormat("#0.00");
     
            //Runde1 (In der Datenbank sind alle Faktoren als DOUBLE gespeichert)
            data**[0] = wertungsklassenOrderByWertungsklassenname.get(i);
            data**[1] = f.format(faktorenEinerWertungsklasse.get(0));
            data**[2] = f.format(faktorenEinerWertungsklasse.get(1));
            data**[3] = f.format(faktorenEinerWertungsklasse.get(2));
            data**[4] = f.format(faktorenEinerWertungsklasse.get(3));
            data**[5] = f.format(faktorenEinerWertungsklasse.get(4));
            data**[6] = f.format(faktorenEinerWertungsklasse.get(5));
            data**[7] = faktorenEinerWertungsklasse.get(6);             
        }
        ausgewaehlteWertungsklasse_Runde1 = faktorenEinerWertungsklasse.get(7).toString();        
        
        setDtmStatistikRunde1(data);
    }    
    public void setDtmStatistikRunde1(Object[][] data) {
        dtmStatistikRunde1 = new StatistikRunde1_TableModel(controller, data);
        notifyObser();
    }

public class StatistikRunde1_TableModel extends DefaultTableModel 
                    implements javax.swing.event.TableModelListener{

    private Controller controller;
    String[] COL_IDENTIFIER_Statistik = 
        {"Wertungsklasse","Gesamt","Mini","Kinder","Junioren1","Junioren2",
            "AllgK","Einheitlich"};
    
    public StatistikRunde1_TableModel(Controller controller,Object[][] data) {
        this.controller = controller;       
        
        setDataVector(data, COL_IDENTIFIER_Statistik);
        this.addTableModelListener(this);
    }

    @Override
    public Object getValueAt(int row, int column) {
        return super.getValueAt(row, column);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        if(columnIndex == 7)
            return Boolean.class;
        return super.getColumnClass(columnIndex);
    }        

    @Override
    public boolean isCellEditable(int row, int column) {
        if(getValueAt(row, 7).toString().equals("true"))
        {
            //Darf nur Gesamt und Einheitlich verändern
            return column == 1 || column == 7;
        }else
        {
            return column > 1;
        }
    }

    @Override
    public void tableChanged(TableModelEvent e) {     
//HIER wird noch nichts gemacht!  
        int row = e.getFirstRow();
        int column = e.getColumn();

        TableModel model = (TableModel)e.getSource();
        //String columnName = model.getColumnName(column);
        Object auszeichnungsName = model.getValueAt(row, 0);
        Object wert = model.getValueAt(row, column);

    }
    
}

private StatistikRunde1_TableModel  dtmStatistikRunde1;
public static void main(String[] argv) throws Exception {
 JTable table = new JTable();
 setDtmStatistikRunde1("Alle Disziplinen");
table.setmodel(dtmStatistikRunde1);

            for(int z=1; z<=6; z++)
            {
                TableColumn eineColumn = jTable_StatistikRunde1
                        .getColumnModel().getColumn(z);
                JComboBox comboBox = new JComboBox();

                for(String einFaktor : controller.getModel().getFaktorenFuerJCombobox())
                {
                    comboBox.addItem(einFaktor);
                }
                eineColumn.setCellEditor(new DefaultCellEditor(comboBox));
            } 
}

Wenn der Code irgendwo Schreibfehler enthält tut mir leid, habe es jetzt nur mal aus meinem Programm herauskopiert, dort sind die Methoden aber noch verstrickter, aber das ist jetzt mal das wichtigste was mit der jTable passiert.

Ich setzte eigentlich nur einen CellEditor (siehe main).

So ich versuche derweilen einmal das von coderanch zu verstehen (ist mir leider noch nicht ersichtlich wie er zur Lösung kommt)

Wenn bei meinem Code etwas auffallen sollte, wo der Fehler sein könnte, wäre ich natürlich auch sehr dankbar

ein Renderer fehlt also,
genauer angeschaut habe ich mir nur den zweiten Link, Code laufen lassen, geht anscheinend,
der MyComboBoxRenderer dort mag dir helfen

Uh super, danke es hat funktioniert.

Also für alle die noch vlt auf das Problem stoßen werden, ein Renderer hat gefehlt wie SlaterB gesagt hat und wenn man den folgenden Code von MyComboboxRenderer einfach kopiert und in sein jeweiliges Beispiel einbaut funktioniert es.

  public MyComboBoxRenderer(String[] items) {
    super(items);
  }

  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      super.setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setSelectedItem(value);
    return this;
  }
}```

//EDIT
Eine Frage ist jetzt noch aufgekommen.

```eineColumn.setCellEditor(new DefaultCellEditor(comboBox));
eineColumn.setCellRenderer(new MyComboBoxRenderer(faktoren));```

Warum muss ich einen CellEditor und einen CellRenderer setzten?

[QUOTE=Paul279]

eineColumn.setCellRenderer(new MyComboBoxRenderer(faktoren));```

Warum muss ich einen CellEditor und einen CellRenderer setzten?[/QUOTE]

Weil der Editor zum Editieren der Zelle da ist und der Renderer zum Rendern des Inhalts.

das Verhalten was du am Anfang hattest im Gegensatz zum neuen ist ein schönes Beispiel,
man will vielleicht Daten ganz simpel darstellen, nicht als ComboBox, nicht als Eingabefeld mit blinkenden Cursor

technisch besteht sowieso der Unterschied, dass der Editor eine (vergleichsweise) aktive Komponente in der Bearbeitungsphase ist (*),
der Renderer existiert je Zelle nur virtuell kurzzeitig beim Zeichenprozess, dessen Aufgabe ist es Pixel zur Darstellung zu erzeugen, das angezeigte Bild der Tabelle

(*) letztlich wird aber eh immer gezeichnet und an den Monitor übertragen

Dein letztes ganzes Zitat muss man mal auf der Zunge zergehn lassen X)

Danke sehr für eure Erklärungen und Mühen, ich glaube ich habs jetzt :slight_smile: