Удалить значение, отображаемое над большим пальцем в JSlider

У меня есть небольшая проблема с моим JSlider, которую я не смог решить. Чтобы немного объяснить ситуацию, я должен сделать JSlider, перемещающийся от 0 до 20 через 0,1 шага. Я нашел выход из проблем, создав JSlider от 0 до 200 и переопределив метки под ползунком, чтобы отображать правильные проценты вместо целых значений.

Но у меня есть одна последняя проблема: я использую пользовательский L&F (который я не могу изменить, очевидно, так как он от клиента), который отображает значение поверх ползунка. Однако это значение отображается... стандартным образом, как целое число. Из того, что я смог понять, это отображение связано со свойством Slider.paintValue, как я вижу в исходном коде javax.swing.plaf.synth.SynthSliderUI. Тем не менее, я был резко не в состоянии удалить его.

Что я пробовал на данный момент:

UIManager.getLookAndFeelDefaults().put("Slider.paintValue", false);
UIManager.put("Slider.paintValue", false);

Ни один из этих двоих ничего не изменил.

Есть ли поблизости гуру Swing, который мог бы вытащить меня из этого?


person Valentin Rocher    schedule 16.12.2010    source источник
comment
Хм, я не могу этого сделать, так как это коммерческий код. Кроме того, единственное, что я делаю, это создаю JSlider, а затем пытаюсь его установить. SSCCE здесь не применяется.   -  person Valentin Rocher    schedule 17.12.2010


Ответы (2)


Я только что создал демонстрацию с JSlider и с использованием базового Synth LAF, и я могу подтвердить, что установка этих свойств не имеет никакого эффекта, что странно и очень раздражает.

Я посмотрел на SynthSliderUI и вижу, что protected boolean paintValue устанавливается в private void updateStyle(JSlider c), поэтому, если вы хотите создать собственное расширение этого класса, установите значение paintValue в false, а затем установите пользовательский интерфейс вашего ползунка на новый пользовательский интерфейс с setUI(), вы может стать ближе. Либо так, либо полностью переопределить методы рисования, скопировав код из оригинала, но удалив часть, которая рисует значение большого пальца.

Теперь SynthSliderUI сам по себе является пакетным, но в любом случае это не проблема, поскольку вы используете предоставленный клиентом LAF. Если их собственный класс пользовательского интерфейса слайдера является общедоступным и неокончательным, вы можете сделать взломанную версию, как я описал выше, и применить ее к своему слайдеру.

Если это окончательно, вы можете использовать отражение, чтобы изменить это поле paintValue в качестве последнего средства (возможно, непосредственно перед рисованием слайдера). У меня работает следующий хак (уберите вызов отражения, который устанавливает для поля значение false, чтобы увидеть, что значение большого пальца рисуется):

import java.awt.BorderLayout;
import java.lang.reflect.Field;

import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class SliderDemo {

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel("javax.swing.plaf.synth.SynthLookAndFeel");

        Class<?> sliderUIClass = Class.forName("javax.swing.plaf.synth.SynthSliderUI");
        final Field paintValue = sliderUIClass.getDeclaredField("paintValue");
        paintValue.setAccessible(true);

        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLayout(new BorderLayout());

                JSlider slider = new JSlider(3, 6, 4);
                try {
                    paintValue.set(slider.getUI(), false);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                f.add(slider, BorderLayout.CENTER);

                f.pack();
                f.setVisible(true);
            }
        });
    }

}
person BoffinBrain    schedule 17.12.2010
comment
Святое дерьмо, почему я не мог подумать об использовании отражения для этого? Я думаю, что ваше решение может сработать. Как только у меня будет время протестировать его, я сообщу вам и отмечу ответ на вопрос :) - person Valentin Rocher; 17.12.2010
comment
Чувак, ты действительно спас мне жизнь этим. Так что извините, что не могу назначить вознаграждение за этот вопрос, я действительно хотел бы дать вам немного больше репутации. После ответов на многие вопросы здесь, это один из первых, которые я задал, и я так счастлив. Еще раз спасибо ! - person Valentin Rocher; 17.12.2010
comment
Без проблем. :) Ужасно, как часто в таких ситуациях на помощь приходит Reflection! - person BoffinBrain; 20.12.2010

Звонок UIManager.put("Slider.paintValue", false) перед звонком initComponents() сработал для меня.

person jacknad    schedule 19.03.2012