package aliview.test;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
/**
* Simple panel that illustrates the synchronization of two JScrollPanes.
* The number of elements in the two JList components do not have to be
* the same. The ChangeListener will synchronize their respective
* BoundedRangeModels and scale as necessary.
* <p> Note: Since it is the right JScrollBar's model-ChangeListener that listens
* for changes from the left JScrollBar, it is the right JList that controls
* the total number of elements shown in the JScrollPanes. </p>
*
* @author R. Kevin Cole
*/
public class ScrollBarSynchronizer extends JPanel
{
private MyChangeListener scrollBarListener;
/**
* Two JLists are created and initialized from Vectors and
* then added to JScrollPanes to test the synchronized JScrollBars.
*/
public ScrollBarSynchronizer()
{
super( new BorderLayout() );
// create something to scroll
Vector leftData = new Vector();
Vector rightData = new Vector();
for( int i = 0; i < 71; i++ )
{
rightData.add( "Right " + i );
// the modulo operator is used to create a different number
// of elements within each scrolling region.
// if( (i % 2) == 0 )
leftData.add( "Left " + i );
}
JScrollPane leftScrollPane = new JScrollPane( new JList( leftData ) );
// leftScrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_NEVER );
// leftScrollPane.setVerticalScrollBar(verticalScrollBar)
JScrollPane rightScrollPane = new JScrollPane( new JList( rightData ) );
//leftScrollPane.setVerticalScrollBar(rightScrollPane.getVerticalScrollBar());
JScrollBar leftBar = leftScrollPane.getVerticalScrollBar();
JScrollBar rightBar = rightScrollPane.getVerticalScrollBar();
scrollBarListener = new MyChangeListener(leftBar.getModel());
rightBar.getModel().addChangeListener( scrollBarListener );
MyChangeListener listener2 = new MyChangeListener(rightBar.getModel());
leftBar.getModel().addChangeListener( listener2 );
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT
, leftScrollPane
, rightScrollPane );
add( split, BorderLayout.CENTER );
}
/**
* Test routine.
*/
public static void main( String[] arg )
{
JFrame frame = new JFrame("Test ScrollBarSynchronizer");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setContentPane( new ScrollBarSynchronizer() );
frame.setSize( 640, 480 );
frame.setLocation( 100, 100 );
frame.setVisible(true);
}
}
/**
* Synchronize the data models of any two JComponents that use a
* BoundedRangeModel ( such as a JScrollBar, JSlider or ProgressBar).
*
* @see javax.swing.BoundedRangeModel
* @see javax.swing.event.ChangeListener
* @Author R. Kevin Cole
*/
class MyChangeListener implements ChangeListener
{
private BoundedRangeModel myModel;
/**
* @param model This model is forced to move in synchronization
* to this ChangeListener's event-source.
*/
public MyChangeListener( BoundedRangeModel model )
{
myModel = model;
}
// - begin - implementation of ChangeListener
//
/**
* Envoked when the target of the listener has changed its state.
*/
public void stateChanged( ChangeEvent e )
{
BoundedRangeModel sourceModel = (BoundedRangeModel) e.getSource();
int sourceDiff = sourceModel.getMaximum() - sourceModel.getMinimum();
int destDiff = myModel.getMaximum() - myModel.getMinimum();
int destValue = sourceModel.getValue();
if( sourceDiff != destDiff )
destValue = (destDiff * sourceModel.getValue())/sourceDiff;
myModel.setValue( myModel.getMinimum() + destValue );
}
//
// - end - implementation of ChangeListener
}