All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.bordertech.wcomponents.examples.table.WTableOptionsExample Maven / Gradle / Ivy

There is a newer version: 1.5.36
Show newest version
package com.github.bordertech.wcomponents.examples.table;

import com.github.bordertech.wcomponents.ActionEvent;
import com.github.bordertech.wcomponents.HeadingLevel;
import com.github.bordertech.wcomponents.Request;
import com.github.bordertech.wcomponents.SimpleBeanBoundTableModel;
import com.github.bordertech.wcomponents.SimpleBeanBoundTableModel.LevelDetails;
import com.github.bordertech.wcomponents.WButton;
import com.github.bordertech.wcomponents.WCheckBox;
import com.github.bordertech.wcomponents.WContainer;
import com.github.bordertech.wcomponents.WDateField;
import com.github.bordertech.wcomponents.WDefinitionList;
import com.github.bordertech.wcomponents.WField;
import com.github.bordertech.wcomponents.WFieldLayout;
import com.github.bordertech.wcomponents.WFieldSet;
import com.github.bordertech.wcomponents.WHeading;
import com.github.bordertech.wcomponents.WHorizontalRule;
import com.github.bordertech.wcomponents.WMessages;
import com.github.bordertech.wcomponents.WMultiSelectPair;
import com.github.bordertech.wcomponents.WNumberField;
import com.github.bordertech.wcomponents.WRadioButtonSelect;
import com.github.bordertech.wcomponents.WTable;
import com.github.bordertech.wcomponents.WTable.PaginationMode;
import com.github.bordertech.wcomponents.WTableColumn;
import com.github.bordertech.wcomponents.WText;
import com.github.bordertech.wcomponents.WTextField;
import com.github.bordertech.wcomponents.examples.table.PersonBean.TravelDoc;
import com.github.bordertech.wcomponents.subordinate.And;
import com.github.bordertech.wcomponents.subordinate.Equal;
import com.github.bordertech.wcomponents.subordinate.Hide;
import com.github.bordertech.wcomponents.subordinate.NotEqual;
import com.github.bordertech.wcomponents.subordinate.Rule;
import com.github.bordertech.wcomponents.subordinate.Show;
import com.github.bordertech.wcomponents.subordinate.WSubordinateControl;
import com.github.bordertech.wcomponents.util.TableUtil;
import com.github.bordertech.wcomponents.validation.ValidatingAction;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * This class demonstrates the options available on a {@link WTable}.
 *
 * @author Jonathan Austin
 * @since 1.0.0
 */
public class WTableOptionsExample extends WContainer {

	/**
	 * Messages.
	 */
	private final WMessages messages = new WMessages();

	/**
	 * Example of a basic table.
	 */
	private final WTable table1;
	/**
	 * Example of a table with expandable context.
	 */
	private final WTable table2;
	/**
	 * Example of a hierarchic table.
	 */
	private final WTable table3;

	/**
	 * Default rows per page on the example tables.
	 */
	private static final int DEFAULT_ROWS_PER_PAGE = 3;

	/**
	 * Default rows per page options.
	 */
	private static final List DEFAULT_ROWS_OPTIONS = Arrays.asList(0, 3, 5);

	/**
	 * Display selected items for table1.
	 */
	private final WText selected1 = new WText();
	/**
	 * Display selected items for table2.
	 */
	private final WText selected2 = new WText();
	/**
	 * Display selected items for table3.
	 */
	private final WText selected3 = new WText();

	/**
	 * Select Options.
	 */
	private final EnumerationRadioButtonSelect rbsSelect;
	/**
	 * Select All Options.
	 */
	private final EnumerationRadioButtonSelect rbsSelectAll;
	/**
	 * Expand Options.
	 */
	private final EnumerationRadioButtonSelect rbsExpand;
	/**
	 * Paging Options.
	 */
	private final EnumerationRadioButtonSelect rbsPaging;
	/**
	 * number of rows per page selection.
	 */
	private final WNumberField numRowsPerPage = new WNumberField();
	/**
	 * Location of pagination controls.
	 */
	private final EnumerationRadioButtonSelect paginationControlsLocation;
	/**
	 * Striping Options.
	 */
	private final EnumerationRadioButtonSelect rbsStriping;
	/**
	 * Separator Options.
	 */
	private final EnumerationRadioButtonSelect rbsSeparator;
	/**
	 * Sorting Options.
	 */
	private final EnumerationRadioButtonSelect rbsSorting;
	/**
	 * Column header toggle.
	 */
	private final WCheckBox showColHeaders = new WCheckBox();

