Search code examples
javaswingactionlistenerjscrollpanejscrollbar

Java - synchronizing two scrollbars via a checkbox


this code below creates a checkbox which I want to turn synchronized scrolling on my two panels on/off. Initially when the program runs the scrollbars are independent. When the checkbox is checked and the "if" statement is reached, scroller2's scrollbar is set to the model of scroller1's scrollbar and they are connected, i.e. they move together.

However the problem is when the checkbox is unchecked, meaning I want the scrollbars to be independent again. Nothing I put in the else statement seems to work.

JCheckBox check = new JCheckBox("Global");

ActionListener actionListener = new ActionListener() {
    public void actionPerformed(ActionEvent actionEvent) {
        AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
        boolean selected = abstractButton.getModel().isSelected();
        System.out.println(selected);
        if (selected){
            scroller2.getHorizontalScrollBar().setModel(scroller.getHorizontalScrollBar().getModel());
        } else {
            scroller = new JScrollPane(plotPanel);
            scroller2 = new JScrollPane(plotPanel2);
        }
    }
};
check.addActionListener(actionListener);    

Solution

  • This:

    scroller = new JScrollPane(plotPanel);
    scroller2 = new JScrollPane(plotPanel2);
    

    creates two new JScrollPanes but you do nothing with them. Understand that changing the object a variable refers to, here the scroller and scroller2 vairables will have no effect on the object that is displayed, and this issue gets to the core distinction of the difference between a reference variable and a reference or object. If you wanted to change the displayed JScrollPane you'd have to remove the old one, and add the new one to the GUI.

    But you don't want to do this. Simply give one of the horizontal JScrollBars a new model, specifically a new DefaultBoundedRangeModel. I would use the constructor that takes 4 ints, and would scrape the value, extent, min, max parameters from the current model.

    e.g., something like:

    else {
        JScrollBar horizBar = scroller2.getHorizontalScrollBar();
        DefaultBoundedRangeModel currentModel = (DefaultBoundedRangeModel) horizBar.getModel();
        int extent = currentModel.getExtent();
        int min = currentModel.getMin();
        int max = currentModel.getMax();
        int value = currentModel.getValue();
    
        DefaultBoundedRangeModel newModel = new DefaultBoundedRangeModel(value, extent, min, max);
        horizBar.setModel(newModel);
    }
    

    Note code not tested