/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pivot.tutorials;
import java.awt.Color;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.Comparator;
import org.apache.pivot.beans.BXMLSerializer;
import org.apache.pivot.collections.ArrayList;
import org.apache.pivot.collections.HashMap;
import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Map;
import org.apache.pivot.json.JSONSerializer;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.util.CalendarDate;
import org.apache.pivot.util.Filter;
import org.apache.pivot.util.Vote;
import org.apache.pivot.wtk.Action;
import org.apache.pivot.wtk.ActivityIndicator;
import org.apache.pivot.wtk.Alert;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.ApplicationContext;
import org.apache.pivot.wtk.Border;
import org.apache.pivot.wtk.Button;
import org.apache.pivot.wtk.ButtonGroup;
import org.apache.pivot.wtk.ButtonPressListener;
import org.apache.pivot.wtk.Component;
import org.apache.pivot.wtk.ComponentMouseButtonListener;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.DragSource;
import org.apache.pivot.wtk.DropAction;
import org.apache.pivot.wtk.DropTarget;
import org.apache.pivot.wtk.ImageView;
import org.apache.pivot.wtk.Label;
import org.apache.pivot.wtk.ListButton;
import org.apache.pivot.wtk.ListView;
import org.apache.pivot.wtk.LocalManifest;
import org.apache.pivot.wtk.Manifest;
import org.apache.pivot.wtk.Menu;
import org.apache.pivot.wtk.MenuHandler;
import org.apache.pivot.wtk.MessageType;
import org.apache.pivot.wtk.Mouse;
import org.apache.pivot.wtk.Point;
import org.apache.pivot.wtk.Prompt;
import org.apache.pivot.wtk.PushButton;
import org.apache.pivot.wtk.Rollup;
import org.apache.pivot.wtk.RollupStateListener;
import org.apache.pivot.wtk.Slider;
import org.apache.pivot.wtk.SliderValueListener;
import org.apache.pivot.wtk.SortDirection;
import org.apache.pivot.wtk.Spinner;
import org.apache.pivot.wtk.Style;
import org.apache.pivot.wtk.TableView;
import org.apache.pivot.wtk.TableViewSortListener;
import org.apache.pivot.wtk.TreeView;
import org.apache.pivot.wtk.Visual;
import org.apache.pivot.wtk.Window;
import org.apache.pivot.wtk.content.CalendarDateSpinnerData;
import org.apache.pivot.wtk.content.ListItem;
import org.apache.pivot.wtk.content.NumericSpinnerData;
import org.apache.pivot.wtk.content.TableViewHeaderData;
import org.apache.pivot.wtk.content.TableViewRowComparator;
import org.apache.pivot.wtk.content.TreeBranch;
import org.apache.pivot.wtk.content.TreeNode;
import org.apache.pivot.wtk.effects.ReflectionDecorator;
import org.apache.pivot.wtk.media.Image;
public class KitchenSink implements Application, Application.AboutHandler {
/**
* A sample of a Custom Table Row.
Note that this is public because it's
* references in one of bxml files of this application.
*/
public static final class CustomTableRow {
private boolean a = false;
private Image b = null;
private String c = null;
public boolean getA() {
return this.a;
}
public void setA(boolean a) {
this.a = a;
}
public Image getB() {
return this.b;
}
public void setB(Image b) {
this.b = b;
}
public void setB(URL bURL) {
setB(Image.loadFromCache(bURL));
}
public String getC() {
return this.c;
}
public void setC(String c) {
this.c = c;
}
}
/**
* Orders TreeNode instances by their name using string comparison.
*/
private static final class TreeNodeComparator implements Comparator, Serializable {
private static final long serialVersionUID = 1L;
public TreeNodeComparator() {
}
@Override
public int compare(TreeNode treeNode1, TreeNode treeNode2) {
String text1 = treeNode1.getText();
String text2 = treeNode2.getText();
int result;
if (text1 == null && text2 == null) {
result = 0;
} else if (text1 == null) {
result = -1;
} else if (text2 == null) {
result = 1;
} else {
result = text1.compareToIgnoreCase(text2);
}
return result;
}
}
private abstract class RollupStateHandler implements RollupStateListener {
public RollupStateHandler() {
}
@Override
public void expandedChangeVetoed(Rollup rollup, Vote reason) {
// No-op
}
@Override
public void expandedChanged(Rollup rollup) {
// No-op
}
}
private class InfoRollupStateHandler extends RollupStateHandler {
Component component = null;
Label infoPivotVersion = null;
Label infoPivotOrigin = null;
Label infoJavaVersion = null;
public InfoRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"info.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.infoPivotVersion = (Label) bxmlSerializer.getNamespace().get(
"info-pivot-version");
this.infoPivotVersion.setText(this.infoPivotVersion.getText()
+ ApplicationContext.getPivotVersion().toString());
this.infoPivotOrigin = (Label) bxmlSerializer.getNamespace().get(
"info-pivot-origin");
String origin = (ApplicationContext.getOrigin() != null) ? ApplicationContext.getOrigin().toString()
: "";
this.infoPivotOrigin.setText(this.infoPivotOrigin.getText() + "\"" + origin + "\"");
this.infoJavaVersion = (Label) bxmlSerializer.getNamespace().get(
"info-java-version");
// String javaVersion =
// ApplicationContext.getJVMVersion().toString();
String javaVersion = System.getProperty("java.version");
this.infoJavaVersion.setText(this.infoJavaVersion.getText() + javaVersion);
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class ButtonsRollupStateHandler extends RollupStateHandler {
private Component component = null;
public ButtonsRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"buttons.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class ListsRollupStateHandler extends RollupStateHandler {
Component component = null;
ListView editableListView = null;
ListView iconListView = null;
ListView checkedListView = null;
ListButton iconListButton = null;
public ListsRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"lists.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.editableListView = (ListView) bxmlSerializer.getNamespace().get(
"editableListView");
this.iconListView = (ListView) bxmlSerializer.getNamespace().get("iconListView");
this.checkedListView = (ListView) bxmlSerializer.getNamespace().get(
"checkedListView");
this.iconListButton = (ListButton) bxmlSerializer.getNamespace().get(
"iconListButton");
rollup.setContent(this.component);
@SuppressWarnings("unchecked")
List listData = (List) this.editableListView.getListData();
listData.setComparator(new Comparator() {
@Override
public int compare(ListItem listItem1, ListItem listItem2) {
String text1 = listItem1.getText();
String text2 = listItem2.getText();
return text1.compareToIgnoreCase(text2);
}
});
Filter disabledItemFilter = new Filter() {
@Override
public boolean include(ListItem listItem) {
return Character.toLowerCase(listItem.getText().charAt(0)) == 'c';
}
};
this.iconListView.setDisabledItemFilter(disabledItemFilter);
this.iconListButton.setDisabledItemFilter(disabledItemFilter);
this.checkedListView.setItemChecked(0, true);
this.checkedListView.setItemChecked(2, true);
this.checkedListView.setItemChecked(3, true);
}
return Vote.APPROVE;
}
}
private class TextRollupStateHandler extends RollupStateHandler {
Component component = null;
public TextRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"text.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class CalendarsRollupStateHandler extends RollupStateHandler {
Component component = null;
public CalendarsRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"calendars.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class ColorChoosersRollupStateHandler extends RollupStateHandler {
Component component = null;
public ColorChoosersRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"color_choosers.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class NavigationRollupStateHandler extends RollupStateHandler {
Component component = null;
public NavigationRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"navigation.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class SplittersRollupStateHandler extends RollupStateHandler {
Component component = null;
public SplittersRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"splitters.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
rollup.setContent(this.component);
}
return Vote.APPROVE;
}
}
private class MenusRollupStateHandler extends RollupStateHandler {
Component component = null;
ImageView menuImageView = null;
Menu.Item helpAboutMenuItem = null;
Menu.Section menuSection = null;
ButtonGroup imageMenuGroup = null;
public MenusRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
Action.getNamedActions().put("selectImageAction", new Action() {
@Override
public String getDescription() {
return "Select Image Action";
}
@Override
public void perform(Component source) {
Button selectedItem = MenusRollupStateHandler.this.imageMenuGroup.getSelection();
String imageName = (String) selectedItem.getUserData().get("image");
URL imageURL = getClass().getResource(imageName);
// Update the image
MenusRollupStateHandler.this.menuImageView.setImage(Image.loadFromCache(imageURL));
}
});
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"menus.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.menuImageView = (ImageView) bxmlSerializer.getNamespace().get("menuImageView");
this.helpAboutMenuItem = (Menu.Item) bxmlSerializer.getNamespace().get(
"helpAboutMenuItem");
rollup.setContent(this.component);
try {
this.menuSection = (Menu.Section) bxmlSerializer.readObject(KitchenSink.class,
"menu_section.bxml");
this.imageMenuGroup = (ButtonGroup) bxmlSerializer.getNamespace().get(
"imageMenuGroup");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.menuImageView.setMenuHandler(new MenuHandler() {
@Override
public boolean configureContextMenu(Component comp, Menu menu, int x, int y) {
menu.getSections().add(MenusRollupStateHandler.this.menuSection);
return false;
}
});
this.helpAboutMenuItem.getButtonPressListeners().add(new ButtonPressListener() {
@Override
public void buttonPressed(Button button) {
aboutRequested();
}
});
}
return Vote.APPROVE;
}
}
private class MetersRollupStateHandler extends RollupStateHandler {
Component component = null;
ActivityIndicator activityIndicator1 = null;
ActivityIndicator activityIndicator2 = null;
ActivityIndicator activityIndicator3 = null;
public MetersRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"meters.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.activityIndicator1 = (ActivityIndicator) bxmlSerializer.getNamespace().get(
"activityIndicator1");
this.activityIndicator2 = (ActivityIndicator) bxmlSerializer.getNamespace().get(
"activityIndicator2");
this.activityIndicator3 = (ActivityIndicator) bxmlSerializer.getNamespace().get(
"activityIndicator3");
rollup.setContent(this.component);
KitchenSink.this.metersRollup.getRollupStateListeners().add(
new RollupStateListener() {
@Override
public Vote previewExpandedChange(Rollup roll) {
return Vote.APPROVE;
}
@Override
public void expandedChangeVetoed(Rollup roll, Vote reason) {
// No-op
}
@Override
public void expandedChanged(Rollup roll) {
MetersRollupStateHandler.this.activityIndicator1.setActive(roll.isExpanded());
MetersRollupStateHandler.this.activityIndicator2.setActive(roll.isExpanded());
MetersRollupStateHandler.this.activityIndicator3.setActive(roll.isExpanded());
}
});
}
return Vote.APPROVE;
}
}
private class SpinnersRollupStateHandler extends RollupStateHandler {
Component component = null;
Spinner numericSpinner = null;
Spinner dateSpinner = null;
Slider redSlider = null;
Slider greenSlider = null;
Slider blueSlider = null;
Border colorBorder = null;
public SpinnersRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"spinners.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.numericSpinner = (Spinner) bxmlSerializer.getNamespace().get("numericSpinner");
this.dateSpinner = (Spinner) bxmlSerializer.getNamespace().get("dateSpinner");
this.redSlider = (Slider) bxmlSerializer.getNamespace().get("redSlider");
this.greenSlider = (Slider) bxmlSerializer.getNamespace().get("greenSlider");
this.blueSlider = (Slider) bxmlSerializer.getNamespace().get("blueSlider");
this.colorBorder = (Border) bxmlSerializer.getNamespace().get("colorBorder");
rollup.setContent(this.component);
initializeNumericSpinner(this.numericSpinner);
initializeDateSpinner(this.dateSpinner);
SliderValueListener sliderValueListener = new SliderValueListener() {
@Override
public void valueChanged(Slider slider, int previousValue) {
Color color = new Color(
SpinnersRollupStateHandler.this.redSlider.getValue(),
SpinnersRollupStateHandler.this.greenSlider.getValue(),
SpinnersRollupStateHandler.this.blueSlider.getValue());
SpinnersRollupStateHandler.this.colorBorder.putStyle(
Style.backgroundColor, color);
}
};
this.redSlider.getSliderValueListeners().add(sliderValueListener);
this.greenSlider.getSliderValueListeners().add(sliderValueListener);
this.blueSlider.getSliderValueListeners().add(sliderValueListener);
Color color = new Color(this.redSlider.getValue(), this.greenSlider.getValue(),
this.blueSlider.getValue());
this.colorBorder.putStyle(Style.backgroundColor, color);
}
return Vote.APPROVE;
}
private void initializeNumericSpinner(Spinner spinner) {
NumericSpinnerData numericSpinnerData = new NumericSpinnerData(0, 256, 4);
spinner.setSpinnerData(numericSpinnerData);
spinner.setSelectedIndex(0);
}
private void initializeDateSpinner(Spinner spinner) {
CalendarDate lowerBound = new CalendarDate(2008, 0, 0);
CalendarDate upperBound = new CalendarDate(2019, 11, 30);
CalendarDateSpinnerData spinnerData = new CalendarDateSpinnerData(lowerBound,
upperBound);
CalendarDate today = new CalendarDate();
spinner.setSpinnerData(spinnerData);
spinner.setSelectedItem(today);
}
}
private class TablesRollupStateHandler extends RollupStateHandler {
Component component = null;
TableView sortableTableView = null;
TableView customTableView = null;
public TablesRollupStateHandler() {
}
@Override
public Vote previewExpandedChange(Rollup rollup) {
if (this.component == null) {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
try {
this.component = (Component) bxmlSerializer.readObject(KitchenSink.class,
"tables.bxml");
} catch (IOException exception) {
throw new RuntimeException(exception);
} catch (SerializationException exception) {
throw new RuntimeException(exception);
}
this.sortableTableView = (TableView) bxmlSerializer.getNamespace().get(
"sortableTableView");
this.customTableView = (TableView) bxmlSerializer.getNamespace().get(
"customTableView");
rollup.setContent(this.component);
// Set table header data
TableView.ColumnSequence columns = this.sortableTableView.getColumns();
columns.get(0).setHeaderData(new TableViewHeaderData("#"));
columns.get(1).setHeaderData(new TableViewHeaderData("A"));
columns.get(2).setHeaderData(new TableViewHeaderData("B"));
columns.get(3).setHeaderData(new TableViewHeaderData("C"));
columns.get(4).setHeaderData(new TableViewHeaderData("D"));
// Populate table
ArrayList