	/**
	 * Column footers toggle.
	 */
	private final WCheckBox showColFooters = new WCheckBox();

	/**
	 * Expand all toggle.
	 */
	private final WCheckBox expandAll = new WCheckBox();
	/**
	 * Editable.
	 */
	private final WCheckBox chbEditable = new WCheckBox();
	/**
	 * Column order.
	 */
	private final WMultiSelectPair columnOrder = new WMultiSelectPair(Arrays.asList(COLUMN.values()));

	/**
	 * Rows per page options.
	 */
	private final WCheckBox chbRowsPerPageOptions = new WCheckBox();

	/**
	 * Caption text.
	 */
	private final WTextField tfCaption = new WTextField();

	/**
	 * Sub row select toggle.
	 */
	private final WCheckBox cbToggleSubRowSelection = new WCheckBox();

	/**
	 * Use row headers.
	 */
	private final WCheckBox cbHasRowHeaders = new WCheckBox();

	/**
	 * Turn on responsive tables using the CSS class "wc-respond".
	 */
	private final WCheckBox cbEnableRespond = new WCheckBox();

	/**
	 * Construct the example.
	 */
	public WTableOptionsExample() {
		// Create Options
		rbsSelect = createRadioButtonGroup(WTable.SelectMode.values());
		rbsSelectAll = createRadioButtonGroup(WTable.SelectAllType.values());
		rbsExpand = createRadioButtonGroup(WTable.ExpandMode.values());
		rbsPaging = createRadioButtonGroup(WTable.PaginationMode.values());
		rbsStriping = createRadioButtonGroup(WTable.StripingType.values());
		rbsSeparator = createRadioButtonGroup(WTable.SeparatorType.values());
		rbsSorting = createRadioButtonGroup(WTable.SortMode.values());
		numRowsPerPage.setNumber(DEFAULT_ROWS_PER_PAGE);
		numRowsPerPage.setMinValue(1);
		paginationControlsLocation = createRadioButtonGroup(WTable.PaginationLocation.values());

		columnOrder.setSelected(columnOrder.getOptions());
		columnOrder.setMinSelect(1);
		columnOrder.setShuffle(true);
		columnOrder.setMandatory(true);

		add(messages);

		// Options Layout
		WFieldSet fieldSet = new WFieldSet("Table configuration");
		WFieldLayout layout = new WFieldLayout();
		layout.setLabelWidth(30);

		layout.addField("Select Mode", rbsSelect);
		WField fieldSelectAll = layout.addField("Select All Type", rbsSelectAll);
		/* show and hide the row selection sub-options */
		WSubordinateControl subShowSelectOptions = new WSubordinateControl();
		Rule rule = new Rule();
		rule.setCondition(new Equal(rbsSelect, WTable.SelectMode.MULTIPLE));
		rule.addActionOnTrue(new Show(fieldSelectAll));
		rule.addActionOnFalse(new Hide(fieldSelectAll));
		subShowSelectOptions.addRule(rule);
		add(subShowSelectOptions);

		layout.addField("Expand Mode", rbsExpand);
		layout.addField("Paging Mode", rbsPaging);
		layout.addField("Striping Type", rbsStriping);
		layout.addField("Separator Type", rbsSeparator);
		layout.addField("Sort Mode", rbsSorting);
		layout.addField("Show col headers", showColHeaders);
		layout.addField("Show col footers", showColFooters);
		WField fieldExpandAll = layout.addField("Expand all", expandAll);
		/* show and hide the row expansion sub-options */
		WSubordinateControl subShowExpandOptions = new WSubordinateControl();
		rule = new Rule();
		rule.setCondition(new Equal(rbsExpand, WTable.ExpandMode.NONE));
		rule.addActionOnTrue(new Hide(fieldExpandAll));
		rule.addActionOnFalse(new Show(fieldExpandAll));
		subShowExpandOptions.addRule(rule);
		add(subShowExpandOptions);

		WField fieldToggleSubRowSelection = layout.addField("Parent row selection controls sub row selection", cbToggleSubRowSelection);
		/* show/hide sub-row selection options */
		WSubordinateControl subToggler = new WSubordinateControl();
		rule = new Rule();
		rule.setCondition(new And(new Equal(rbsSelect, WTable.SelectMode.MULTIPLE), new NotEqual(rbsExpand, WTable.ExpandMode.NONE)));
		rule.addActionOnTrue(new Show(fieldToggleSubRowSelection));
		rule.addActionOnFalse(new Hide(fieldToggleSubRowSelection));
		subToggler.addRule(rule);
		add(subToggler);

		layout.addField("Editable", chbEditable);
		layout.addField("Column order", columnOrder);
		WField fieldRows = layout.addField("Rows per page", numRowsPerPage);
		WField fieldRowsOptions = layout.addField("Rows per page options", chbRowsPerPageOptions);
		WField fieldPaginationLocation = layout.addField("Location of pagination controls", paginationControlsLocation);
		/* show/hide pagination options */
		WSubordinateControl pagRowsPerPage = new WSubordinateControl();
		rule = new Rule();
		rule.setCondition(new Equal(rbsPaging, WTable.PaginationMode.NONE));
		rule.addActionOnTrue(new Hide(fieldRows));
		rule.addActionOnTrue(new Hide(fieldRowsOptions));
		rule.addActionOnTrue(new Hide(fieldPaginationLocation));
		rule.addActionOnFalse(new Show(fieldRows));
		rule.addActionOnFalse(new Show(fieldRowsOptions));
		rule.addActionOnFalse(new Show(fieldPaginationLocation));
		pagRowsPerPage.addRule(rule);
		add(pagRowsPerPage);

		layout.addField("Caption", tfCaption);
		layout.addField("Use row headers", cbHasRowHeaders);
		layout.addField("Enable responsive design for phones", cbEnableRespond);

		// Apply Button
		WButton apply = new WButton("Apply");
		apply.setAction(new ValidatingAction(messages.getValidationErrors(), fieldSet) {
			@Override
			public void executeOnValid(final ActionEvent event) {
				applySettings();
			}
		});

		fieldSet.add(layout);
		fieldSet.add(apply);
		add(fieldSet);

		add(new WHorizontalRule());

		// Create Tables
		table1 = createBasicDataTable();
		table2 = createExpandedDataTable();
		table3 = createHierarchicDataTable();

		add(new WHeading(HeadingLevel.H3, "Basic Table"));
		add(table1);
		add(selected1);

		add(new WHorizontalRule());

		add(new WHeading(HeadingLevel.H3, "Expanded Content Table"));
		add(table2);
		add(selected2);

		add(new WHorizontalRule());

		add(new WHeading(HeadingLevel.H3, "Hierarchic Table"));
		add(table3);
		add(selected3);

		add(new WHorizontalRule());

		add(new WButton("Refresh"));
	}

