Графические интерфейсы пользователя Java - Тимур Сергеевич Машнин Страница 22
Графические интерфейсы пользователя Java - Тимур Сергеевич Машнин читать онлайн бесплатно
Это изменение также отслеживается событием TableColumnModelEvent.
Событие изменения модели TableColumnModel – добавление или удаление столбцов, их перестановка, выделение столбцов можно отследить с помощью слушателя, который добавляется методом addColumnModelListener.
По соображениям производительности каждая ячейка в таблице не является отдельным компонентом.
Вместо этого таблица рисует свои ячейки с помощью визуализатора ячеек TableCellRenderer.
Один визуализатор ячеек обычно используется для рисования всех ячеек, которые содержат один и тот же тип данных.
Когда же пользователь начинает редактировать данные ячейки, в игру вступает редактор ячейки, контролируя поведение редактирования ячейки.
Чтобы выбрать рендерер, который отображает ячейки в столбце, таблица сначала определяет, указали ли вы рендер для этого конкретного столбца.
Если вы этого не сделали, таблица вызывает метод getColumnClass модели таблицы, который возвращает тип данных ячеек столбца.
Затем таблица сравнивает тип данных столбца со списком типов данных, для которых зарегистрированы рендереры.
По умолчанию, таблица помещает в этот список следующие типы данных:
Boolean – отображается с помощью флажка.
Число – отображается выравниванием по правому краю, с использованием NumberFormat.
Дата – визуализируется с помощью метки Label, с использованием DateFormat.
ImageIcon, Icon – отображается с помощью центрированной метки Label.
Объект – отображается меткой Label со строковым значением объекта.
Редакторы ячеек TableCellEditor выбираются с использованием аналогичного алгоритма.
Интерфейс TableCellRenderer описывает всего один метод getTableCellRendererComponent.
Как видно из описания, для каждой ячейки с индексами (row, col) можно задать свой способ визуализации.
Этот способ может меняться в зависимости от содержимого value ячейки, от того, выделена ли ячейка isSelected, имеет ли она фокус ввода hasFocus, и даже от того, какая таблица table использует этот метод.
Исходя из этих данных, метод интерфейса должен сформировать компонент, содержащий значение value, и вернуть его.
Удобно реализовать интерфейс TableCellRenderer каким-нибудь графическим компонентом, имеющим метод paint, который будет вызван после вызова метода getTableCellRendererComponent, чтобы отрисовать компонент, отображающий значение ячейки.
По умолчанию, интерфейс TableCellRenderer реализован классом DefaultTableCellRenderer, расширяющим класс JLabel.
Но класс DefaultTableCellRenderer не отображает изображения типа Icon.
Используется только метод setText (String) класса JLabel.
Это означает, что, хотя ячейка таблицы может содержать любой объект, на экране появляется только строка, полученная методом toString () этого объекта.
Класс JTable, позволяет указать класс рендеринга для каждого класса столбца с помощью метода setDefaultRenderer.
Помните, мы в модели данных таблицы определяли метод getColumnClass, который возвращал тип данных каждого столбца.
Это означает, что все столбцы, объявленные как строки, получат один визуализатор, в то время как столбцы, объявленные как Interger, получат другой визуализатор.
Это имеет смысл, потому что основная функция рендеринга – быть адаптерами или преобразователями между объектами и строками.
Давайте взглянем на простой пример визуализатора, который показывает, как сделать затенение в таблице.
Здесь мы реализуем интерфейс TableCellRenderer и в его методе извлекаем компонент из визуализатора по умолчанию DefaultTableCellRenderer.
Для этого компонента, в зависимости от индекса строки таблицы, мы меняем фон.
Теперь давайте посмотрим на пример, когда данные в таблице больше не являются однородными.
Первый столбец будет содержать целые числа, второй будет содержать цвета, а третий будет содержать объект.
Для правильного отображения этих данных мы будем использовать три разных средства визуализации.
Сначала мы должны определить модель данных таблицы, в которой присутствуют разные типы данных.
В этой модели данных мы заполняем массив данных разными объектами.
И определяем метод getValueAt, который возвращает элемент этого массива.
Метод getColumnClass возвращает разные типы в зависимости от номера столбца.
Обратите внимание, что класс объекта не содержит метод toString.
За преобразование объекта в строку будет отвечать рендерер.
И вот у нас есть рендерер для объекта Student, который переводит объект в строку, используя поля класса объекта.
И есть рендереры для целых чисел и цветов.
В рендерере цветов мы возвращаем кнопку, закрашенную определенным цветом.
А в рендерере целых чисел мы переводим объект Integer в строку.
Теперь, чтобы свести это все вместе, мы создаем таблицу на основе модели данных.
И для каждого типа данных устанавливаем свой рендерер.
Наконец, точно так же, как таблица позволяет нам указывать разные средства визуализации, мы также можем предоставлять различные типы редакторов, которые позволяют нам редактировать объекты в таблице.
Основная ответственность редактора заключается в том, чтобы преобразовать строку, вводимую пользователем, в тип объекта, который представляет конкретная ячейка.
По умолчанию таблица создается редактируемой.
Это означает, что содержимое ее ячеек можно изменять вводом новых значений с клавиатуры.
Для редактирования ячеек используется любой класс, реализующий интерфейс TableCellEditor.
TableCellEditor расширяет интерфейс CellEditor, который определяет методы, которые должен реализовывать любой общий редактор.
Наличие этого интерфейса позволяет отделить JTable от конкретных редакторов, таких как JTextField, JCheckBox, JComboBox и т. д.
Этот интерфейс CellEditor облегчает обмен данными между редактором и компонентом, ячейка которого редактируется.
Компонент устанавливает редактор ячеек и говорит ему, когда начать и прекратить редактирование.
Например, когда CellEditor получает вызов метода stopCellEditing, он знает, что нужно преобразовать значение из строки в объект и сохранить это значение, для предстоящего вызова метода getCellEditorValue.
Интерфейс TableCellEditor расширяет интерфейс CellEditor и добавляет к его методам только один метод getTableCellEditorComponent, который возвращает компонент, пригодный для редактирования, например, объект класса JTextField, для заданной ячейки с индексами (row, column) и содержимым value.
При изменении содержимого ячейки происходит событие класса ChangeEvent, которое можно отследить, присоединив к редактору слушателя события методом addCellEditorListener.
Интерфейс TableCellEditor реализован классом DefaultCellEditor.
Конструкторы этого класса применяют в качестве конкретных редакторов компоненты JCheckBox, JComboBox и JTextField.
По умолчанию таблицы используют редактор с полем ввода JTextField.
Хотя в ячейках таблицы могут располагаться любые объекты, этот редактор обрабатывает только текст, получающийся применением метода toString () объекта.
Компонент JCheckBox используется для изображения в виде флажка логического содержимого ячейки типа boolean.
Этот редактор позволяет изменять истинность содержимого ячейки.
Компонент JСomboBox применяется для ввода в ячейку одного из нескольких значений, содержащихся в раскрывающемся списке.
В этом примере мы реализуем редактор ячеек таблицы на основе интерфейса TableCellEditor.
Этот редактор предназначен для редактирования таблицы, отображающей целые числа.
В конструкторе редактора мы присоединяем к компоненту редактирования, текстовому полю, слушатель, который при нажатии пользователем клавиши Enter, вызывает метод stopCellEditing редактора.
В методе getTableCellEditorComponent редактора, мы преобразуем целое число в строку, которую устанавливаем в текстовое поле.
В методе stopCellEditing редактора, мы делаем обратное, переводим строку в целое число.
И если это не удается – выбрасывается исключение.
Таким образом, мы позволяем пользователю вводить в редактируемое поле только целые числа.
Назначить этот редактор для таблицы мы можем методом setDefaultEditor, в котором указываем, для какого типа
Жалоба
Напишите нам, и мы в срочном порядке примем меры.