Статьи

Редактирование строки таблицы в Apache Pivot

Традиционно считается, что существует два способа редактирования данных таблицы. Вы можете использовать встроенный редактор ячеек или запустить диалог редактирования, который позволяет редактировать всю запись за раз. Разве не было бы замечательно, если бы мы могли получить лучшее из обоих миров и отредактировать всю запись inline? Как оказалось, Apache Pivot предоставляет этот тип редактора строк таблицы из коробки. Ниже приведен простой пример использования этой полезной функции.

На следующем рисунке показан снимок экрана демонстрационного приложения, которое мы рассмотрим. Живой пример доступен здесь . Приложение содержит небольшой набор образцов данных, которые можно редактировать, дважды щелкнув строку.

Пример приложения для редактирования строк

Источник WTKX для демонстрации выглядит следующим образом:

<Window title="Row Editor Demo"
maximized="true"
xmlns:wtkx="http://incubator.apache.org/pivot/wtkx/1.1"
xmlns:collections="pivot.collections"
xmlns:content="pivot.wtk.content"
xmlns:demo="pivot.demos.roweditor"
xmlns="pivot.wtk">
<content>
<Border styles="{padding:0}">
<content>
<ScrollPane horizontalScrollBarPolicy="fillToCapacity">
<view>
<TableView wtkx:id="tableView" selectMode="single">
<columns>
<TableView.Column name="date" width="87" headerData="Date"/>
<TableView.Column name="type" width="125" headerData="Type"/>
<TableView.Column name="amount" width="75" headerData="Amount">
<cellRenderer>
<content:TableViewNumberCellRenderer numberFormat="¤#,##0.00"/>
</cellRenderer>
</TableView.Column>
<TableView.Column name="description" width="1*" headerData="Description"/>
</columns>
<tableData>
<collections:ArrayList>
<demo:CustomTableRow date="2009-03-28" type="Travel"
amount="1286.90" description="Ticket #145-XX-71903-09"/>
<demo:CustomTableRow date="2009-03-28" type="Meals"
amount="34.12" description="Took client out"/>
<demo:CustomTableRow date="2009-03-31" type="Meals"
amount="27.00" description=""/>
<demo:CustomTableRow date="2009-04-01" type="Meals"
amount="12.55" description=""/>
<demo:CustomTableRow date="2009-04-02" type="Meals"
amount="18.86" description=""/>
<demo:CustomTableRow date="2009-04-02" type="Parking"
amount="30.00" description="Cambridge Center parking"/>
<demo:CustomTableRow date="2009-04-03" type="Meals"
amount="20.72" description=""/>
<demo:CustomTableRow date="2009-04-06" type="Hotel"
amount="529.90" description="Marriott reservation #DF-9982-BRN"/>
</collections:ArrayList>
</tableData>
</TableView>
</view>
<columnHeader>
<TableViewHeader tableView="$tableView" styles="{headersPressable:false}"/>
</columnHeader>
</ScrollPane>
</content>
</Border>
</content>
</Window>

Он содержит развернутое окно без декораций с границей в качестве содержимого. Граница содержит ScrollPane, содержащий данные. Для демонстрации я жестко закодировал образцы данных в WTKX. Существует четыре столбца: дата, вид расходов, сумма и описание. Для суммы я использую средство визуализации ячеек, которое форматирует число как валюту.

Основной класс приложения

Поскольку в Pivot есть редактор строк табличного представления по умолчанию, для запуска и запуска демоверсии не так уж и много. Однако редактор строк по умолчанию будет использовать экземпляры TextInput для отдельных редакторов ячеек, если мы не укажем иное. В этом случае я хотел сделать несколько изменений. На сегодняшний день я хотел использовать Spinner с пользовательской моделью данных. Для типа расходов я хотел ListButton, который позволял бы пользователю выбирать среди различных значений перечисления для типа расходов. Наконец, для суммы я хотел TextInput, который будет проверять текст так, что будут приниматься только допустимые значения валюты.

Метод запуска () приложения — это основная часть работы; это показано ниже:

