#java #swing
#java #swing
Вопрос:
У меня есть JTable, и я хочу выбирать ячейку только при щелчке на ячейке в первом столбце таблицы. Когда я нажимаю на ячейку в любом другом столбце, я хочу, чтобы была выбрана вся строка. Как я могу этого добиться?
Комментарии:
1. Я бы сказал, что вам нужно будет обработать это в прослушивателе выбора .
Ответ №1:
Вам необходимо реализовать интерфейс TableColumnModelListener и добавить его в TableColumnModel
свой JTable
.
Вот пример.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.time.LocalDate;
import java.time.Month;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class TableSel implements Runnable, TableColumnModelListener {
private JFrame frame;
private JTable table;
@Override // java.lang.Runnable
public void run() {
showGui();
}
@Override // javax.swing.event.TableColumnModelListener
public void columnAdded(TableColumnModelEvent event) {
// Do nothing.
}
@Override // javax.swing.event.TableColumnModelListener
public void columnRemoved(TableColumnModelEvent event) {
// Do nothing.
}
@Override // javax.swing.event.TableColumnModelListener
public void columnMoved(TableColumnModelEvent event) {
// Do nothing.
}
@Override // javax.swing.event.TableColumnModelListener
public void columnMarginChanged(ChangeEvent event) {
// Do nothing.
}
@Override // javax.swing.event.TableColumnModelListener
public void columnSelectionChanged(ListSelectionEvent event) {
if (!event.getValueIsAdjusting()) {
int selectedColumn = table.getSelectedColumn();
if (selectedColumn == 0) {
table.setColumnSelectionAllowed(true);
}
else {
table.setColumnSelectionAllowed(false);
}
}
}
private JScrollPane createTable() {
TableModel model = new CustoMod();
table = new JTable(model);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
TableColumnModel tcm = table.getColumnModel();
tcm.addColumnModelListener(this);
JScrollPane scrollPane = new JScrollPane(table);
return scrollPane;
}
private void showGui() {
frame = new JFrame("Table");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createTable(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new TableSel());
}
}
class CustoMod extends AbstractTableModel {
private static final String[] COLUMNS;
private static final Object[][] DATA;
static {
COLUMNS = new String[]{"Surname", "Name", "Games", "Goals", "Born"};
DATA = new Object[][] {
{"Rumney","Harold", 171, 28, LocalDate.of(1907, Month.MAY, 16)},
{"Regan","Jack", 196, 3, LocalDate.of(1912, Month.SEPTEMBER, 12)},
{"Coventry","Syd", 227, 62, LocalDate.of(1899, Month.JUNE, 13)},
{"Picken","Billy", 212, 46, LocalDate.of(1956, Month.JUNE, 7)},
{"Collier","Albert", 205, 54, LocalDate.of(1909, Month.JULY, 9)},
{"Buckley","Nathan", 260, 263, LocalDate.of(1972, Month.JULY, 26)},
{"Merrett","Thorold", 180, 148, LocalDate.of(1933, Month.SEPTEMBER, 30)},
{"Rose","Bob", 152, 214, LocalDate.of(1928, Month.AUGUST, 07)},
{"Millane","Darren", 147, 78, LocalDate.of(1965, Month.AUGUST, 9)},
{"Fothergill","Des", 111, 337, LocalDate.of(1920, Month.JULY, 15)},
{"Weideman","Murray", 180, 262, LocalDate.of(1936, Month.FEBRUARY, 16)},
{"Lee","Dick", 230, 707, LocalDate.of(1899, Month.MARCH, 19)},
{"Kyne","Phonse", 245, 237, LocalDate.of(1915, Month.OCTOBER, 29)},
{"Coventry","Gordon", 306, 1299, LocalDate.of(1901, Month.SEPTEMBER, 25)},
{"Daicos","Peter", 250, 549, LocalDate.of(1961, Month.SEPTEMBER, 20)},
{"Thompson","Len", 268, 217, LocalDate.of(1947, Month.AUGUST, 27)},
{"Tuddenham","Des", 182, 251, LocalDate.of(1943, Month.JANUARY, 29)},
{"Collier","Harry", 253, 299, LocalDate.of(1907, Month.OCTOBER, 01)},
{"Shaw","Tony", 313, 157, LocalDate.of(1960, Month.JULY, 23)},
{"Richardson","Wayne", 277, 323, LocalDate.of(1946, Month.DECEMBER, 8)},
{"Whelan","Marcus", 173, 31, LocalDate.of(1914, Month.JUNE, 27)},
{"Brown","Gavin", 254, 195, LocalDate.of(1967, Month.SEPTEMBER, 25)},
};
}
@Override
public int getRowCount() {
return DATA.length;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
Class<?> theClass;
switch (columnIndex) {
case 0:
case 1:
theClass = String.class;
break;
case 2:
case 3:
theClass = Integer.class;
break;
case 4:
theClass = LocalDate.class;
default:
theClass = Object.class;
}
return theClass;
}
@Override
public int getColumnCount() {
return COLUMNS.length;
}
@Override
public String getColumnName(int column) {
return COLUMNS[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return DATA[rowIndex][columnIndex];
}
}
Я использую пользовательскую табличную модель, но это не требуется для реализации желаемого поведения.
Ответ на ваш вопрос содержится в следующих частях приведенного выше кода.
- Реализовать интерфейс
TableColumnModelListener
public class TableSel implements Runnable, TableColumnModelListener {
- При реализации интерфейса вам нужно только реализовать метод
columnSelectionChanged(ListSelectionEvent)
. Другие методы могут быть пустыми. - Добавьте свою реализацию в
JTable
table = new JTable(model);
TableColumnModel tcm = table.getColumnModel();
tcm.addColumnModelListener(this);
Обратите внимание, что я также установил режим выбора на одиночный выбор.
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
A JTable
имеет выбор строки и выбор столбца. По умолчанию выбор строки включен, а выбор столбца — нет. Смотрите методы setColumnSelectionAllowed() и setRowSelectionAllowed() . Когда для обоих установлено значение true, выбирается одна ячейка. Когда включен только выбор строки, при выборе ячейки выбирается вся строка, содержащая эту ячейку. Аналогично, когда разрешен только выбор столбца.
Итак, в основном вы хотите включать и выключать выбор столбцов. Если выбранный столбец является первым столбцом, то необходимо включить выбор столбца, а для любого другого столбца его необходимо отключить.