Search code examples
javaswingeventsjslider

JSlider with 2 data sources event handling


I have a JSlider component on my frame which is being constantly updated by an external component (a media player which sets a new value from time to time). I want the slider to handle the stateChanged event only when I manipulate the slider and not my external component.

Is there any way to achieve this?


Solution

  • I'd implement my own BoundedRangeModel, this way you can add additional flags that indicates whether it should accept updates or not

    UPDATE with EXAMPLE

    The basic idea would be to implement your own model, that way you can control when the value is actually changed

    public class MyBoundedRangeModel extends DefaultBoundedRangeModel {
    
        private boolean updatesAllowed;
    
        public void setUpdatesAllowed(boolean updatesAllowed) {
            this.updatesAllowed = updatesAllowed;
        }
    
        public boolean isUpdatesAllowed() {
            return updatesAllowed;
        }
    
        @Override
        public void setMinimum(int n) {
            setUpdatesAllowed(true);
            super.setMinimum(n);
            setUpdatesAllowed(false);
        }
    
        @Override
        public void setMaximum(int n) {
            setUpdatesAllowed(true);
            super.setMaximum(n);
            setUpdatesAllowed(false);
        }
    
        @Override
        public void setExtent(int n) {
            setUpdatesAllowed(true);
            super.setExtent(n);
            setUpdatesAllowed(false);
        }
    
        @Override
        public void setValue(int n) {
            super.setValue(n);
        }
    
        @Override
        public void setValueIsAdjusting(boolean b) {
            setUpdatesAllowed(true);
            super.setValueIsAdjusting(b);
            setUpdatesAllowed(false);
        }
    
        @Override
        public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) {        
            if (isUpdatesAllowed()) {
                super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
            }
        }
    
    }
    

    This would allow you to control the change of the "value" property. The problem you have here is that ALL the set methods go through the setRangeProperties method, so you need to decide what should be allowed to effect it. In my example, the only method that does not control it is the setValue method.

    In your code you would need to call it something like...

    MyBoundedRangeModel boundedRangeModel = new MyBoundedRangeModel();
    slider.setModel(boundedRangeModel);
    
    ...
    
    boundedRangeModel.setUpdatesAllowed(true);
    slider.setValue(value);
    boundedRangeModel.setUpdatesAllowed(false);
    

    Your only other choice is to extend the JSlider itself and override the setValue method directly in a similar way