public void startup(Display display, Dictionary<String, String> properties)
throws Exception {
WTKXSerializer wtkxSerializer = new WTKXSerializer();
window = (Window)wtkxSerializer.readObject(getClass().getResource("demo.wtkx"));
window.open(display);

TableView tableView = (TableView)wtkxSerializer.getObjectByName("tableView");
TableViewRowEditor tableViewRowEditor = new TableViewRowEditor();
tableView.setRowEditor(tableViewRowEditor);

// Date uses a Spinner with a CalendarDateSpinnerData model
Spinner dateSpinner = new Spinner(new CalendarDateSpinnerData());
dateSpinner.setSelectedItemKey("date");
tableViewRowEditor.getCellEditors().put("date", dateSpinner);

// Expense type uses a ListButton that presents the expense types
ListButton typeListButton = new ListButton
(new EnumList<ExpenseType>(ExpenseType.class));
typeListButton.setSelectedItemKey("type");
tableViewRowEditor.getCellEditors().put("type", typeListButton);

// Amount uses a TextInput with strict currency validation
TextInput amountTextInput = new TextInput();
amountTextInput.setValidator(new CurrencyValidator());
amountTextInput.getStyles().put("strictValidation", true);
amountTextInput.setTextKey("amount");
tableViewRowEditor.getCellEditors().put("amount", amountTextInput);
}

Сначала создается экземпляр сериализатора WTKX для загрузки пользовательского интерфейса из файла WTKX. Затем он получает ссылку на табличное представление и устанавливает редактор строк на табличное представление. Наконец, он вносит необходимые изменения в редактор строк, создавая три пользовательских компонента редактора ячеек и сопоставляя их с соответствующими столбцами с помощью метода getCellEditors () редактора строк. Обратите внимание, что редактор строк использует средства привязки данных Pivot для передачи данных из строки в компоненты редактора ячеек и для возврата данных, когда пришло время сохранить пользовательские изменения. Обратите внимание, как я настраивал ключи привязки данных в каждом созданном мной редакторе ячеек.

Поддержка классов

Последними частями головоломки являются вспомогательные классы, которые я использовал в демоверсии: CurrencyValidator, CustomTableRow и ExpenseType. Сначала давайте посмотрим на валидатор:

public class CurrencyValidator implements Validator {
public boolean isValid(String text) {
boolean valid = true;

if (text.length() > 0) {
try {
BigDecimal numericAmount = new BigDecimal(text);
valid = (numericAmount.scale() <= 2
&& numericAmount.signum() >= 0);
} catch (NumberFormatException ex) {
valid = false;
}
}

return valid;
}
}

Этот валидатор просто гарантирует, что текст в текстовом вводе суммы может быть представлен как положительный BigDecimal с десятичной точностью, меньшей или равной 2.

Источник для CustomTableRow выглядит следующим образом:

public class CustomTableRow {
private CalendarDate calendarDate = null;
private ExpenseType type = null;
private double amount = 0;
private String description = null;

public CalendarDate getDate() {
return calendarDate;
}

public void setDate(CalendarDate calendarDate) {
this.calendarDate = calendarDate;
}

public final void setDate(String calendarDate) {
setDate(new CalendarDate(calendarDate));
}

public ExpenseType getType() {
return type;
}

public void setType(ExpenseType type) {
this.type = type;
}

public final void setType(String type) {
setType(ExpenseType.valueOf(type));
}

public double getAmount() {
return amount;
}

public void setAmount(double amount) {
this.amount = amount;
}

public final void setAmount(String amount) {
if (amount == null || amount.length() == 0) {
setAmount(0);
} else {
setAmount(Double.parseDouble(amount));
}
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}

Это простой объект значений с несколькими перегрузками. Первая перегрузка, setDate (String), должна поддерживать создание CustomTableRow в WTKX. Второе, setAmount (String), должно поддерживать привязку количества строк таблицы к TextInput.

Наконец, давайте посмотрим на перечисление ExpenseType:

public enum ExpenseType {
Hotel,
Miscellaneous,
Meals,
Parking,
Travel;
}

Для простоты я использовал понятные человеку значения в enum и представил значения, используя набор EnumList в качестве модели моего ListButton. Если бы это было реальное приложение, я должен был бы рассмотреть локализацию и, вероятно, использовал бы собственный ListView.ItemRenderer на кнопке списка.

Вывод

Итак, создать редактор строк табличного представления, который позволяет пользователю редактировать всю запись в строке, очень легко с помощью Pivot, и это удобная новая метафора пользовательского интерфейса для редактирования данных таблицы. Обратите внимание, что интерфейс TableView.RowEditor в Pivot не мешает разработчику приложения создавать более традиционный редактор (фактически, Pivot также включает в себя стандартный TableViewCellEditor), оставляя ваши параметры открытыми в отношении того, какая парадигма наиболее подходит для вас.

Полный исходный код этой демонстрации доступен здесь . Для получения дополнительной информации об Apache Pivot посетите веб- сайт http://incubator.apache.org/pivot .