Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

540

ГЛАВА 17

умолчанию, мы уже знаем их значения). Есть и более полные конструкторы, которые вы сможете отыскать в интерактивной документации, но всегда для любого столбца TableColumn должен иметься соответствующий столбец в модели данных TableModel. Полученный столбец добавляется в модель с помощью метода addColumn(). Правда, приходится вручную задавать для него текст заголовка (методом setHeaderValue(), и здесь поддерживается HTML): объект TableColumn ничего не знает о модели данных и о том, какой у него должен быть заголовок.

Таким образом, мы видим, что один столбец, описанный в модели данных, может отображаться на экране несколькими столбцами благодаря отдельной модели столбцов и ее гибкости. Впрочем, все же лучше, если изменения в количестве столбцов идут из одного источника, где их легко обнаружить и поддерживать: таким источником должна быть модель данных TableModel. Добавление столбцов посредством модели TableColumnModel имеет смысл, только если вы «копируете» некоторые столбцы, несколько раз воспроизводя их на экране. К тому же после запуска примера возникнет небольшая неприятность: если вы меняете данные в ячейке в одном столбце, дополнительный столбец не перерисовывается автоматически, он будет перерисован лишь тогда, когда поменяется его размер или выделение строки таблицы. Столбец таблицы — довольно низкоуровневая ее часть, и при работе с ним стоит это учитывать. В нашем случае необходимо вручную попросить все столбцы, отображающие изменившийся столбец, перерисовать себя, что конечно не совсем удобно.

Запустив программу с примером, вы сможете увидеть, как модель столбцов таблицы позволяет менять их размеры и динамически манипулировать местоположением и количеством столбцов, даже если в модели данных TableModel (бесспорно, главной модели таблицы JTable) новые столбцы не имеют своего представительства. Сведем наиболее полезные методы и свойства модели TableColumnModel в табл. 17.4.

Таблица 17.4. Самые полезные методы и свойства модели TableColumnModel

Методы и свойства

Описание

addColumn(), removeColumn()

Методы дают возможность динамически управлять количеством

 

хранимых в модели TableColumnModel столбцов. Первый ме-

 

тод присоединяет к модели новый столбец (заданный объектом

 

TableColumn), второй удаляет из модели заданный столбец

addColumnModelListener(),

Эти два метода поддерживают присоединение и отсоединение

removeColumnModelListener()

слушателей TableColumnModelListener. Присоединив к модели

 

такого слушателя, вы будете получать полную информацию обо

 

всех происходящих со столбцами таблицы действиях

Таблицы

541

Таблица 17.4 (продолжение)

 

 

 

Методы и свойства

Описание

 

 

getColumnCount(), getColumn(),

Позволяют получить исчерпывающую информацию о содер-

getColumns()

жащихся в модели столбцах. Первый метод сообщает количе-

 

ство столбцов, второй возвращает столбец по его порядково-

 

му номеру, и наконец, третий метод возвращает перечисление

 

(Enumeration) всех содержащихся в модели столбцов

moveColumn()

Меняет местами два столбца таблицы, заданных (своими индек-

 

сами в модели) в виде параметров данного метода. Не забывай-

 

те, что отсчет столбцов ведется с нуля

columnMargin (методы get/set)

Это свойство управляет расстоянием между столбцами таблицы

 

(в пикселах)

Это основные методы модели столбцов таблицы, но не забывайте также о том, что львиная доля свойств отдельного столбца задается в объекте TableColumn, который мы кратко рассмотрели. Основными свойствами любого столбца являются его размеры (и мы видели, как они меняются), а также собственные объекты для отображения и редактирования ячеек, если они заданы (до них мы вскоре доберемся и обсудим подробно). Чтобы при случае основные свойства столбца таблицы были у вас «под рукой», соорудим еще одну полезную таблицу (табл. 17.5).

Таблица 17.5. Важнейшие свойства столбца TableColumn

Свойства

Описание

modelIndex

Индекс столбца в модели данных таблицы TableModel. Данные

 

именно этого столбца отображает объект TableColumn

preferredWidth, minWidth,

Предпочтительный, минимальный и максимальный размеры

maxWidth

столбца таблицы (длина столбца в пикселах). Таблица всегда

 

соблюдает минимальный и максимальный размеры столбца, так

 

что эти свойства довольно «сильного» действия

resizable