	/**
	 * Create a radio button select containing the options.
	 *
	 * @param  the enumeration type.
	 * @param options the list of options
	 * @return a radioButtonSelect with the options
	 */
	private > EnumerationRadioButtonSelect createRadioButtonGroup(
			final T[] options) {
		EnumerationRadioButtonSelect rbSelect = new EnumerationRadioButtonSelect<>(options);
		rbSelect.setButtonLayout(EnumerationRadioButtonSelect.Layout.FLAT);
		rbSelect.setFrameless(true);
		return rbSelect;
	}

	/**
	 * @return a basic table example.
	 */
	private WTable createBasicDataTable() {
		WTable table = new WTable();
		addColumns(table);
		table.setType(WTable.Type.TABLE);
		table.setRowsPerPage(DEFAULT_ROWS_PER_PAGE);
		table.setCaption("Basic table caption");
		table.setBeanProperty(".");

		// Setup model with column properties
		MyBeanBoundTableModel model = new MyBeanBoundTableModel(
				new String[]{"firstName", "lastName",
					"dateOfBirth"});
		model.setSelectable(true);
		model.setEditable(true);
		model.setComparator(0, SimpleBeanBoundTableModel.COMPARABLE_COMPARATOR);
		model.setComparator(1, SimpleBeanBoundTableModel.COMPARABLE_COMPARATOR);
		table.setTableModel(model);

		return table;
	}

