Ответ 1
Чтобы сделать редактируемый столбцом, вы должны переопределить метод isCellEditable
в TableModel
. Создание TableModel
довольно легко, если вы наследуете AbstractTableModel
, и я бы рекомендовал его для всех, кроме самых простых JTable
s.
Однако адаптация TableModel
является лишь частью того, что вам нужно сделать. Чтобы на самом деле получить пользовательский компонент в JTable
, вам нужно установить собственный рендеринг ячеек. Чтобы использовать интерактивный пользовательский компонент, вам нужно установить собственный редактор ячеек. В некоторых случаях достаточно использовать слегка модифицированные версии классов по умолчанию для этого.
Редакторы
Если у вас уже есть пользовательский компонент, легко выполнить с помощью делегирования: создайте новый класс, реализующий TableCellEditor
, и верните экземпляр new компонента getCellEditorComponent
. Параметр к этому методу включает в себя текущее значение, а также координаты ячейки, ссылку назад к таблице и, если не выбрана ячейка.
TableCellEditor
также имеет метод, который вызывается, когда пользователь совершает изменение содержимого ячейки (где вы можете проверить ввод пользователя и настроить модель) или отменяет редактирование. Обязательно вызовите метод stopEditing()
в своем редакторе, если вы когда-либо программно прекращаете редактирование, иначе компонент редактора останется на экране - это потребовало от меня времени от 2 до 2 часов.
Обратите внимание, что в редакторах JTable
и только редакторы получают события! Отображение кнопки может быть выполнено с помощью средства визуализации. Но чтобы получить действующую кнопку, вам нужно реализовать редактор с правильным EventListeners
зарегистрированным. Регистрация слушателя на рендерере ничего не делает.
рендерерами
Реализация средства визуализации не является строго необходимым для того, что вы описываете в своем вопросе, но вы, как правило, в конечном итоге делаете это, хотя бы для незначительных изменений. Renderers, в отличие от редакторов, имеют критически высокую скорость. getTableCellRendererComponent
средства визуализации вызывается один раз для каждой ячейки таблицы! Компонент, возвращаемый средством визуализации, используется только для рисования ячейки, а не для взаимодействия, и поэтому может быть "повторно использован" для следующей ячейке. Другими словами, вы должны отрегулировать компонент (например, используя setText(...)
или setFont(...)
, если это TextComponent
) в рендерере, вы должны not создать новый экземпляр - способ калечить производительность.
Предостережения
Обратите внимание, что для работы рендереров и редакторов вам нужно указать JTable
, когда использовать определенный рендерер/редактор. Есть два способа сделать это. Вы можете установить рендеринг/редактор ячеек по умолчанию для определенного типа с помощью соответствующих методов JTable
. Чтобы этот способ работал, ваш TableModel
должен вернуть именно этот тип в методе getColumnClass(...)
! Модель таблицы по умолчанию будет not делать это за вас, она всегда возвращает Object.class
. Я уверен, что кто-то бросил много людей.
Другой способ установки редактора/средства визуализации - это явно установить его на самом столбце, т.е. получить TableColumn
с помощью метода getTableColumn(...)
JTable
. Это намного сложнее, однако это единственный способ иметь два разных рендерера/редактора для одного класса. Например. ваша модель может иметь два столбца класса String, которые визуализируются совершенно по-разному, возможно, один раз с помощью JLabel/DefaultRenderer
, а другой с помощью JButton
для доступа к более сложному редактору.
JTable
с его настраиваемыми рендерерами и редакторами является extreme универсальным, но его также много, и есть много чего сделать неправильно. Удачи!
Как использовать таблицы в Учебное пособие Swing является обязательным для всех, кто настраивает JTables. В частности, прочитайте и перечитайте "Концепции: Редакторы и рендеринги" , поскольку для этого обычно требуется некоторое время для "click". Примеры для индивидуальных рендереров и редакторов также очень полезны.