jSlider go to clicked position - problem only on Macintosh
Asked Answered
A

2

3

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

Algiers answered 4/6, 2011 at 13:28 Comment(2)
Are you actually using the Metal LAF on the MAC or just trying to use the MetalSliderUI on the MAC LAF?Ample
@camickr: Judging by the error, I suspect the latter, as suggested here.Hives
M
1

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.

Metathesize answered 4/6, 2011 at 14:11 Comment(3)
A good guess (1+). I have a feeling that the OP will have a tough time making his SSCCE as it appears that the user is experiencing the error, not the OP, so he won't be able to reproduce the error on his own box.Quiteris
@HFOE: Good point. I missed the fact that the code was not running on the Mac. of the OP.Metathesize
Yes, I have a Mac user in Germany using my s/w. I live in the USA and do not have access to a Mac.Algiers
H
1

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);
Hives answered 4/6, 2011 at 17:21 Comment(7)
So, you think all I need to do is change "new MetalSliderUI() {" to be "new BasicSliderUI() {" and it should work on Windows, Linux, and Macs?Algiers
Both approaches work on Mac; it's the only platform I tried. Here's the example I used to verify the anomaly. Update you question with an sscce using whichever you like. I'd be happy to try it on Mac, and it might attract a Linux user or two.Hives
NO GO - does not solve the problem. The original problem was I click on my slider and the value only moves by 1.Algiers
stackoverflow had the answer - I have a link to the code. I use this code in dozens of places for all my slider. It works great, I click on a value on the slider's scale and the value jumps to it. But, it doesn't work on a MAC.Algiers
Your example code - looks absolutely nothing like what I want. I try using a SliderUI instead of MetalSliderUI - and it won't compile. I do appreciate your trying to help me. But I think you missed entirely what I am trying to do - I think you did not look at the original stackoverflow problem and solution. Seems that code only works with a MetalSliderUI. Java is great - write it once, and it only works right on windows. hihiAlgiers
I do appreciate your effort in trying to help. But, I am ONLY trying to change the behavior of my jSliders when I click on the scale. Looks like Java made crappy default behavior for swing items. It's a pain to customize to work the right way, and then it won't work on all platforms. I'll just check which operating system my s/w is running on - and if its MAC then they'll get bad slider behavior.Algiers
Yes, BasicSliderUI is quite plain, but it's a good start for a custom slider. Absent a way to subclass com.apple.laf.AquaSliderUI, you'll probably want to use MetalSliderUI, as shown. I certainly did read the article. Changing to MetalSliderUI in my example merely reveals the problem. SliderUI is abstract; you must use a concrete subclass. Please answer @camickr's question. Please supply an sscce.Hives

© 2022 - 2024 — McMap. All rights reserved.