	/**
	 * @return a table that has expanded content.
	 */
	private WTable createExpandedDataTable() {
		WTable table = new WTable();
		addColumns(table);
		table.setType(WTable.Type.TABLE);
		table.setRowsPerPage(DEFAULT_ROWS_PER_PAGE);
		table.setCaption("Expanded content table caption");
		table.setBeanProperty(".");

		// Define the expandable level. The row will expand if the bean has "extra" details
		LevelDetails level1 = new LevelDetails("documents", TravelDocPanel.class);

		// Setup model with column properties and the "expandable" level
		MyBeanBoundTableModel model = new MyBeanBoundTableModel(new String[]{"firstName", "lastName", "dateOfBirth"},
				level1);

		model.setSelectable(true);
		model.setEditable(true);
		model.setComparator(0, SimpleBeanBoundTableModel.COMPARABLE_COMPARATOR);
		model.setComparator(1, SimpleBeanBoundTableModel.COMPARABLE_COMPARATOR);

		table.setTableModel(model);

		return table;
	}

	/**
	 * @return a hierarchic table
	 */
	private WTable createHierarchicDataTable() {
		WTable table = new WTable();
		addColumns(table);
		table.setType(WTable.Type.HIERARCHIC);
		table.setRowsPerPage(DEFAULT_ROWS_PER_PAGE);
		table.setCaption("Hierarchic table caption");
		table.setBeanProperty(".");

		// Setup model with column properties and the "level" to iterate on (ie more details)
		MyBeanBoundTableModel model = new MyBeanBoundTableModel(
				new String[]{"firstName", "lastName", "dateOfBirth"}, "more");

		model.setIterateFirstLevel(true);
		model.setSelectable(true);
		model.setEditable(true);
		model.setComparator(0, SimpleBeanBoundTableModel.COMPARABLE_COMPARATOR);
		model.setComparator(1, SimpleBeanBoundTableModel.COMPARABLE_COMPARATOR);

		table.setTableModel(model);

		return table;
	}

	/**
	 * @param table the table to add columns
	 */
	private void addColumns(final WTable table) {
		// Column - First name
		WTextField textField = new WTextField();
		textField.setToolTip("First name");
		table.addColumn(new WTableColumn("First name", textField, new WText("Footer 1")));

		// Column - Last name
		textField = new WTextField();
		textField.setToolTip("Last name");
		table.addColumn(new WTableColumn("Last name", textField, new WText("Footer 2")));

		// Column - Date field
		WDateField dateField = new WDateField();
		dateField.setToolTip("Date of birth");
		table.addColumn(new WTableColumn("Date of birth", dateField, new WText("Footer 3")));
	}

	@Override
	protected void preparePaintComponent(final Request request) {
		if (!isInitialised()) {
			// Defaults
			rbsSelect.setSelected(WTable.SelectMode.NONE);
			rbsSelectAll.setSelected(WTable.SelectAllType.NONE);
			rbsExpand.setSelected(WTable.ExpandMode.NONE);
			rbsPaging.setSelected(WTable.PaginationMode.NONE);
			rbsStriping.setSelected(WTable.StripingType.NONE);
			rbsSeparator.setSelected(WTable.SeparatorType.NONE);
			rbsSorting.setSelected(WTable.SortMode.NONE);
			showColHeaders.setSelected(true);
			paginationControlsLocation.setSelected(WTable.PaginationLocation.AUTO);
			applySettings();

			// Set the data used by the tables
			setBean(ExampleDataUtil.createExampleData());

			setInitialised(true);
		}

		displaySelected();

	}

