/ / Pole wyboru tylko w jednej komórce JTable - java, swing, jtable, jcheckbox

Checkbox w tylko jednej JTable Cell - java, swing, jtable, jcheckbox

Chcę stworzyć JTable z 2 kolumnami, które wyglądają jak ankieta. Po lewej stronie znajdują się pytania, a po prawej użytkownik może udzielić odpowiedzi. Ale w jednym wierszu powinno być pole wyboru po prawej stronie, aby użytkownik mógł odpowiedzieć tylko tak lub nie.

Czy można to zrobić z JTablei jak mogę to osiągnąć?

pozdrowienia

Odpowiedzi:

1 dla odpowiedzi № 1

W komentarzu stwierdziłeś:

Próbowałem z kolumną JCheckboksów, ale działa, ale chcę tylko jedna komórka

Zauważ, że ten wymóg jest trochę trudny. Myślę, że możesz zastąpić getCellRenderer (int wiersz, int kolumna) i getCellEditor (int wiersz, int kolumna) metody pytające o klasę wartości komórki.

W ten sposób renderer / edytor komórek będzie JCheckbox nawet po posortowaniu wierszy tabeli lub zmianie kolejności kolumn tabeli.

Coś takiego:

    JTable table = new JTable(model) {
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
if(getValueAt(row, column) instanceof Boolean) {
return super.getDefaultRenderer(Boolean.class);
} else {
return super.getCellRenderer(row, column);
}
}

@Override
public TableCellEditor getCellEditor(int row, int column) {
if(getValueAt(row, column) instanceof Boolean) {
return super.getDefaultEditor(Boolean.class);
} else {
return super.getCellEditor(row, column);
}
}
};

Przykład

Oto kompletny przykład do zabawy.

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class Demo {

private void createAndShowGUI() {

DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0);
model.addRow(new Object[]{"Property # 1", "Value # 1"});
model.addRow(new Object[]{"Property # 2", Boolean.TRUE});
model.addRow(new Object[]{"Property # 3", "Value # 3"});

JTable table = new JTable(model) {
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
if(getValueAt(row, column) instanceof Boolean) {
return super.getDefaultRenderer(Boolean.class);
} else {
return super.getCellRenderer(row, column);
}
}

@Override
public TableCellEditor getCellEditor(int row, int column) {
if(getValueAt(row, column) instanceof Boolean) {
return super.getDefaultEditor(Boolean.class);
} else {
return super.getCellEditor(row, column);
}
}
};
table.setAutoCreateRowSorter(true);

JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}

Zrzuty ekranu

wprowadź opis obrazu tutaj


1 dla odpowiedzi nr 2

Możesz zaimplementować interfejs TableCellRendereraby utworzyć niestandardowy moduł renderujący dla komórek, które mają różne obiekty, takie jak JTextField i JLabel. Musisz zaimplementować metodę getTableCellRendererComponent, a następnie możesz zwrócić komponent (taki jak JPanel lub co chcesz) ze składnikami, które chcesz pokazać w komórce. W tabeli użyjesz JTable.setDefaultRenderer (), aby ustawić nowy moduł renderujący dla klasy niestandardowej.

Jeśli masz tylko 2 wartości, być może możesz również ustawić swoje dane na wartości boolowskie i pozwolić, aby tabela wyświetlała je jako CheckBox (domyślne renderowanie).

To jest kod dla drugiej metody, która wydaje się bardziej podobna do tego, co chcesz.

class CheckBoxModel extends AbstractTableModel{

private final Object[][] rowData = {{"John" , true}, {"Mary", false}};
final String columnNames[] = { "Student", "Approve" };

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

@Override
public int getColumnCount() {
return columnNames.length;
}

@Override
public Class<?> getColumnClass(final int columnIndex) {
if (columnIndex == 1) {
return Boolean.class; //renders column as a CheckBox
}
return super.getColumnClass(columnIndex);
}

@Override
public Object getValueAt(final int rowIndex, final int columnIndex) {
return rowData[rowIndex][columnIndex];
}

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

@Override
public boolean isCellEditable(final int rowIndex, final int columnIndex) {
return true;    //makes all cells editable
}
}

I klasa testowa:

public class TestTable {

public static void main(String[] args) {
final JFrame frame = new JFrame("Editable Color Table");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTable table = new JTable(new CheckBoxModel());
final JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(500, 500);
frame.setVisible(true);
}
}