Both scroll panes are the same size.
What i want to do, is to hide the scrollbar for the left hand scroll
pane - and control the scrolling for both scrollpanes by using the
right hand scroll bar.
I have searched through this newsgroups and tried the following
approaches:
A) Using an AdjustmentListener
scrollPane1.setVerticalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane2.getVerticalScrollBar().addAdjustmentListener(new
AdjustmentListener()
{
public void adjustmentValueChanged(AdjustmentEvent e)
{
scrollPane1.getVerticalScrollBar().setValue(e.getValue());
}
});
The problem with this is that it does work - but is slow and the
scrolling of the first scroll bar is always delayed.
B) Setting the model
I found this suggestion in a newsgroup:
JScrollPane first = ...; // table scrollPane
JScrollPane second = ...; // tree scrollPane
first.getVerticalScrollBar()
.setModel(second.getVerticalScrollBar().getModel());
The problem with this is that while the 2 scroll bars are prefectly in
sync - only the tree scroll pane actually scrolls.
The ideal solution would be one where one vertical scroll bar could
control two models. Has anyone had a similar problem to solve - this
has been puzzling me at work for a couple of days now.
Also, there is a chance that the scroll panes may end up different
sizes - would this have a big effect on any possible solution chosen?
Thanks in advance
why not just put the tree and list side-by-side (using something like
BoxLayout) and then put them both into the one ScrollPane?
Try this link:
http://java.sun.com/products/jfc/tsc/articles/treetable2/index.html
Try this:
--------------------------------- cut here ------------------------------------
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
{
/**
* 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 );
JScrollPane rightScrollPane = new JScrollPane( new JList( rightData ) );
JScrollBar leftBar = leftScrollPane.getVerticalScrollBar();
JScrollBar rightBar = rightScrollPane.getVerticalScrollBar();
MyChangeListener listener = new MyChangeListener(leftBar.getModel());
rightBar.getModel().addChangeListener( listener );
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
}
--------------------------------- cut here ------------------------------------