Spec-Zone .ru
спецификации, руководства, описания, API
|
С JTable
class можно вывести на экран таблицы данных, дополнительно разрешая пользователю отредактировать данные. JTable
не содержит или данные кэша; это - просто представление Ваших данных. Вот изображение типичной таблицы, выведенной на экран в пределах области прокрутки:
Остальная часть этого раздела показывает Вам, как выполнить некоторые общие связанные с таблицей задачи. Вот являются темы этим разделом покрытия:
Нажмите кнопку Launch, чтобы работать SimpleTableDemo
Щелкните по ячейке, которая содержит "Сноубординг".
Вся первая строка выбирается, указывая, что Вы выбрали данные Кэти Смит. Специальное выделение указывает, что ячейка "Сноубординга" доступна для редактирования. Обычно, Вы начинаете редактировать текстовую ячейку двойным щелчком это.
Расположите курсор по "Имени". Теперь нажмите кнопку мыши и перетащите направо.
Как можно видеть, пользователи могут перестроить столбцы в таблицах.
Расположите курсор только направо от заголовка столбца. Теперь нажмите кнопку мыши и перетащите направо или оставленный.
Размер изменений столбца, и другие столбцы корректируются, чтобы заполнить остающееся пространство.
Таблица в SimpleTableDemo.java
объявляет имена столбцов в Строковом массиве:
String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
Его данные инициализируются и хранятся в двумерном Объектном массиве:
Object[][] data = { {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)}, {"John", "Doe", "Rowing", new Integer(3), new Boolean(true)}, {"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)}, {"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)}, {"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)} };
Затем Таблица создается, используя эти данные и columnNames:
JTable table = new JTable(data, columnNames);
Есть два JTable
конструкторы, которые непосредственно принимают данные (SimpleTableDemo
использует первое):
JTable(Object[][] rowData, Object[] columnNames)
JTable(Vector rowData, Vector columnNames)
Преимущество этих конструкторов состоит в том, что они удобны. Однако, у этих конструкторов также есть недостатки:
Boolean
данные, таблица может вывести на экран данные во флажке. Однако, если Вы используете любой из двух JTable
конструкторы перечисляли ранее, Ваш Boolean
данные выводятся на экран как строка. Можно видеть это различие в Vegetarian
столбец предыдущего числа.Если Вы хотите обойти эти ограничения, Вы должны реализовать свою собственную табличную модель, как описано в Создании Табличной Модели.
Вот типичный код для того, чтобы создать область прокрутки, которая служит контейнером для таблицы:
JScrollPane scrollPane = new JScrollPane(table); table.setFillsViewportHeight(true);
Эти две строки в этом отрывке делают следующее:
JScrollPane
конструктор вызывается с параметром, который обращается к табличному объекту. Это создает область прокрутки как контейнер для таблицы; таблица автоматически добавляется к контейнеру.JTable.setFillsViewportHeight
вызывается, чтобы установить fillsViewportHeight
свойство. Когда это свойство true
таблица использует весь height контейнера, даже если у таблицы нет достаточно многих строк, чтобы использовать целое вертикальное пространство. Это облегчает использовать таблицу в качестве цели перетаскивать-и-отбрасывать.Область прокрутки автоматически помещает табличный заголовок наверху области просмотра. Имена столбцов остаются видимыми наверху области просмотра, когда табличные данные прокручиваются.
Если Вы используете таблицу без области прокрутки, то следует получить табличный компонент заголовка и поместить его непосредственно. Например:
container.setLayout(new BorderLayout()); container.add(table.getTableHeader(), BorderLayout.PAGE_START); container.add(table, BorderLayout.CENTER);
По умолчанию все столбцы в таблице начинаются с равным width, и столбцы автоматически заполняют весь width таблицы. Когда таблица становится более широкой или более узкой (который мог бы произойти, когда пользователь изменяет размеры окна, содержащего таблицу), все ширины столбцов изменяются соответственно.
Когда пользователь изменяет размеры столбца, перетаскивая его правильную границу, тогда или другие столбцы должны изменить размер, или размер таблицы должен измениться. По умолчанию размер таблицы остается тем же самым, и все столбцы направо от перетащить точки изменяют размеры, чтобы разместить пространство, добавленное к или удаленный из столбца налево от перетащить точки.
Чтобы настроить начальные ширины столбцов, можно вызвать setPreferredWidth
на каждом из столбцов Вашей таблицы. Это устанавливает и привилегированные ширины столбцов и их приблизительные относительные ширины. Например, добавляя следующий код к SimpleTableDemo
делает его третий столбец больше чем другие столбцы:
TableColumn column = null; for (int i = 0; i < 5; i++) { column = table.getColumnModel().getColumn(i); if (i == 2) { column.setPreferredWidth(100); //third column is bigger } else { column.setPreferredWidth(50); } }
Поскольку предыдущий код показывает, каждый столбец в таблице представляется a TableColumn
объект. TableColumn
метод get предоставлений и методы метода set для минимума, предпочтенных, и максимальных ширин столбца, так же как метода для того, чтобы получить текущий width. Для примера установки ширин ячейки, основанных на приближении пространства, должен был потянуть содержание ячеек, видеть initColumnSizes
метод в TableRenderDemo.java
.
Когда пользователь явно изменяет размеры столбцов, привилегированные ширины столбцов устанавливаются так, что, определенные пользователем размеры становятся новыми текущими ширинами столбцов. Однако, когда сама таблица изменяется — обычно, потому что окно изменило размеры —; привилегированные ширины столбцов не изменяются. Вместо этого существующие привилегированные ширины используются, чтобы вычислить новые ширины столбцов, чтобы заполнить свободное место.
Можно измениться, таблица изменяют размеры поведения, вызывая setAutoResizeMode
.
В ее конфигурации значения по умолчанию таблица поддерживает выбор, который состоит из одной или более строк. Пользователь может выбрать непрерывный диапазон строк или произвольный набор строк. Последняя ячейка, на которую указал пользователь, получает специальную индикацию; в Металлическом стили обрисовывается в общих чертах ячейка. Эта ячейка известна как ведущий выбор; это иногда вызывают "ячейкой с фокусом" или "текущей ячейкой".
Пользователь использует мышь и/или клавиатуру, чтобы сделать выборы, как описано в следующей таблице:
Работа | Действие мыши | Действие клавиатуры |
---|---|---|
Выберите единственную строку. | Щелкнуть. | Стрелка вверх или Стрелка вниз. |
Расширьте непрерывный выбор. | Щелчок при нажатой клавише Shift или Перетаскивает по строкам. | Стрелка Shift-Up или Стрелка Shift-Down. |
Добавьте строку к выбору строки выбора/переключателя. | Щелчок управления | Переместите ведущий выбор со Стрелкой вверх управления или Стрелкой вниз управления, затем используйте клавишу "Пробел", чтобы добавить к выбору или клавише "Пробел" управления, чтобы переключить выбор строки. |
Чтобы видеть, как выборы работают, нажмите кнопку Launch, чтобы работать TableSelectionDemo
Этот пример программы представляет знакомую таблицу, и позволяет пользователю управлять определенными опциями JTable. Есть также текстовая область, которая регистрирует события выбора.
В снимке экрана ниже, пользователь выполнил программу, по которой щелкают в первой строке, тогда щелкнутой по управлению в третьей строке. Заметьте схему вокруг последней ячейки, по которой щелкают; это - то, как Металлический стиль выделяет ведущий выбор.
Под "Режимом выбора" есть ряд переключателей. Щелкните по тому маркированный "Единственный Выбор". Теперь можно только выбрать одну строку за один раз. Если Вы щелкаете по переключателю "Single Interval Selection", можно выбрать ряд строк, которые должны быть непрерывными.
Все переключатели под "Режимом выбора" вызывают JTable.setSelectionMode
javax.swing.ListSelectionModel
: MULTIPLE_INTERVAL_SELECTION
, SINGLE_INTERVAL_SELECTION
, и SINGLE_SELECTION
.
Возврат TableSelectionDemo
, заметьте три флажка опции под "Опциями Выбора." Каждый флажок управляет состоянием a boolean
связанная переменная, определенная JTable
:
rowSelectionAllowed
у которого есть метод метода set setRowSelectionAllowed
и метод метода get getRowSelectionAllowed
. Когда это связанное свойство true
(и columnSelectionAllowed
свойство false
), пользователь может выбрать строкой.columnSelectionAllowed
у которого есть метод метода set setColumnSelectionAllowed
и метод метода get getColumnSelectionAllowed
. Когда это связанное свойство true
(и rowSelectionAllowed
связанное свойство false
), пользователь может выбрать столбцом.cellSelectionEnabled
, у которого есть метод метода set setCellSelectionEnabled
и метод метода get getCellSelectionEnabled
. Когда это связанное свойство true
, пользователь может выбрать единственную ячейку или прямоугольный блок ячеек.JTable
использует очень простое понятие выбора, которым управляют как пересечение строк и столбцов. Это не было разработано, чтобы обработать полностью независимые выборы ячейки. Если Вы снимаете все три флажка (устанавливающий все три связанных свойства в false
), нет никакого выбора; только ведущий выбор показывают.
Можно заметить, что флажок "Cell Selection" отключается в многократном режиме выбора интервала. Это - то, потому что выбор ячейки не поддерживается в этом режиме в демонстрационном примере. Можно определить выбор ячейкой в многократном режиме выбора интервала, но результатом является таблица, которая не производит полезные выборы.
Можно также заметить, что изменение любой из трех опций выбора может влиять на другие. Это - то, потому что выбор разрешения и строки и выбор столбца являются точно тем же самым как включением выбору ячейки. JTable
автоматически обновляет эти три связанных переменные по мере необходимости, чтобы сохранить их непротиворечивыми.
cellSelectionEnabled
к значению имеет побочный эффект также установки обоих rowSelectionEnabled
и columnSelectionEnabled
к тому значению. Установка обоих rowSelectionEnabled
и columnSelectionEnabled
к значению имеет побочный эффект также установки cellSelectionEnabled
к тому значению. Установка rowSelectionEnabled
и columnSelectionEnabled
к различным значениям имеет побочный эффект также установки cellSelectionEnabled
к false
. Чтобы получить текущий выбор, использовать JTable.getSelectedRows
JTable.getSelectedColumns
String.format("Lead Selection: %d, %d. ", table.getSelectionModel().getLeadSelectionIndex(), table.getColumnModel().getSelectionModel().getLeadSelectionIndex());
Пользовательские выборы генерируют много событий. Для получения информации о них обратитесь к тому
Каждый табличный объект использует табличный объект модели управлять фактическими табличными данными. Табличный объект модели должен реализовать TableModel
интерфейс. Если программист не обеспечивает табличный объект модели, JTable
автоматически создает экземпляр DefaultTableModel
JTable
конструктор, используемый SimpleTableDemo
создает его табличную модель с кодом как это:
new AbstractTableModel() { public String getColumnName(int col) { return columnNames[col].toString(); } public int getRowCount() { return rowData.length; } public int getColumnCount() { return columnNames.length; } public Object getValueAt(int row, int col) { return rowData[row][col]; } public boolean isCellEditable(int row, int col) { return true; } public void setValueAt(Object value, int row, int col) { rowData[row][col] = value; fireTableCellUpdated(row, col); } }
Поскольку предыдущий код показывает, реализовывая табличную модель может быть простым. Обычно, Вы реализуете свою табличную модель в подклассе AbstractTableModel
Ваша модель могла бы содержать свои данные в массиве, векторе, или хешировать карту, или это могло бы получить данные от внешнего источника, такого как база данных. Во время выполнения это могло бы даже генерировать данные.
Эта таблица отличается от SimpleTableDemo
таблица следующими способами:
TableDemo
's пользовательская табличная модель, даже при том, что это просто, может легко определить тип данных, помогая JTable
выведите на экран данные в лучшем формате. SimpleTableDemo
's автоматически создаваемая табличная модель, с другой стороны, не знает, что столбец # of Years содержит числа (который должен обычно быть выровнен по правому краю и иметь определенный формат). Это также не знает что Vegetarian
столбец содержит булевы значения, которые могут быть представлены флажками.TableDemo
не позволяет Вам редактировать столбцы имени; это действительно, однако, позволяет Вам редактировать другие столбцы. В SimpleTableDemo
, все ячейки доступны для редактирования.См. ниже кода, взятого от TableDemo.java
это отличается от SimpleTableDemo.java
. Полужирный шрифт указывает на код, который делает модель этой таблицы отличающейся от табличной модели определенный автоматически для SimpleTableDemo
.
public TableDemo() { ... JTable table = new JTable(new MyTableModel()); ... } class MyTableModel extends AbstractTableModel { private String[] columnNames = ...//same as before... private Object[][] data = ...//same as before... public int getColumnCount() { return columnNames.length; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return columnNames[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } /* * Don't need to implement this method unless your table's * editable. */ public boolean isCellEditable(int row, int col) { //Note that the data/cell address is constant, //no matter where the cell appears onscreen. if (col < 2) { return false; } else { return true; } } /* * Don't need to implement this method unless your table's * data can change. */ public void setValueAt(Object value, int row, int col) { data[row][col] = value; fireTableCellUpdated(row, col); } ... }
У табличной модели может быть ряд слушателей, которые уведомляются всякий раз, когда табличные данные изменяются. Слушатели являются экземплярами TableModelListener
. В следующем примере кода, SimpleTableDemo
расширяется, чтобы включать такого слушателя. Новый код полужирным.
import javax.swing.event.*; import javax.swing.table.TableModel; public class SimpleTableDemo ... implements TableModelListener { ... public SimpleTableDemo() { ... table.getModel().addTableModelListener(this); ... } public void tableChanged(TableModelEvent e) { int row = e.getFirstRow(); int column = e.getColumn(); TableModel model = (TableModel)e.getSource(); String columnName = model.getColumnName(column); Object data = model.getValueAt(row, column); ...// Do something with the data... } ... }
Чтобы запустить события изменения данных, табличная модель должна знать, как создать a TableModelEvent
DefaultTableModel
. Можно или позволить JTable
использовать его экземпляр по умолчанию DefaultTableModel
, или создайте свой собственный подкласс DefaultTableModel
.
Если DefaultTableModel
не подходящий основной class для Вашей пользовательской табличной модели class, рассмотрите разделение на подклассы AbstractTableModel
TableModelEvent
объекты. Ваш пользовательский class просто должен вызвать один следующий AbstractTableModel
методы каждые данные расписания изменяются внешним источником.
Метод | Изменение |
---|---|
fireTableCellUpdated |
Обновление указанной ячейки. |
fireTableRowsUpdated |
Обновление указанных строк |
fireTableDataChanged |
Обновление всей таблицы (данные только). |
fireTableRowsInserted |
Вставляются новые строки. |
fireTableRowsDeleted |
Существующие Удаленные строки |
fireTableStructureChanged |
Лишите законной силы всю таблицу, и данные и структура. |
Прежде, чем Вы продолжите к следующим немногим задачам, Вы должны понять, как таблицы тянут свои ячейки. Вы могли бы ожидать, что каждая ячейка в таблице будет компонентом. Однако, по причинам производительности, таблицы Swing реализуются по-другому.
Вместо этого единственное средство рендеринга ячейки обычно используется, чтобы потянуть все ячейки, которые содержат тот же самый тип данных. Можно думать о средстве рендеринга как о конфигурируемом штампе чернил что табличное использование, чтобы штамповать соответственно отформатированные данные на каждую ячейку. Когда пользователь начинает редактировать данные ячейки, редактор ячейки принимает ячейку, управляя поведением редактирования ячейки.
Например, каждая ячейка в столбце # of Years в TableDemo
содержит Number
данные — определенно, Integer
объект. По умолчанию, средство рендеринга ячейки для a Number
- содержащий столбец использует сингл JLabel
экземпляр, чтобы потянуть соответствующие числа, выровненные по правому краю, на ячейках столбца. Если пользователь начинает редактировать одну из ячеек, редактор ячейки значения по умолчанию использует выровненное по правому краю JTextField
управлять редактированием ячейки.
Чтобы выбрать средство рендеринга, которое выводит на экран ячейки в столбце, таблица сначала определяет, определили ли Вы средство рендеринга для того определенного столбца. Если Вы не сделали, то таблица вызывает табличную модель getColumnClass
метод, который получает тип данных ячеек столбца. Затем, таблица сравнивает тип данных столбца со списком типов данных, для которых регистрируются средства рендеринга ячейки. Этот список инициализируется таблицей, но можно добавить к этому или изменить это. В настоящий момент, таблицы, помещенные следующие типы данных в списке:
Boolean
— представленный с флажком.Number
— представленный выровненной по правому краю меткой.Double
, Float
— то же самое как Number
, но объект к переводу текста выполняется a NumberFormat
Date
— представленный меткой, с объектом к переводу текста, выполняемым a DateFormat
ImageIcon
, Icon
— представленный центрируемой меткой.Object
— представленный меткой, которая выводит на экран строковое значение объекта.Редакторы ячейки выбираются, используя подобный алгоритм.
Помните, что, если Вы позволяете таблице создавать свою собственную модель, она использует Object
как тип каждого столбца. Чтобы определить более точные типы столбца, табличная модель должна определить getColumnClass
метод соответственно, как демонстрирующийся TableDemo.java
.
Имейте в виду, что, хотя средства рендеринга определяют, как каждая ячейка или взгляды заголовка столбца и могут определить свой текст подсказки, средство рендеринга не обрабатывает события. Если Вы должны поднять события, которые имеют место в таблице, метод, который Вы используете, изменяется видом события, которым Вы интересуетесь:
Ситуация | Как Получить События |
---|---|
Обнаружить события от ячейки, которая редактируется... | Используйте редактора ячейки (или зарегистрируйте слушателя на редакторе ячейки). |
Обнаружить выборы строки/столбца/ячейки и отмены выбора... | Используйте слушателя выбора как описано в Обнаружении Пользовательских Выборов. |
Обнаружить события от нажатия мыши на заголовке столбца... | Зарегистрируйте соответствующий тип слушателя мыши на таблице JTableHeader объект. (См. TableSorter.java для примера.) |
Обнаружить другие события... | Зарегистрируйте соответствующего слушателя на JTable объект. |
Следующие немного разделов говорят Вам, как настроить дисплей и редактирование, определяя средства рендеринга и редакторов. Можно определить средства рендеринга ячейки и редакторов или столбцом или типом данных.
Этот раздел говорит Вам, как создать и определить средство рендеринга ячейки. Можно установить специфичное для типа средство рендеринга ячейки, используя JTable
метод setDefaultRenderer
. Чтобы определить, что ячейки в определенном столбце должны использовать средство рендеринга, Вы используете TableColumn
метод setCellRenderer
. Можно даже определить специфичное для ячейки средство рендеринга, создавая a JTable
подкласс.
Легко настроить текст или изображение, представленное средством рендеринга значения по умолчанию, DefaultTableCellRenderer
. Вы только создаете подкласс и реализуете setValue
метод так, чтобы это вызвало setText
или setIcon
с соответствующей строкой или изображением. Например, вот то, как средство рендеринга даты значения по умолчанию реализуется:
static class DateRenderer extends DefaultTableCellRenderer { DateFormat formatter; public DateRenderer() { super(); } public void setValue(Object value) { if (formatter==null) { formatter = DateFormat.getDateInstance(); } setText((value == null) ? "" : formatter.format(value)); } }
Расширяясь DefaultTableCellRenderer
недостаточно, можно создать средство рендеринга, используя другой суперкласс. Самый легкий путь состоит в том, чтобы создать подкласс существующего компонента, заставляя Ваш подкласс реализовать TableCellRenderer
интерфейс. TableCellRenderer
требует только одного метода: getTableCellRendererComponent
. Ваша реализация этого метода должна установить компонент рендеринга, чтобы отразить переданный - в состоянии, и затем возвратить компонент.
В снимке TableDialogEditDemo
, средство рендеринга, используемое для Любимых Цветных ячеек, является подклассом JLabel
вызванный ColorRenderer
. Вот выборки от ColorRenderer.java
то шоу, как это реализуется.
public class ColorRenderer extends JLabel implements TableCellRenderer { ... public ColorRenderer(boolean isBordered) { this.isBordered = isBordered; setOpaque(true); //MUST do this for background to show up. } public Component getTableCellRendererComponent( JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { Color newColor = (Color)color; setBackground(newColor); if (isBordered) { if (isSelected) { ... //selectedBorder is a solid border in the color //table.getSelectionBackground(). setBorder(selectedBorder); } else { ... //unselectedBorder is a solid border in the color //table.getBackground(). setBorder(unselectedBorder); } } setToolTipText(...); //Discussed in the following section return this; } }
Вот код от TableDialogEditDemo.java
это регистрирует a ColorRenderer
экземпляр как средство рендеринга значения по умолчанию для всех Color
данные:
table.setDefaultRenderer(Color.class, new ColorRenderer(true));
Чтобы определить специфичное для ячейки средство рендеринга, Вы должны определить a JTable
подкласс, который переопределяет getCellRenderer
метод. Например, следующий код заставляет первую ячейку в первом столбце таблицы использовать пользовательское средство рендеринга:
TableCellRenderer weirdRenderer = new WeirdRenderer(); table = new JTable(...) { public TableCellRenderer getCellRenderer(int row, int column) { if ((row == 0) && (column == 0)) { return weirdRenderer; } // else... return super.getCellRenderer(row, column); } };
По умолчанию текст подсказки, выведенный на экран для табличной ячейки, определяется средством рендеринга ячейки. Однако, иногда может быть более просто определить текст подсказки, переопределяя JTable
's реализация getToolTipText(MouseEvent)
метод. Этот раздел показывает Вам, как использовать оба метода.
Чтобы добавить подсказку к ячейке, используя ее средство рендеринга, Вы сначала должны получить или создать средство рендеринга ячейки. Затем, после удостоверения компонента рендеринга a JComponent
, вызовите setToolTipText
метод на этом.
Пример установки подсказок для ячеек находится в TableRenderDemo
. Нажмите кнопку Launch, чтобы работать, она использующий Сеть Java™ Запускается (
Исходный код находится в TableRenderDemo.java
. Это добавляет подсказки к ячейкам столбца Sport со следующим кодом:
//Set up tool tips for the sport cells. DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); renderer.setToolTipText("Click for combo box"); sportColumn.setCellRenderer(renderer);
Хотя текст подсказки в предыдущем примере статичен, можно также реализовать подсказки, текст которых изменяется в зависимости от состояния ячейки или программы. Вот пара способов сделать так:
getTableCellRendererComponent
метод.JTable
метод getToolTipText(MouseEvent)
.Пример добавляющего кода к средству рендеринга ячейки находится в TableDialogEditDemo
. Нажмите кнопку Launch, чтобы работать, она использующий Сеть Java™ Запускается (
TableDialogEditDemo
использует средство рендеринга для цветов, реализованных в ColorRenderer.java
, это устанавливает текст подсказки, используя полужирный код в следующем отрывке:
public class ColorRenderer extends JLabel implements TableCellRenderer { ... public Component getTableCellRendererComponent( JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { Color newColor = (Color)color; ... setToolTipText("RGB value: " + newColor.getRed() + ", " + newColor.getGreen() + ", " + newColor.getBlue()); return this; } }
Вот пример того, на что похожа подсказка:
Можно определить текст подсказки, переопределяя JTable
's getToolTipText(MouseEvent)
метод. Программа TableToolTipsDemo
шоу, как. Нажмите кнопку Launch, чтобы работать, она использующий Сеть Java™ Запускается (
Ячейки с подсказками находятся в столбцах Sport и Vegetarian. Вот изображение его подсказки:
Вот код от TableToolTipsDemo.java
это реализует подсказки для ячеек в столбцах Sport и Vegetarian:
JTable table = new JTable(new MyTableModel()) { //Implement table cell tool tips. public String getToolTipText(MouseEvent e) { String tip = null; java.awt.Point p = e.getPoint(); int rowIndex = rowAtPoint(p); int colIndex = columnAtPoint(p); int realColumnIndex = convertColumnIndexToModel(colIndex); if (realColumnIndex == 2) { //Sport column tip = "This person's favorite sport to " + "participate in is: " + getValueAt(rowIndex, colIndex); } else if (realColumnIndex == 4) { //Veggie column TableModel model = getModel(); String firstName = (String)model.getValueAt(rowIndex,0); String lastName = (String)model.getValueAt(rowIndex,1); Boolean veggie = (Boolean)model.getValueAt(rowIndex,4); if (Boolean.TRUE.equals(veggie)) { tip = firstName + " " + lastName + " is a vegetarian"; } else { tip = firstName + " " + lastName + " is not a vegetarian"; } } else { //another column //You can omit this part if you know you don't //have any renderers that supply their own tool //tips. tip = super.getToolTipText(e); } return tip; } ... }
Код является довольно прямым, кроме, возможно, для звонка convertColumnIndexToModel
. Тот вызов необходим, потому что, если пользователь перемещает столбцы, представление индексирует для столбца, не будет соответствовать, модель индексируют для столбца. Например, пользователь мог бы перетащить столбец Vegetarian (который модель рассматривает, чтобы быть в, индексируют 4), таким образом, это выводится на экран, поскольку первый столбец — при представлении индексирует 0. С тех пор prepareRenderer
обеспечивает представление индексируют, Вы должны преобразовать представление, индексируют к модели, индексируют так, можно убедиться, что намеченный столбец был выбран.
Можно добавить подсказку к заголовку столбца, устанавливая текст подсказки для таблицы JTableHeader
. Часто, различные заголовки столбца требуют различного текста подсказки. Можно изменить текст, переопределяя табличный заголовок getToolTipText
метод. Поочередно, можно вызвать TableColumn.setHeaderRenderer
обеспечить пользовательское средство рендеринга для заголовка.
Пример использования того же самого текста подсказки для всех заголовков столбца находится в TableSorterDemo.java
. Вот то, как это устанавливает текст подсказки:
table.getTableHeader().setToolTipText( "Click to sort; Shift-Click to sort in reverse order");
TableToolTipsDemo.java
имеет пример реализации подсказок заголовка столбца, которые изменяются столбцом. Если Вы работаете TableToolTipsDemo
(нажмите кнопку Launch), использующий Сеть Java™ Запускаются (
Вы будете видеть подсказки когда Вы мышь по любому заголовку столбца за исключением первых двух. Никакие подсказки не были suppled для столбцов имени, так как они казались очевидными. Вот изображение одной из подсказок заголовка столбца:
Следующий код реализует подсказки. В основном это создает подкласс JTableHeader
это переопределяет getToolTipText(MouseEvent)
метод так, чтобы это возвратило текст для текущего столбца. Связать пересмотренный табличный заголовок с таблицей, JTable
метод createDefaultTableHeader
переопределяется так, чтобы это возвратило экземпляр JTableHeader
подкласс.
protected String[] columnToolTips = { null, // "First Name" assumed obvious null, // "Last Name" assumed obvious "The person's favorite sport to participate in", "The number of years the person has played the sport", "If checked, the person eats no meat"}; ... JTable table = new JTable(new MyTableModel()) { ... //Implement table header tool tips. protected JTableHeader createDefaultTableHeader() { return new JTableHeader(columnModel) { public String getToolTipText(MouseEvent e) { String tip = null; java.awt.Point p = e.getPoint(); int index = columnModel.getColumnIndexAtX(p.x); int realIndex = columnModel.getColumn(index).getModelIndex(); return columnToolTips[realIndex]; } }; } };
Табличной сортировкой и фильтрацией управляет объект сортировщика. Самый легкий способ обеспечить объект сортировщика состоит в том, чтобы установить autoCreateRowSorter
связанное свойство к true
:
JTable table = new JTable(); table.setAutoCreateRowSorter(true);
Это действие определяет сортировщика строки, который является экземпляром javax.swing.table.TableRowSorter
, как замечено в этом снимке экрана:TableSortDemo.java
Чтобы иметь больше контроля над сортировкой, можно создать экземпляр TableRowSorter
и определите, что это - объект сортировщика для Вашей таблицы.
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()); table.setRowSorter(sorter);
TableRowSorter
использование java.util.Comparator
объекты сортировать его строки. class, который реализует этот интерфейс, должен обеспечить вызванный метод compare
это определяет, как любые два объекта сравниваются с целью сортировки. Например, следующий код создает a Comparator
это сортирует ряд строк последним словом в каждой строке:
Comparator<String> comparator = new Comparator<String>() { public int compare(String s1, String s2) { String[] strings1 = s1.split("\\s"); String[] strings2 = s2.split("\\s"); return strings1[strings1.length - 1] .compareTo(strings2[strings2.length - 1]); } };
Этот пример довольно упрощен; более обычно, a Comparator
реализация является подклассом java.text.Collator
Collator
получить a Comparator
для определенной локали, или использования java.text.RuleBasedCollator
Определить который Comparator
использовать для столбца, TableRowSorter
попытки применить каждое из следующих правил поочередно. Правила сопровождаются в упомянутом ниже порядке; первое правило, которое предоставляет сортировщику a Comparator
используется, и проигнорированные правила remainining.
setComparator
TableModel.getColumnClass
возвраты String.class
для того столбца), используйте компаратор, который сортирует строки, основанные на текущей локали.TableModel.getColumnClass
реализации Comparable
, используйте компаратор, который сортирует строки, основанные на значениях, возвращенных Comparable.compareTo
setStringConverter
toString
на данных столбца и видах получающиеся строки, основанные на текущей локали.Для более сложных видов сортировки, подкласса TableRowSorter
или его родительский class javax.swing.DefaultRowSorter
Чтобы определить порядок сортировки и приоритет вида для столбцов, вызвать setSortKeys
List <RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>(); sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING)); sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); sorter.setSortKeys(sortKeys);
В дополнение к переупорядочению результатов табличный сортировщик может также определить, какие строки будут выведены на экран. Это известно как фильтрация. TableRowSorter
использование фильтрации реализаций javax.swing.RowFilter
RowFilter
реализации несколько методов фабрики, которые создают общие виды фильтров. Например, regexFilter
RowFilter
это фильтрует основанный на
В следующем примере кода Вы явно создаете объект сортировщика, таким образом, можно позже использовать его, чтобы определить фильтр:
MyTableModel model = new MyTableModel(); sorter = new TableRowSorter<MyTableModel>(model); table = new JTable(model); table.setRowSorter(sorter);
Затем Вы фильтруете основанный на текущей стоимости текстового поля:
private void newFilter() { RowFilter<MyTableModel, Object> rf = null; //If current expression doesn't parse, don't update. try { rf = RowFilter.regexFilter(filterText.getText(), 0); } catch (java.util.regex.PatternSyntaxException e) { return; } sorter.setRowFilter(rf); }
В последующем примере, newFilter()
вызывается каждый раз изменения текстового поля. Когда пользователь вводит сложные регулярные выражения, try...catch
препятствует тому, чтобы исключение синтаксиса вмешалось во ввод.
Когда таблица использует сортировщика, данные, которые видят пользователи, могут быть в различном порядке чем определенное по условию модель, и, возможно, не включают все строки, определенные по условию модель. Данные, которые фактически видит пользователь, известны как представление, и имеют свой собственный набор координат. JTable
обеспечивает методы, которые преобразовывают из координат модели, чтобы просмотреть координаты — convertColumnIndexToView
и convertRowIndexToView
convertColumnIndexToModel
convertRowIndexToModel
Следующий пример объединяет идеи, обсужденные в этом разделе.
добавляет небольшое количество изменений к TableFilterDemo.java
TableDemo
. Они включают фрагменты кода ранее в этот раздел, которые предоставляют сортировщику для основной таблицы, и используют текстовое поле, чтобы предоставить регулярное выражение фильтрации. Следующие шоу снимка экрана TableFilterDemo
перед любой сортировкой или фильтрацией был сделан. Заметьте, что строка 3 в модели является все еще тем же самым как строкой 3 в представлении:
Если пользователь щелкает дважды по второму столбцу, четвертая строка становится первой строкой — но только в представлении:
Как ранее отмечено, текст, который пользователь вводит в текстовое поле "Filter Text", определяет фильтр, который определяет, какие строки показывают. Как с сортировкой, фильтрация может заставить координаты представления отклоняться от координат модели:
Вот код, который обновляет поле состояния, чтобы отразить текущий выбор:
table.getSelectionModel().addListSelectionListener( new ListSelectionListener() { public void valueChanged(ListSelectionEvent event) { int viewRow = table.getSelectedRow(); if (viewRow < 0) { //Selection got filtered away. statusText.setText(""); } else { int modelRow = table.convertRowIndexToModel(viewRow); statusText.setText( String.format("Selected Row in view: %d. " + "Selected Row in model: %d.", viewRow, modelRow)); } } } );
Устанавливая поле комбинированного списка, поскольку редактор прост как следующие шоу в качестве примера. Полужирная строка кодовых наборов поле комбинированного списка как редактор для определенного столбца.
TableColumn sportColumn = table.getColumnModel().getColumn(2); ... JComboBox comboBox = new JComboBox(); comboBox.addItem("Snowboarding"); comboBox.addItem("Rowing"); comboBox.addItem("Chasing toddlers"); comboBox.addItem("Speed reading"); comboBox.addItem("Teaching high school"); comboBox.addItem("None"); sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
Вот изображение редактора поля комбинированного списка в использовании:
Предыдущий код от TableRenderDemo.java
. Можно работать TableRenderDemo
(нажмите кнопку Launch), использующий Сеть Java™ Запускаются (
Устанавливаете ли Вы редактора для единственного столбца ячеек (использующий TableColumn
setCellEditor
метод) или для определенного типа данных (использующий JTable
setDefaultEditor
метод), Вы определяете редактора, использующего параметр, который придерживается TableCellEditor
интерфейс. К счастью, DefaultCellEditor
class реализует этот интерфейс и предоставляет конструкторам, чтобы позволить Вам определять компонент редактирования, который является a JTextField
, JCheckBox
, или JComboBox
. Обычно Вы не должны явно определить флажок как редактора, начиная со столбцов с Boolean
данные автоматически используют средство рендеринга флажка и редактора.
Что, если Вы хотите определить редактора кроме текстового поля, флажка, или поля комбинированного списка? Как DefaultCellEditor
не поддерживает другие типы компонентов, следует сделать немного больше работы. Вы должны создать class, который реализует TableCellEditor
AbstractCellEditor
TableCellEditor
's суперинтерфейс, CellEditor
Ваш редактор ячейки class должен определить по крайней мере два метода — getCellEditorValue
и getTableCellEditorComponent
. getCellEditorValue
метод, требуемый CellEditor
, возвращает текущую стоимость ячейки. getTableCellEditorComponent
метод, требуемый TableCellEditor
, должен сконфигурировать и возвратить компонент, который Вы хотите использовать в качестве редактора.
Вот изображение таблицы с диалоговым окном, которое служит, косвенно, как редактор ячейки. Когда пользователь начинает редактировать ячейку в столбце Favorite Color, кнопка (истинный редактор ячейки) появляется и переводит в рабочее состояние диалоговое окно, с которым пользователь может выбрать различный цвет.
Можно работать TableDialogEditDemo
(нажмите кнопку Launch), использующий
Вот код, взятый от ColorEditor.java
, это реализует редактора ячейки.
public class ColorEditor extends AbstractCellEditor implements TableCellEditor, ActionListener { Color currentColor; JButton button; JColorChooser colorChooser; JDialog dialog; protected static final String EDIT = "edit"; public ColorEditor() { button = new JButton(); button.setActionCommand(EDIT); button.addActionListener(this); button.setBorderPainted(false); //Set up the dialog that the button brings up. colorChooser = new JColorChooser(); dialog = JColorChooser.createDialog(button, "Pick a Color", true, //modal colorChooser, this, //OK button handler null); //no CANCEL button handler } public void actionPerformed(ActionEvent e) { if (EDIT.equals(e.getActionCommand())) { //The user has clicked the cell, so //bring up the dialog. button.setBackground(currentColor); colorChooser.setColor(currentColor); dialog.setVisible(true); fireEditingStopped(); //Make the renderer reappear. } else { //User pressed dialog's "OK" button. currentColor = colorChooser.getColor(); } } //Implement the one CellEditor method that AbstractCellEditor doesn't. public Object getCellEditorValue() { return currentColor; } //Implement the one method defined by TableCellEditor. public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { currentColor = (Color)value; return button; } }
Как можно видеть, код довольно прост. Единственная часть, которая немного хитра, является звонком fireEditingStopped
в конце обработчика действия кнопки редактора. Без этого вызова редактор остался бы активным, даже при том, что модальное диалоговое окно больше не видимо. Звонок fireEditingStopped
позволяет таблице знать, что она может деактивировать редактора, позволяя ячейке быть обработанным средством рендеринга снова.
Если редактор значения по умолчанию ячейки позволяет ввод текста, Вы получаете некоторую проверку на ошибки бесплатно, если тип ячейки определяется как что-то другое чем String
или Object
. Проверка на ошибки является побочным эффектом преобразования вводимого текста в объект надлежащего типа.
Автоматическая проверка вводимых пользователем строк происходит, когда редактор значения по умолчанию пытается создать новый экземпляр class, связанного со столбцом ячейки. Редактор значения по умолчанию создает этот экземпляр, используя конструктора, который берет a String
как параметр. Например, в столбце, у ячеек которого есть тип Integer
, когда пользователь вводит "123", редактор значения по умолчанию создает соответствие Integer
использование кода, эквивалентного new Integer("123")
. Если конструктор выдает исключение, схема ячейки покраснела и отказывается позволить фокусу перемещаться из ячейки. Если Вы реализуете class, используемый в качестве типа данных столбца, можно использовать редактора значения по умолчанию, если Ваш class предоставляет конструктора, который берет единственный параметр типа String
.
Если Вы любите иметь текстовое поле как редактор для ячейки, но хотите настроить это — возможно, чтобы проверить вводимый пользователем текст более строго или реагировать по-другому, когда текст недопустим — можно изменить редактора ячейки, чтобы использовать отформатированное текстовое поле. Отформатированное текстовое поле может проверить значение или непрерывно в то время как пользователь вводит или после того, как пользователь указал на конец ввода (такой, поскольку нажатием Входят).
Следующий код, взятый от демонстрационного примера, называют TableFTFEditDemo.java
, устанавливает отформатированное текстовое поле как редактора, который ограничивает все целочисленные значения, чтобы быть между 0 и 100. Можно работать TableFTFEditDemo
(нажмите кнопку Launch), использующий Сеть Java™ Запускаются (
Следующий код делает отформатированное текстовое поле редактором для всех столбцов, которые содержат данные типа Integer
.
table.setDefaultEditor(Integer.class, new IntegerEditor(0, 100));
IntegerEditor
class реализуется как подкласс DefaultCellEditor
JFormattedTextField
вместо JTextField
это DefaultCellEditor
поддерживает. Это выполняет это первой установкой отформатированного текстового поля, чтобы использовать целочисленный формат и иметь указанные минимальные и максимальные значения, используя API, описанный в том, Как Использовать Отформатированные Текстовые поля. Это тогда переопределяет DefaultCellEditor
реализация getTableCellEditorComponent
, getCellEditorValue
, и stopCellEditing
методы, добавляя операции, которые необходимы для отформатированных текстовых полей.
Переопределение getTableCellEditorComponent
устанавливает свойство значения отформатированного текстового поля (и не только текстовое свойство, от которого оно наследовалось JTextField
) прежде, чем редактора показывают. Переопределение getCellEditorValue
сохраняет значение ячейки как Integer
, а не, скажем, Long
значение, которое синтаксический анализатор отформатированного текстового поля имеет тенденцию возвращать. Наконец, переопределение stopCellEditing
позволяет Вам проверять, допустим ли текст, возможно мешая редактору быть отклоненным. Если текст не допустим, Ваша реализация stopCellEditing
поднимает диалоговое окно, которое дает пользователю опцию продолжения отредактировать или возвращение к последнему хорошему значению. Исходный код является немного слишком длинным, чтобы включать здесь, но можно найти это в IntegerEditor.java
.
JTable
обеспечивает простой API для того, чтобы он напечатал таблицы. Самый легкий способ распечатать таблицу состоит в том, чтобы вызвать JTable.print
без параметров:
try { if (! table.print()) { System.err.println("User cancelled printing"); } } catch (java.awt.print.PrinterException e) { System.err.format("Cannot print %s%n", e.getMessage()); }
Вызов print
на нормальном Swing приложение переводит стандартное диалоговое окно печати в рабочее состояние. (На бездисплейном приложении просто печатается таблица.) Возвращаемое значение указывает, продолжил ли пользователь задание печати или отменил это. JTable.print
может бросить java.awt.print.PrinterException
, который является try ... catch
.
JTable
обеспечивает несколько перегрузок print
с различными вариантами. Следующий код от
шоу, как определить верхний колонтитул страницы:TablePrintDemo.java
MessageFormat header = new MessageFormat("Page {0,number,integer}"); try { table.print(JTable.PrintMode.FIT_WIDTH, header, null); } catch (java.awt.print.PrinterException e) { System.err.format("Cannot print %s%n", e.getMessage()); }
Для более сложных приложений печати использовать JTable.getPrintable
получить a Printable
объект для таблицы. Для больше на Printable
, обратитесь к уроку
Эта таблица приводит примеры то использование JTable
и где те примеры описываются.
Пример | Где Описано | Примечания |
---|---|---|
SimpleTableDemo |
Составление Простой Таблицы | Основная таблица без пользовательской модели. Не включает код, чтобы определить ширины столбцов или обнаружить пользователя, редактирующего. |
SimpleTable- |
Обнаружение Пользовательских Выборов | Добавляет единственное обнаружение выбора и выбора к SimpleTableDemo . Изменяя программу ALLOW_COLUMN_SELECTION и ALLOW_ROW_SELECTION константы, можно экспериментировать с альтернативами табличному значению по умолчанию разрешения только строк, которые будут выбраны. |
TableDemo |
Создание Табличной Модели | Основная таблица с пользовательской моделью. |
TableFTFEditDemo |
Используя Редактора, чтобы Проверить Вводимого пользователем текста | Изменяет TableDemo использовать пользовательского редактора (отформатированная разновидность текстового поля) для всех Integer данные. |
TableRenderDemo |
Используя Поле комбинированного списка как Редактор | Изменяет TableDemo использовать пользовательского редактора (поле комбинированного списка) для всех данных в столбце Sport. Также разумно размеры столбца выборов. Средства рендеринга использования, чтобы вывести на экран подсказки для спортивных ячеек. |
TableDialogEditDemo |
Используя Других Редакторов | Изменяет TableDemo иметь средство рендеринга ячейки и редактора, которые выводят на экран цвет и позволяют Вам выбирать новый, используя цветное диалоговое окно селектора. |
TableToolTipsDemo |
Определение Подсказок для Ячеек, Определение Подсказок для Заголовков Столбца, | Демонстрирует, как использовать несколько методов, чтобы установить текст подсказки для заголовков столбца и ячеек. |
TableSortDemo |
Сортировка и Фильтрация | Демонстрирует сортировщика значения по умолчанию, который позволяет пользователю сортировать столбцы, щелкая по их заголовкам. |
TableFilterDemo |
Сортировка и Фильтрация | Демонстрирует, как сортировать и фильтровать, и как это может заставить координаты представления отклоняться от координат модели. |
TablePrintDemo |
Печать | Демонстрирует табличную печать. |
ListSelectionDemo |
Как Записать Слушателю Выбора Списка | Шоу, как использовать все режимы выбора списка, используя слушателя выбора списка, это совместно используется таблицей и списком. |
SharedModelDemo |
Нигде | Основывается ListSelectionDemo создание модели данных быть совместно использованным таблицей и списком. Если Вы редактируете элемент в первом столбце таблицы, новое значение отражается в списке. |