简体   繁体   中英

jSlider go to clicked position - problem only on Macintosh

I have been using the above MetalSliderUI solution for all my JSliders. Windows users have been happy with it. I appreciate finding this solution on stackoverflow.com The solution was discussed here: JSlider question: Position after leftclick

Now recently a MAC OSX/64bit user is trying to use my software and he gets null pointer exceptions from the MetalSliderUI references.

Sample of code which I added to JFrame's constructor:

// Radio Window Elecraft K3 RFPWR Slider - when click on slider
            // go to the value instead of going up/down one tick.
            jSliderElecraftK3RFPWR.setUI(
                new MetalSliderUI() {
                    protected void scrollDueToClickInTrack(int direction) {
                        int value = jSliderElecraftK3RFPWR.getValue();
                        if (jSliderElecraftK3RFPWR.getOrientation() == JSlider.HORIZONTAL) {
                            value = this.valueForXPosition(jSliderElecraftK3RFPWR.getMousePosition().x);
                        } else if (jSliderElecraftK3RFPWR.getOrientation() == JSlider.VERTICAL) {
                            value = this.valueForYPosition(jSliderElecraftK3RFPWR.getMousePosition().y);
                        }
                        jSliderElecraftK3RFPWR.setValue(value);
                    }
                }
            );

Exception which does not quote the exact line in my code:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at 
javax.swing.plaf.metal.MetalSliderUI.installUI(MetalSliderUI.java:92) at 
javax.swing.JComponent.setUI(JComponent.java:662) at 
javax.swing.JSlider.setUI(JSlider.java:300) at 
HamRadioIntegrator_N3ZH.JFrameRadio.(JFrameRadio.java) at 
HamRadioIntegrator_N3ZH.JFrameRadio$550.run(JFrameRadio.java) at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at 
java.awt.EventQueue.dispatchEventImpl(EventQueue.java:678) at 
java.awt.EventQueue.access$000(EventQueue.java:86) at 
java.awt.EventQueue$1.run(EventQueue.java:639) at 
java.awt.EventQueue$1.run(EventQueue.java:637) at 
java.security.AccessController.doPrivileged(Native Method) at 
java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:648) at 
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296) at 
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211) at 
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201) at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196) at 
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188) at  
java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Do you have any suggestions for fixing this problem which only occurs on Macs?

Howard

It is hard to say without an SSCCE (even harder without a Mac. to test with) but these problems are often caused by failing to update the GUI on the EDT. See the Concurrency in Swing lesson of the Java Tutorial for more details.

The problem is in line 92 of MetalSliderUI , which wants a UI default value named Slider.trackWidth , among others. The value does not appear in com.apple.laf.AquaSliderUI .

trackWidth = ((Integer)UIManager.get("Slider.trackWidth")).intValue();

A simple alternative is to use BasicSliderUI . A more complex approach is to initialize the MetalLookAndFeel and save a reference to your subclass for later use.

LookAndFeel save = UIManager.getLookAndFeel();
LookAndFeel laf = new MetalLookAndFeel();
UIManager.setLookAndFeel(laf);
SliderUI mySliderUI = new MetalSliderUI() { ... };
UIManager.setLookAndFeel(save);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM