Custom Widget: TableDrivenOneClick
The following example creates a TableDrivenOneClick
widget, a GUI component placed like a OneClick panel that similarly implements filters on tables and plots. A TableDrivenOneClick
panel contains two components: a text box and a combo box. Once the user types an entry into the text box and presses Enter, the combo box is updated with the values from the comboBoxColumn
in the associated table.
The TableDrivenOneClick
panel uses a common template for custom widgets. The deflate()
method creates a Descriptor instance holding all the information we want the GUI component to have, in this case the Table and the two columns. This implements the interface Inflatable<TableDrivenOneClick>
, which tells Deephaven how to re-inflate your widget after it has been deflated and shipped.
See Custom Widgets in the User Guide to learn more.
Step 1: Create a Java class for the widget
In order to create your own widget, first create a Java class which implements the com.illumon.iris.db.tables.utils.LiveWidget
Class. This class tells Deephaven how to ship the information required to create the GUI component to the client.
import com.fishlib.io.logger.Logger;
import com.illumon.iris.db.tables.Table;
import com.illumon.iris.db.tables.remote.ExportedObjectClient;
import com.illumon.iris.db.tables.remote.Inflatable;
import com.illumon.iris.db.tables.remotequery.QueryProcessorConnection;
import com.illumon.iris.db.tables.utils.LiveWidget;
import com.illumon.iris.gui.widget.AsyncPanel;
import javax.swing.*;
In the code below, baseTable sets the table filtering values are drawn from, textBoxColumn
sets the column for text box input, and comboBoxColumn
sets the column for ComboBox
input.
//The constructor takes a Table and two columns as input.
public class TableDrivenOneClick implements LiveWidget<TableDrivenOneClick> {
private final Table baseTable;
private final String textBoxColumn, comboBoxColumn;
//The next segment of code runs on the server and creates a table
//with only the unique value of the two columns, textBoxColumn and comboBoxColumn,
//so that the client has to process less data.
public TableDrivenOneClick(final Table baseTable, final String textBoxColumn,
final String comboBoxColumn) {
if (!baseTable.hasColumns(textBoxColumn, comboBoxColumn)) {
throw new IllegalArgumentException("Base table does not contain columns " +
textBoxColumn + ", " + comboBoxColumn);
}
//.preemptiveUpdatesTable(1000L) specifies how frequently
//the client side Table will update.
this.baseTable = baseTable.selectDistinct(textBoxColumn,
comboBoxColumn).preemptiveUpdatesTable(1000L);
this.textBoxColumn = textBoxColumn;
this.comboBoxColumn = comboBoxColumn;
}
Step 2: Implement Deflate and Inflate for the LiveWidget
Ticking Deephaven tables are not serializable and are not shipped to the client. All Table objects must be deflated to create a serializable Inflatable<Table>
object, which is essentially a table handle, or identifier that the client may use to communicate with the server about a given table. Note: other Java objects do not need to be inflated, or uncompressed, because they use Java serialization.
// Since tables are not serializable and the entire table cannot be shipped to the
// server, we use the table.deflate()method to produce a handle to the table.
@Override
public Inflatable<TableDrivenOneClick> deflate(ExportedObjectClient client) {
return new Descriptor(baseTable.deflate(client), textBoxColumn, comboBoxColumn);
}
@Override
public JComponent getComponent(AsyncPanel dataPanel, String viewId, String title, Object irisWidgetSupportObject, Logger log) {
return new TableDrivenOneClickPanel(baseTable, textBoxColumn, comboBoxColumn, log);
}
The descriptor class holds all the information needed to create a TableDrivenOneClick
widget. It defines an inflate()
method, which inflates all the deflated tables.
private static class Descriptor implements Inflatable<TableDrivenOneClick> {
private static final long serialVersionUID = -242821532734185765L;
private final Inflatable<Table> table;
private final String textBoxColumn, comboBoxColumn;
public Descriptor(final Inflatable<Table> table,
final String textBoxColumn, final String comboBoxColumn) {
this.table = table;
this.textBoxColumn = textBoxColumn;
this.comboBoxColumn = comboBoxColumn;
}
@Override
The next lines create a proxy Table on the client side, and when this code is run, it creates a TableDrivenOneClick
widget on the client.
public TableDrivenOneClick inflate(QueryProcessorConnection queryProcessorConnection) {
return new TableDrivenOneClick(table.inflate(queryProcessorConnection), textBoxColumn, comboBoxColumn);
}
}
}
Step 3: Define the component described by the LiveWidget in the console
Next, the new TableDriveOneClick
widget needs to be instantiated in the GUI. It is placed like a OneClick Panel and triggers filters on tables, plots, etc. like a OneClick filter would, and includes a text box and a drop down menu. Here, the getComponent()
method is called. The TableDrivenOneClick
on the client returns a TableDrivenOneClickPanel
, whose code is below:
@SuppressWarnings("WeakerAccess")
public class TableDrivenOneClickPanel extends JPanel {
private final String textBoxColumn, comboBoxColumn; //The columns whose values drive the filtering.
private final JTextField textField = new JTextField(10); //This creates a text field that is 10 characters long.
private final ComboBox comboBox = new ComboBox(); //This creates a drop down menu.
private final TableMap listColMap; // This maps textBoxColumn values to separate Tables.
private final Logger log;
private String currentTextBoxColumnValue = ""; // Current values are based on user input; this is the value from the text box.
private String currentComboBoxColumnValue = ""; // This is the value from the combo box.
private Table currentComboBoxColumnTable; //This creates a table of distinct values in the comboBoxColumn for the currentTextBoxColumnValue.
private InstrumentedListenerAdapter currentListenerAdapter;
// The following parameters create a panel with a text box and drop down menu.
@SuppressWarnings("WeakerAccess")
public TableDrivenOneClickPanel(Table baseTable, final String textBoxColumn, final String comboBoxColumn, final Logger log) {
baseTable = baseTable.subscribeToPreemptiveUpdates(); // the table which gives possible filter values
this.log = log;
this.textBoxColumn = textBoxColumn; // the column for text box input
this.comboBoxColumn = comboBoxColumn; // the column for combo box input
this.listColMap = baseTable.byExternal(textBoxColumn); //creates a TableMap
}
}
Step 4: Open the widget in the console
import com.illumon.iris.console.Playground.TableDrivenOneClick
t = emptyTable(10).update("USym = `A`"), ("Date = `2018-05-07`")
widget = NewTableDrivenOneClick (t, "USym", "Date")
t2 = emptyTable(10).update("USym = `A`"), ("Date = `2018-05-07`")
The complete code block follows:

