How to customize the appearance of an AgcJSlider control and respond to changes in data.
You can run this technique code from:
NOTE First make sure that database is running on your localhost SilverStream Server | |
See the chapter on the Form Designer in the Tools Guide |
This example displays an AgcJSlider control that is associated with the quantity column of the orderdetails table. As the user navigates through the result set, the slider value changes to reflect the quantity value in the current row. Setting the slider is explicitly coded in the navigation button events, but you could use data bind to achieve the same result.
When navigating the result set, the slider range is automatically reset to the maximum order value in the result set. The form executes a SQL query via a invoked data source object (DSO) to get the maximum order quantity.
Other controls on the form allow the user to customize the slider's appearance: tick marks, labels, orientation, and minimum and maximum values.
The user can slide the pointer and see a continuously updated report of the current value in a text field. The form implements the ChangeListener interface so that the slider can fire stateChanged events. This event is not exposed in the Form Designer, but you can code it yourself. It allows the form to respond to continuous changes of the slider, in contrast to the valueChanged event, which occurs when the user has finished changing the value.
The formActivate event gets information about the initial state of the slider and displays that information in other controls on the form.
protected void formActivate() { Point point = jsldSlider.getLocation(); m_xPosition = point.x; m_yPosition = point.y; Dimension dimension = jsldSlider.getSize(); m_HorizontalWidth = dimension.width; m_HorizontalHeight = dimension.height; rbHorizontal.setState (true); chkShowTicks.setState (true); m_iMajorTickSpacing = jsldSlider.getMajorTickSpacing(); m_iMinorTickSpacing = jsldSlider.getMinorTickSpacing(); m_iMinimumValue = jsldSlider.getMinimum(); m_iMaximumValue = jsldSlider.getMaximum(); jsldSlider.setValue (m_iCurrentValue); lblValue.setText("" + m_iCurrentValue); fldMajorTicks.setText("" + m_iMajorTickSpacing); fldMinorTicks.setText("" + m_iMinorTickSpacing); fldMinimum.setText("" + m_iMinimumValue); fldMaximum.setText("" + m_iMaximumValue); jsldSlider.addChangeListener(this); jsldSlider.setBackground(m_formColorBackground); if (jsldSlider.getPaintLabels()) chkShowLabels.setState(true); }
setText()
method concatenates and empty string with the integer variable.
fldValue.setText("" + m_iCurrentValue);
There are several controls that let the user alter the slider's appearance or specify its range. The table lists the appearance settings and the methods that affect them.
The labels are the most complicated part of the slider. The labels for the major tick marks are label Components. (see setLabelTable()).
The JSlider class provides a static method to create standard labels, which gives numeric labels to the major tick marks. The example uses this code in the actionPerformed event of the chkShowLabels check box.
jsldSlider.setLabelTable (jsldSlider.createStandardLabels (m_iMajorTickSpacing, m_iMinimumValue) );
You can create custom labels by creating a label table yourself. This code (not in the live example) marks the ticks with letters -- rather arbitrary, but it illustrates how to create label components and put them into a Hashtable.
public Hashtable makeLabels(int min, int max, int incr) { String[] alpha = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "X", "Y", "Z" }; Hashtable hshLabels = new Hashtable(); int val = min; int i = 0; while (val <= max) { hshLabels.put(new Integer(val), new JLabel(alpha[i]) ); val += incr; i++; if (i > 23) i = 0; } return hshLabels; }
On the sample form, the user can drag the slider's pointer to change its value. The changing value is continuously displayed in the fldValue text field. (For how this is done, see Implementing the stateChanged event.)
The user can also scroll through the data from the orderdetails table. The dataOrderDetails AgcData control retrieves the data and buttons navigate the result set. For each row, the slider displays the quantity value.
The JSlider contol is not bound to data initially. To bind the JSlider, the user can check the Bind JSlider to agcData checkbox. The code in the valueChanged event for the checkbox binds the JSlider to the dataOrderDetails agcData.
try { if (chkBind.getState()) { //find the max value of quantity in dataOrderDetails setMaxOrderQuantity(); //rescale the slider to the max value resetMinMaxValues(0, m_maxOrderQuantity, m_maxOrderQuantity/10); //bind agcData to JSlider control using the quantity column from dataOrderDetails agDataMgr.bind (jsldSlider, "Value", "getValue", "setValue", dataOrderDetails, "quantity"); //goto the first record dataOrderDetails.gotoFirst(); } else { //release data binding from the JSlider control agDataMgr.unbind (jsldSlider, "Value"); } } catch (Exception e) { agDialog.displayError(e); }
resetMinMaxValues()
sets the slider range based on the maximum value in the orderdetails table. An ExecuteSQL DSO obtained the value in another user-defined method, setMaxOrderQuantity()
.
The stateChanged event occurs repeatedly as the user drags the slider's pointer. It is not automatically included on the form. To add it, you implement the ChangeListener interface. SilverStream can generate stubs for interface methods when you use this procedure:
import javax.swing.event.*;
javax.swing.event.ChangeListener
. Select the check box Create stubs for interface methods.
jsldSlider.addChangeListener(this);
public void stateChanged (ChangeEvent evt) { JSlider jSlider = (JSlider)evt.getSource(); int iValue = jSlider.getValue(); fldValue.setText ("Slider Value: " + iValue); }
The slider example uses an ExecuteSQL DSO to get the maximum value for the quantity column in the orderdetails table. An AgcData control called dataISQL is associated with the generic dsoISQL business object. This DSO is used in several examples for executing SQL statements.
For more information, see the complete example on executing SQL statements with dsoISQL [techFormDSO.html].
To make the SQL query, you put a valid SQL statement and a database name in a Hashtable and pass the Hashtable to the AgcData control in the invokeQuery()
method.
public void setMaxOrderQuantity() { Hashtable hshQueryInfo = new Hashtable(); hshQueryInfo.put("Query", "SELECT MAX(quantity) from orderdetails"); String sDatabaseURL = agGeneral.getDatabaseURL().toString(); // strip off final '/' sDatabaseURL = sDatabaseURL.substring(0, sDatabaseURL.length() - 1); int iOffset = sDatabaseURL.lastIndexOf('/'); sDatabaseURL = sDatabaseURL.substring(iOffset + 1, sDatabaseURL.length()); hshQueryInfo.put("Database", sDatabaseURL); try { // Invoke the data source object Object queryResult = dataISQL.invokeQuery(hshQueryInfo); // Live example includes error checking here // Get the value from the result set if (!dataISQL.gotoFirst()) { System.out.println("frmJSlider.setMaxOrderQuantity(): " + "Query failed to return data. "); return ; } m_maxOrderQuantity = ((Integer) dataISQL.getProperty(0)).intValue(); return; } catch (Exception e) { agDialog.displayError(e); } }
agGeneral
instance variable. agGeneral is an instance of the PVHelperGeneral class.
gotoFirst()
fails, it means that the query failed to get data. The SQL in this example retrieves only one row.
getProperty(0)
gets data from the first column that was specified in the SQL statement.