	/**
	 * Display the rows that have been selected.
	 */
	private void displaySelected() {
		copySelection(table1, selected1);
		copySelection(table2, selected2);
		copySelection(table3, selected3);
	}

	/**
	 * @param table the table with selected items
	 * @param selected the text field that will contain a copy of the selected item details
	 */
	private void copySelection(final WTable table, final WText selected) {
		Set rows = table.getSelectedRows();

		if (rows.isEmpty()) {
			selected.setText("No Rows Selected");
		} else {
			StringBuffer out = new StringBuffer("Selected: ");
			boolean firstRow = true;
			for (Object row : rows) {
				if (firstRow) {
					firstRow = false;
				} else {
					out.append(", ");
				}
				out.append(row);
			}
			selected.setText(out.toString());
		}
	}

	/**
	 * Apply the table options selected by the user.
	 */
	private void applySettings() {
		applyTableSettings(table1);
		applyTableSettings(table2);
		applyTableSettings(table3);
	}

	/**
	 * Apply the settings to a particular table.
	 *
	 * @param table the table to apply settings to
	 */
	private void applyTableSettings(final WTable table) {
		table.setSelectMode(rbsSelect.getSelected());

		table.setSelectAllMode(rbsSelectAll.getSelected());
		table.setExpandMode(rbsExpand.getSelected());
		table.setSortMode(rbsSorting.getSelected());
		table.setStripingType(rbsStriping.getSelected());
		table.setSeparatorType(rbsSeparator.getSelected());
		table.setShowColumnHeaders(showColHeaders.isSelected());
		table.setRenderColumnFooters(showColFooters.isSelected());
		table.setExpandAll(expandAll.isSelected());
		table.setEditable(chbEditable.isSelected());
		table.setToggleSubRowSelection(table.getType() == WTable.Type.HIERARCHIC
				&& cbToggleSubRowSelection.isSelected()
				&& rbsExpand.getSelected() != WTable.ExpandMode.NONE
				&& rbsSelect.getSelected() == WTable.SelectMode.MULTIPLE);
		// row headers
		table.setRowHeaders(cbHasRowHeaders.isSelected());
		// Caption
		if (null == tfCaption.getText() || "".equals(tfCaption.getText())) {
			table.setCaption(null);
		} else {
			table.setCaption(tfCaption.getText());
		}

		// Pagination
		table.setPaginationMode(rbsPaging.getSelected());
		if (rbsPaging.getSelected() == PaginationMode.NONE) {
			table.setRowsPerPage(DEFAULT_ROWS_PER_PAGE);
			table.setRowsPerPageOptions(null);
			table.setPaginationLocation(WTable.PaginationLocation.AUTO);
		} else {
			// Options
			table.setRowsPerPageOptions(chbRowsPerPageOptions.isSelected() ? DEFAULT_ROWS_OPTIONS : null);
			// Rows
			int rows;
			if (numRowsPerPage.isEmpty() || numRowsPerPage.getNumber().intValue() < 1) {
				rows = DEFAULT_ROWS_PER_PAGE;
			} else {
				rows = numRowsPerPage.getNumber().intValue();
				if (chbRowsPerPageOptions.isSelected() && !DEFAULT_ROWS_OPTIONS.contains(rows)) {
					rows = DEFAULT_ROWS_PER_PAGE;
					numRowsPerPage.setNumber(rows);
				}
			}
			table.setRowsPerPage(rows);
			table.setPaginationLocation(paginationControlsLocation.getSelected());
		}
		// enable responsive design for phones.
		table.setHtmlClass(cbEnableRespond.isSelected() ? "wc-respond" : "");

		List cols = (List) columnOrder.getSelected();
		int[] order = new int[cols.size()];
		int i = 0;
		for (COLUMN col : cols) {
			order[i++] = col.getCol();
		}
		table.setColumnOrder(order);

	}

