jSlider переходит в положение щелчка - проблема только на Macintosh

Я использую вышеупомянутое решение MetalSliderUI для всех своих JSlider. Пользователи Windows остались довольны. Я благодарен за то, что нашел это решение на stackoverflow.com. Решение обсуждалось здесь: JSlider question: Позиция после щелчка левой кнопкой мыши

Недавно пользователь MAC OSX/64bit пытается использовать мое программное обеспечение, и он получает исключения нулевого указателя из ссылок MetalSliderUI.

Пример кода, который я добавил в конструктор JFrame:

// 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 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)

Есть ли у вас какие-либо предложения по устранению этой проблемы, возникающей только на компьютерах Mac?

Говард


person howard    schedule 04.06.2011    source источник
comment
Вы на самом деле используете Metal LAF на MAC или просто пытаетесь использовать MetalSliderUI на MAC LAF?   -  person camickr    schedule 04.06.2011
comment
@camickr: Судя по ошибке, я подозреваю последнее, как было предложено здесь.   -  person trashgod    schedule 04.06.2011


Ответы (2)


Трудно сказать без SSCCE (еще сложнее без Mac для тестирования), но эти проблемы часто вызвано невозможностью обновить графический интерфейс на EDT. Дополнительные сведения см. в уроке Параллелизм в Swing в Учебном руководстве по Java.

person Andrew Thompson    schedule 04.06.2011
comment
Хорошая догадка (1+). У меня есть ощущение, что ОП будет нелегко сделать свой SSCCE, поскольку кажется, что пользователь испытывает ошибку, а не ОП, поэтому он не сможет воспроизвести ошибку на своем собственном поле. - person Hovercraft Full Of Eels; 04.06.2011
comment
@HFOE: Хороший вопрос. Я упустил тот факт, что код не работал на Mac. ОП. - person Andrew Thompson; 04.06.2011
comment
Да, у меня есть пользователь Mac в Германии, использующий мое программное обеспечение. Я живу в США и у меня нет доступа к Mac. - person howard; 05.06.2011

Проблема находится в строке 92 MetalSliderUI< /a>, которому, помимо прочего, требуется значение по умолчанию для пользовательского интерфейса с именем Slider.trackWidth. Значение не отображается в com.apple.laf.AquaSliderUI.

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

Простой альтернативой является использование BasicSliderUI. Более сложный подход заключается в инициализации MetalLookAndFeel и сохранении ссылки на ваш подкласс для последующего использования.

LookAndFeel save = UIManager.getLookAndFeel();
LookAndFeel laf = new MetalLookAndFeel();
UIManager.setLookAndFeel(laf);
SliderUI mySliderUI = new MetalSliderUI() { ... };
UIManager.setLookAndFeel(save);
person trashgod    schedule 04.06.2011
comment
Итак, вы думаете, все, что мне нужно сделать, это изменить new MetalSliderUI() { на new BasicSliderUI() {, и он должен работать на Windows, Linux и Mac? - person howard; 05.06.2011
comment
Оба подхода работают на Mac; это единственная платформа, которую я пробовал. Вот пример, который я использовал для проверки аномалии. Обновите свой вопрос с помощью sscce, используя то, что вам нравится. Я был бы рад попробовать его на Mac, и это могло бы привлечь одного или двух пользователей Linux. - person trashgod; 05.06.2011
comment
NO GO - не решает проблему. Первоначальная проблема заключалась в том, что я нажимаю на свой ползунок, и значение перемещается только на 1. - person howard; 05.06.2011
comment
У stackoverflow был ответ - у меня есть ссылка на код. Я использую этот код в десятках мест для всех своих слайдеров. Он отлично работает, я нажимаю на значение на шкале ползунка, и значение переходит к нему. Но это не работает на MAC. - person howard; 05.06.2011
comment
Ваш пример кода - абсолютно не похож на то, что я хочу. Я пытаюсь использовать SliderUI вместо MetalSliderUI — и он не компилируется. Я ценю вашу попытку помочь мне. Но я думаю, что вы полностью пропустили то, что я пытаюсь сделать - я думаю, вы не смотрели на исходную проблему и решение stackoverflow. Похоже, этот код работает только с MetalSliderUI. Java великолепна — напишите ее один раз, и она работает только в Windows. привет - person howard; 05.06.2011
comment
Я ценю ваши усилия в попытке помочь. Но я ТОЛЬКО пытаюсь изменить поведение своих jSliders, когда нажимаю на шкалу. Похоже, Java сделал дерьмовое поведение по умолчанию для качающихся элементов. Это больно настроить для правильной работы, и тогда это не будет работать на всех платформах. Я просто проверю, на какой операционной системе работает мое программное обеспечение, и если это MAC-адрес, то они получат плохое поведение ползунка. - person howard; 05.06.2011
comment
Да, BasicSliderUI довольно прост, но это хорошее начало для пользовательского слайдера. При отсутствии способа создания подкласса com.apple.laf.AquaSliderUI вы, вероятно, захотите использовать MetalSliderUI, как показано. Я действительно читал статью. Изменение на MetalSliderUI в моем примере просто раскрывает проблему. SliderUI абстрактно; вы должны использовать конкретный подкласс. Пожалуйста, ответьте на вопрос @camickr. Укажите sscce. - person trashgod; 05.06.2011