Application Techniques



Using the JSlider Control

How to customize the appearance of an AgcJSlider control and respond to changes in data.

About this technique

Details

Category

Java Client Techniques> Version 3 Swing-based controls

Description

You'll learn about:

You can run this technique code from:

NOTE   First make sure that database is running on your localhost SilverStream Server

Related reading

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.

Initializing form controls with slider settings   Top of page

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);  
  } 

Notes on the code

Changing the slider's appearance and parameters   Top of page

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.

Slider setting

Corresponding methods in JSlider class

Range of the slider

  setMaximum(int) 
  setMinimum(int) 

Whether there are labels for values

  setPaintLabels(boolean) 

The text of the labels

  setLabelTable(Hashtable) 
  Hashtable createStandardLabels(int, int) 

Whether there are tick marks

  setPaintTicks(boolean) 

The intervals for major and minor ticks

  setMajorTickSpacing(int) 
  setMinorTickSpacing(int) 

Whether the slider snaps to tick marks

  setSnapToTicks(boolean) 

The orientation of the slider (does the slider move side to side or up and down)

  setOrientation(JSlider.VERTICAL) 
  setOrientation(JSlider.HORIZONTAL) 

The direction of the scale (which ends have the high and low values)

  setInverted(boolean) 

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; 
  } 

Setting the slider value   Top of page

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); 
   } 
   

Notes on the code

Implementing the stateChanged event   Top of page

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:

  1. To work with ChangeListener, include this import statement in your form:

      import javax.swing.event.*; 
    
  2. In the Programming Editor, select File>Java Interfaces and add the interface javax.swing.event.ChangeListener. Select the check box Create stubs for interface methods.

  3. Add the form as a listener for the slider control. This code is in the formActivate event:

      jsldSlider.addChangeListener(this);  
    
  4. In the generated stub for the stateChanged event, write code to display the slider's current value in a text control:

      public void stateChanged (ChangeEvent evt) 
      { 
         JSlider jSlider = (JSlider)evt.getSource(); 
         int iValue = jSlider.getValue(); 
         fldValue.setText ("Slider Value: " + iValue); 
      } 
    

Executing a SQL statement   Top of page

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); 
     }    
  } 

Notes on the code






Copyright © 2000, SilverStream Software, Inc. All rights reserved.