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);
}
}
);
开发者_如何学Go
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);
精彩评论