Позволяет указать, можно ли будет динамически менять раз-

 

меры столбца, или он всегда будет иметь предпочтительный

 

размер

cellRenderer, cellEditor,

Объекты для отображения и редактирования ячеек данного

headerRenderer

столбца, а также объект, отображающий заголовок столбца. Мы

 

обсудим их в разделе, посвященном внешнему виду ячеек та-

 

блицы

headerValue, identifier

Первое свойство хранит значение, которое будет отображать-

 

ся в заголовке столбца, а второе, используемое довольно

 

редко, позволяет связать со столбцом некоторый уникальный

 

идентификатор. Применяя этот идентификатор, вы впослед-

 

ствии всегда сможете обнаружить данный столбец в модели

 

TableColumnModel (с помощью метода getColumnIndex()), как бы

 

сильно не изменилась структура последней

Как правило, модель столбцов таблицы и объекты TableColumn чаще всего требуются для настройки размеров столбцов. Таблица JTable разрешает пользователю менять размеры столбцов прямо во время работы программы (если только вы не установили свойство столбца resizable равным false), поэтому в дополнение к трем размерам столбца иногда необходимо управлять тем, как таблица будет перераспределять

542

ГЛАВА 17

пространство при изменении размеров того или иного столбца. Режим перераспределения пространства таблицы управляется специальным свойством autoResizeMode. Класс JTable поддерживает несколько режимов перераспределения пространства таблицы, давайте посмотрим, как работает каждый из них, с помощью следующего примера:

//TableResizeModes.java

//Режимы перераспределения пространства таблицы

//при изменении размеров столбцов

import javax.swing.*; import java.awt.*;

public class TableResizeModes extends JFrame {

//названия столбцов таблицы private String[] columnNames = {

"Название", "Вкус", "Цвет"

};

//данные для таблицы

private String[][] data = {

{"Апельсин", "Кисло-сладкий", "Оранжевый"},

{"Лимон", "Кислый", "Желтый"}

}; // массив таблиц

private JTable[] tables = new JTable[5]; public TableResizeModes() {

super("TableResizeModes"); setDefaultCloseOperation(EXIT_ON_CLOSE);

//окно делим на пять ячеек setLayout(new GridLayout(5, 1));

//создаем массив таблиц

for (int i=0; i<tables.length; i++) { tables[i] =

new JTable(data, columnNames); add(new JScrollPane(tables[i]));

}

// меняем режимы распределения пространства tables[1].setAutoResizeMode(

JTable.AUTO_RESIZE_OFF); tables[2].setAutoResizeMode(

JTable.AUTO_RESIZE_NEXT_COLUMN); tables[3].setAutoResizeMode(

JTable.AUTO_RESIZE_LAST_COLUMN); tables[4].setAutoResizeMode(

Таблицы

543

JTable.AUTO_RESIZE_ALL_COLUMNS);

//придаем окну оптимальный размер и

//выводим его на экран

pack();

setVisible(true);

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new TableResizeModes(); } });

}

}

В примере создается пять таблиц, отображающих одни и те же данные, полученные из массивов data (данные ячеек) и columnNames (названия столбцов). Таблицы размещаются в окне с менеджером расположения GridLayout, который разбивает панель на пять ячеек одинакового размера, располагающихся вертикально. Единственное различие

всозданных таблицах заключается в том, что они задействуют различные режимы распределения пространства таблицы. Таблица JTable предоставляет нам пять таких режимов, пять таблиц мы и создали в примере. Обратите внимание, что для первой таблицы

вмассиве (tables[0]) режим не меняется — он остается используемым по умолчанию режимом AUTO_RESIZE_SUBSEQUENT_COLUMNS.

Запустив программу с примером, вы сможете своими руками «пощупать», чем характерен тот или иной режим перераспределения пространства, при этом вам наверняка пригодится краткое описание этих режимов, представленное в табл. 17.6.

Таблица 17.6. Режимы распределения пространства таблицы JTable

Режим

Краткое описание

AUTO_RESIZE_OFF

В данном режиме пространство не перераспределяет-

 

ся — размеры столбцов, если вы не меняете их вручную,

 

таблицей не меняются. По умолчанию размер столбца ра-

 

вен его предпочтительному размеру, если вы меняете раз-

 

мер столбца, то меняется только он, остальные столбцы не

 

затрагиваются. Если после изменения размеров столбцов

 