import com.fishlib.io.logger.Logger;
import com.illumon.iris.db.tables.Table;
import com.illumon.iris.db.tables.remote.ExportedObjectClient;
import com.illumon.iris.db.tables.remote.Inflatable;
import com.illumon.iris.db.tables.remotequery.QueryProcessorConnection;
import com.illumon.iris.db.tables.utils.LiveWidget;
import com.illumon.iris.gui.widget.AsyncPanel;
import javax.swing.*;
public class TableDrivenOneClick implements LiveWidget<TableDrivenOneClick> {
private final Table baseTable;
private final String textBoxColumn, comboBoxColumn;
public TableDrivenOneClick(final Table baseTable, final String textBoxColumn, final String comboBoxColumn) {
if (!baseTable.hasColumns(textBoxColumn, comboBoxColumn)) {
throw new IllegalArgumentException("Base table does not contain columns " + textBoxColumn + ", " + comboBoxColumn);
}
this.baseTable = baseTable.selectDistinct(textBoxColumn, comboBoxColumn)
.preemptiveUpdatesTable(1000L);
this.textBoxColumn = textBoxColumn;
this.comboBoxColumn = comboBoxColumn;
}
@Override
public Inflatable<TableDrivenOneClick> deflate(ExportedObjectClient client) {
return new Descriptor(baseTable.deflate(client), textBoxColumn, comboBoxColumn);
}
@Override
public JComponent getComponent(AsyncPanel dataPanel, String viewId, String title, Object irisWidgetSupportObject, Logger log) {
return new TableDrivenOneClickPanel(baseTable, textBoxColumn, comboBoxColumn, log);
}
private static class Descriptor implements Inflatable<TableDrivenOneClick> {
private static final long serialVersionUID = -242821532734185765L;
private final Inflatable<Table> table;
private final String textBoxColumn, comboBoxColumn;
public Descriptor(final Inflatable<Table> table, final String textBoxColumn, final String comboBoxColumn) {
this.table = table;
this.textBoxColumn = textBoxColumn;
this.comboBoxColumn = comboBoxColumn;
}
@Override
public TableDrivenOneClick inflate(QueryProcessorConnection queryProcessorConnection) {
return new TableDrivenOneClick(table.inflate(queryProcessorConnection), textBoxColumn, comboBoxColumn);
}
}
}
@SuppressWarnings("WeakerAccess")
public class TableDrivenOneClickPanel extends JPanel {
private final String textBoxColumn, comboBoxColumn;
private final JTextField textField = new JTextField(10);
private final ComboBox comboBox = new ComboBox();
private final TableMap listColMap;
private final Logger log;
private String currentTextBoxColumnValue = "";
private String currentComboBoxColumnValue = "";
private Table currentComboBoxColumnTable;
private InstrumentedListenerAdapter currentListenerAdapter;
@SuppressWarnings("WeakerAccess")
public TableDrivenOneClickPanel(Table baseTable, final String textBoxColumn, final String comboBoxColumn, final Logger log) {
baseTable = baseTable.subscribeToPreemptiveUpdates();
this.log = log;
this.textBoxColumn = textBoxColumn;
this.comboBoxColumn = comboBoxColumn;
this.listColMap = baseTable.byExternal(textBoxColumn);
}
}
import com.illumon.iris.console.Playground.TableDrivenOneClick
t = emptyTable(10).update("USym = `A`"), ("Date = `2018-05-07`")
widget = NewTableDrivenOneClick (t, "USym", "Date")
t2 = emptyTable(10).update("USym = `A`"), ("Date = `2018-05-07`")
Last Updated: 16 February 2021 18:06 -04:00 UTC Deephaven v.1.20200928 (See other versions)
Deephaven Documentation Copyright 2016-2020 Deephaven Data Labs, LLC All Rights Reserved