2017-09-22 6 views
1

EDIT JETZT MIT MCVE funktioniert:Einstellung JComboBox als Tabellenspalte nicht

Ich möchte eine JTable Zelle als JComboBox anzuzeigen. Ich habe es mit dem Oracle Tutorial versucht und es funktioniert nicht. Das Lernprogramm sagt nichts darüber aus, wie Sie Ihr Tabellenmodell ändern müssen, damit es funktioniert. Also hier ist der Code:

Tablemodel:

import javax.swing.*; 
import javax.swing.table.AbstractTableModel; 

public class TableModel extends AbstractTableModel { 

@Override 
public int getColumnCount() { 
    // TODO Auto-generated method stub 
    return 2; 
} 

@Override 
public int getRowCount() { 
    // TODO Auto-generated method stub 
    return 2; 
} 

@Override 
public Object getValueAt(int row, int col) { 
    if (row == 0) { 
     return 2; 
    } else if (col == 1) { 
     return 1; 
    } else { 
     return null; 
    } 
} 

} 

Und die Aussicht, die Komponenten zeigen:

import java.awt.BorderLayout; 

import javax.swing.*; 
import javax.swing.table.TableColumn; 

public class View extends JFrame { 
public View() { 
    super(); 
    TableModel tableModel = new TableModel(); 
    JTable testTable = new JTable(tableModel); 

    JScrollPane scrollpane = new JScrollPane(testTable); 
    // scrollpane.setOpaque(false); 
    // scrollpane.getViewport().setOpaque(false); 
    JPanel testTablePanel = new JPanel(); 
    testTablePanel.setBorder(
      BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Testkonfiguration")); 
    testTablePanel.setLayout(new BorderLayout()); 
    testTablePanel.add(scrollpane); 

    TableColumn sportColumn = testTable.getColumnModel().getColumn(1); 

    JComboBox comboBox = new JComboBox(); 
    comboBox.addItem("Snowboarding"); 
    comboBox.addItem("Rowing"); 
    comboBox.addItem("Chasing toddlers"); 
    comboBox.addItem("Speed reading"); 
    comboBox.addItem("Teaching high school"); 
    comboBox.addItem("None"); 
    sportColumn.setCellEditor(new DefaultCellEditor(comboBox)); 

    add(scrollpane); 

    pack(); 
    setVisible(true); 
} 
public static void main(String[] args) { 
    new View(); 
} 

} 

Was muß ich in dem Tablemodel ändern, um es zu arbeiten?

+0

Was die meisten helfen würde, wenn Sie schaffen könnte und schreiben einen gültigen [MCVE] - eine *** kleine *** übersetzbar und lauffähiges Programm, klein genug, um hier komplett zu posten, das zeigt das Problem für uns. Bitte überlege, dies zu tun. –

+0

@HovercraftFullOfEels Ich schrieb jetzt einen, danke – Phreneticus

+0

@Phreneusus müssen Sie einfach Ihr Modell korrekt implementieren. Zuallererst für die Spalte 1 sollte es einen der Werte zurückgeben, die Sie zum Kombinationsfeld hinzugefügt haben. Zweitens: Sie müssen die Methode setValueAt (Object aValue, int rowIndex, int columnIndex) implementieren, um die Werte zu speichern, die Sie im Kombinationsfeld auswählen. Und auch Sie müssen 'isCellEditable (int rowIndex, int columnIndex)' implementieren, was für die Spalte mit Index 1 den Wert true zurückgibt. –

Antwort

1

In Ihrem Beispiel wird die 1-Spalte nicht bearbeitet. Sie zuerst das tun müssen, wie im Modell:

@Override 
public boolean isCellEditable(int rowIndex, int columnIndex) { 
    return columnIndex == 1; 
} 

Auch Ihre Modelldaten nicht gut umgehen, hat keine Möglichkeit, die Daten in der Tat zu erhalten und in der Tat festgelegt ist, so dass der Editor kann habe keine mögliche Wirkung. Sie müssen setValueAt überschreiben und den Nukleus des Modells aktualisieren lassen.

Zum Beispiel Ihr triviales Beispiel mit:

import java.awt.BorderLayout; 
import javax.swing.*; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableColumn; 

public class View extends JFrame { 
    public View() { 
     super(); 
     TableModel tableModel = new TableModel(); 
     JTable testTable = new JTable(tableModel); 

     JScrollPane scrollpane = new JScrollPane(testTable); 
     // scrollpane.setOpaque(false); 
     // scrollpane.getViewport().setOpaque(false); 
     JPanel testTablePanel = new JPanel(); 
     testTablePanel.setBorder(BorderFactory 
       .createTitledBorder(BorderFactory.createEtchedBorder(), "Testkonfiguration")); 
     testTablePanel.setLayout(new BorderLayout()); 
     testTablePanel.add(scrollpane); 

     TableColumn sportColumn = testTable.getColumnModel().getColumn(1); 

     JComboBox<String> comboBox = new JComboBox<>(); 
     comboBox.addItem("Snowboarding"); 
     comboBox.addItem("Rowing"); 
     comboBox.addItem("Chasing toddlers"); 
     comboBox.addItem("Speed reading"); 
     comboBox.addItem("Teaching high school"); 
     comboBox.addItem("None"); 
     sportColumn.setCellEditor(new DefaultCellEditor(comboBox)); 

     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     add(scrollpane); 

     pack(); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     new View(); 
    } 

} 

class TableModel extends AbstractTableModel { 
    Object[][] innerModel = new Object[][]{{2, 1}, {2, null}}; 

    public TableModel() { 

    } 

    @Override 
    public int getColumnCount() { 
     return 2; 
    } 

    @Override 
    public int getRowCount() { 
     return innerModel.length; 
    } 

    @Override 
    public Object getValueAt(int row, int col) { 
     return innerModel[row][col]; 
    } 

    @Override 
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
     innerModel[rowIndex][columnIndex] = aValue; 
     fireTableCellUpdated(rowIndex, columnIndex); 
    } 

    @Override 
    public boolean isCellEditable(int rowIndex, int columnIndex) { 
     return columnIndex == 1; 
    } 

} 
+0

Das war's, ich habe einfach vergessen, setValueAt() * facepalm * aufzurufen Danke! – Phreneticus

+0

Mein Code funktioniert jetzt, aber ich kann nur sehen, dass die Tabellenspalte aus ComboBoxen besteht, sobald ich auf eine Tabellenzelle in dieser Spalte klicke. Sobald ich eine andere Option der Combobox auswähle, sehe ich den Pfeil der ComboBox nicht mehr. Gibt es eine Möglichkeit, diesen Pfeil IMMER auf JEDER Zelle zu zeigen? – Phreneticus