места в таблице начинает не хватать, появляется горизон-

 

тальная полоса прокрутки (в том случае если таблица была

 

размещена в панели прокрутки JScrollPane, в противном

 

случае крайние столбцы просто исчезают с экрана)

AUTO_RESIZE_NEXT_COLUMN

При изменении размеров столбца пространство пере-

 

распределяется только между ним и следующим за ним

 

столбцом — если вы делаете столбец больше, следующий

 

столбец становится меньше, и наоборот, при уменьшении

 

столбца следующий за ним сосед забирает освободившее-

 

ся пространство

AUTO_RESIZE_LAST_COLUMN

Столбцы можно увеличивать или уменьшать только за счет

 

последнего столбца таблицы, все остальные столбцы (не

 

считая того, размер которого вы меняете) остаются неиз-

 

менными

544

ГЛАВА 17

Таблица 17.6 (продолжение)

 

 

 

Режим

Краткое описание

 

 

AUTO_RESIZE_SUBSEQUENT_

Данный режим используется таблицей по умолчанию. При

COLUMNS

изменении размеров какого-либо столбца перераспреде-

 

ление пространства происходит равномерно между всеми

 

следующими за ним столбцами. Последний столбец нельзя

 

отдельно уменьшить или увеличить, разве что меняя раз-

 

меры предпоследнего столбца

AUTO_RESIZE_ALL_COLUMNS

Перераспределение пространства в этом режиме происхо-

 

дит между всеми столбцами таблицы. Если вы, к примеру,

 

увеличиваете размер некоторого столбца, то требуемое для

 

этого пространство «отнимается» у всех остальных столб-

 

цов в равном соотношении (правда, если столбец достигает

 

минимального размера или изначально не допускает изме-

 

нения своих размеров, он перестает участвовать в «жерт-

 

вовании» пространства)

Вкупе с регулированием минимального, предпочтительного и максимального размеров столбца, которое предоставляет нам класс TableColumn, различные режимы перераспределения пространства таблицы дают нам возможность сделать размеры таблицы и ее ячеек именно такими, какими вы хотите их видеть. Не забывайте и о простых свойствах rowHeight и intercellSpacing, рассмотренных нами в начале главы. Они позволяют парой строк кода дополнить только что изученные возможности по управлению размерами столбцов — первое свойство отвечает за высоту строк таблицы, а второе задает расстояние между соседними ячейками как по вертикали, так и по горизонтали. Любые размеры таблицы теперь у вас в руках.

Напоследок об еще одном свойстве таблицы JTable, которое имеет непосредственное отношение к модели столбцов TableColumnModel. Это свойство autoCreateColumnsFromModel

булева типа. Когда данное свойство равно true (а по умолчанию оно равно true), то происходит следующее: при присоединении модели данных TableModel таблица получает из этой модели информацию обо всех столбцах и на ее основе создает объекты TableColumn, которые затем передает в модель столбцов TableColumnModel. Если вы хотите получить больше контроля над тем, как, когда и какие столбцы будет выводить таблица на экран, сделайте это свойство равным false и добавляйте столбцы в модель вручную, когда настанет подходящий момент — в этом случае столбцы не будут создаваться автоматически. Правда, обращаться с данным свойством нужно аккуратнее и не забывать добавлять все нужные вам столбцы на экран, в противном случае от таблицы останется только рамка.

Модели выделения

Ячейки таблицы можно выделять любыми способами, которые вы только в состоянии себе представить: строками, столбцами, интервалами, единичными ячейками и многими другими. Нетрудно догадаться, что такую гибкость в выделении содержимого таблицы обеспечивают очередные модели, верно служащие классу JTable. На этот раз это модели, хранящие выделенные строки и столбцы таблицы. И для столбцов, и для строк таблицы имеется собственная модель выделения, но не опасайтесь сложностей — это прекрасно знакомая нам еще с главы 11 (в которой мы изучали списки Swing) модель выделения элементов списка ListSelectionModel. Многое, что мы узнали об этой модели из главы 11, мы здесь повторять не будем, так что если вы не читали про модель выделения списка или просто немного забыли ее, самое время ненадолго вернуться назад.

Итак, модели выделения две. Первая модель хранится непосредственно в таблице JTable и отвечает за выделение строк таблицы. Вторая модель (представленная все тем

Источник: https://studfile.net/preview/15935977/