	/**
	 * An example component to display travel document details. Expects that the supplied bean is a {@link TravelDoc}.
	 */
	public static final class TravelDocPanel extends WContainer {

		/**
		 * Creates a TravelDocPanel.
		 */
		public TravelDocPanel() {
			WHorizontalRule rule = new WHorizontalRule() {
				@Override
				public boolean isVisible() {
					List index = TableUtil.getCurrentRowIndex(TravelDocPanel.this);
					// On expanded row, so check the index of the expanded level
					return index.get(1) > 0;
				}

			};
			add(rule);

			WText documentNumber = new WText();
			WText countryOfIssue = new WText();
			WText placeOfIssue = new WText();

			documentNumber.setBeanProperty("documentNumber");
			countryOfIssue.setBeanProperty("countryOfIssue");
			placeOfIssue.setBeanProperty("placeOfIssue");

			WDefinitionList list = new WDefinitionList(WDefinitionList.Type.COLUMN);
			add(list);

			list.addTerm("Document number", documentNumber);
			list.addTerm("Country of issue", countryOfIssue);
			list.addTerm("Place Of issue", placeOfIssue);
		}
	}

	/**
	 * A simple extension of WRadioButtonSelect to enhance type safety and provide a more intelligent description of the
	 * enumerated values.
	 *
	 * @param  the enumeration type.
	 */
	private static final class EnumerationRadioButtonSelect> extends WRadioButtonSelect {

		/**
		 * Creates an EnumerationRadioButtonSelect.
		 *
		 * @param options the options
		 */
		private EnumerationRadioButtonSelect(final T[] options) {
			super(options);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		// for type-safety only
		public T getSelected() {
			return (T) super.getSelected();
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public String getDesc(final Object option, final int index) {
			String desc = super.getDesc(option, index);
			return desc.charAt(0) + desc.substring(1).replace('_', ' ').toLowerCase();
		}
	}

	/**
	 * Columns used on the table.
	 * 

* This enum is used as the options in the WShuffler to demonstrate how column orders can be changed. *

*/ private enum COLUMN { /** * First name. */ FIRST_NAME(0, "First name"), /** * Last name. */ LAST_NAME(1, "Last name"), /** * Date of birth. */ DATE_OF_BIRTH(2, "Date of birth"); /** * Column index. */ private final int col; /** * Column description. */ private final String desc; /** * @param col the column index * @param desc the column description */ COLUMN(final int col, final String desc) { this.col = col; this.desc = desc; } /** * @return the col index */ public int getCol() { return col; } /** * {@inheritDoc} */ @Override public String toString() { return desc; } } /** * A simple extension of SimpleBeanBoundTableModel to allow for individual rows to be selectable. */ private class MyBeanBoundTableModel extends SimpleBeanBoundTableModel { /** * Create a Bean bound table model. * * @param columnBeanProperties the column properties in this model. */ public MyBeanBoundTableModel(final String[] columnBeanProperties) { super(columnBeanProperties); } /** * Define the column bean properties for the top level along with the expandable levels. * * @param columnBeanProperties the top level column bean properties * @param levels the expandable levels */ public MyBeanBoundTableModel(final String[] columnBeanProperties, final LevelDetails... levels) { super(columnBeanProperties, levels); } /** * Define the column bean properties for the top level along with the bean property of the first expandable * level. * * @param columnBeanProperties the column bean properties * @param levelBeanProperty the bean property for the expandable level */ public MyBeanBoundTableModel(final String[] columnBeanProperties, final String levelBeanProperty) { super(columnBeanProperties, new LevelDetails(levelBeanProperty, columnBeanProperties)); } /** * Is a given row selectable? * * @param row The row to test. * @return true if the row is selectable. */ @Override public boolean isSelectable(final List row) { if (null == row || row.isEmpty()) { return super.isSelectable(row); // let it be handled by super, we don't need to worry about this. } if (!super.isSelectable(row)) { // in the super implementation we determine if the table as a whole is selectable. return false; } Object bean = getRowBean(row); if (null == bean) { return false; } return ((PersonBean) bean).isSelectable(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy