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

Community
  • 1
  • 1
howard
  • 41
  • 4
  • Are you actually using the Metal LAF on the MAC or just trying to use the MetalSliderUI on the MAC LAF? – camickr Jun 04 '11 at 15:06
  • @camickr: Judging by the error, I suspect the latter, as suggested [here](http://stackoverflow.com/questions/6236998/jslider-go-to-clicked-position-problem-only-on-macintosh/6238251#6238251). – trashgod Jun 04 '11 at 17:27

2 Answers2

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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 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. – Hovercraft Full Of Eels Jun 04 '11 at 14:29
  • @HFOE: Good point. I missed the fact that the code was not running on the Mac. of the OP. – Andrew Thompson Jun 04 '11 at 14:47
  • 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. – howard Jun 04 '11 at 23:14
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);
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 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? – howard Jun 04 '11 at 23:17
  • Both approaches work on Mac; it's the only platform I tried. Here's the [example](http://stackoverflow.com/questions/2898023/custom-java-swing-meter-control/2898259#2898259) I used to verify the anomaly. Update you question with an [sscce](http://sscce.org) using whichever you like. I'd be happy to try it on Mac, and it might attract a Linux user or two. – trashgod Jun 05 '11 at 00:14
  • NO GO - does not solve the problem. The original problem was I click on my slider and the value only moves by 1. – howard Jun 05 '11 at 03:32
  • 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. – howard Jun 05 '11 at 03:33
  • 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. hihi – howard Jun 05 '11 at 03:33
  • 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. – howard Jun 05 '11 at 03:34
  • 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](http://stackoverflow.com/questions/518471). Changing to `MetalSliderUI` in my [example](http://stackoverflow.com/questions/2898023/custom-java-swing-meter-control/2898259#2898259) merely reveals the problem. `SliderUI` is abstract; you must use a concrete subclass. Please answer @camickr's question. Please supply an [sscce](http://sscce.org/). – trashgod Jun 05 '11 at 12:10