6

我的 JSlider 有一个小问题,我无法解决。为了稍微解释一下这种情况,我必须做一个从 0 到 20 的 JSlider,经过 0.1 个步骤。我通过创建一个从 0 到 200 的 JSlider 来解决问题,并重新定义了滑块下的标签以显示正确的百分比而不是整数值。

但我还有最后一个问题:我正在使用自定义 L&F(显然,我无法更改,因为它来自客户端),它在滑块拇指上显示值。然而,这个值以标准的方式显示为一个整数。据我所知,这个显示与Slider.paintValue属性有关,正如我在javax.swing.plaf.synth.SynthSliderUI源代码中看到的那样。但是,我一直无法将其删除。

我现在尝试过的:

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

这两个都没有改变任何东西。

附近有没有摇摆大师可以让我摆脱困境?

4

2 回答 2

4

我刚刚使用基本的 Synth LAF 创建了一个演示JSlider,我可以确认设置这些属性似乎根本没有效果,这很奇怪,也很烦人。

我已经看过了SynthSliderUI,我可以看到protected boolean paintValue设置在 中private void updateStyle(JSlider c),因此如果您要对此类进行自定义扩展,请将值设置paintValue为 false,然后使用 将滑块的 UI 设置为新 UI setUI(),您可能会更接近。要么,要么完全覆盖绘制方法,从原始代码中复制代码,但删除绘制拇指值的部分。

现在,SynthSliderUI它本身是包私有的,但这并不是真正的问题,因为您使用的是客户端提供的 LAF。如果他们的自定义滑块 UI 类是公开的且非最终的,您可以按照我上面描述的那样制作一个黑客版本,并将其应用于您的滑块。

如果它是最终的,那么您也许可以使用反射来更改该paintValue字段作为最后的手段(也许就在绘制滑块之前)。以下 hack 对我有用(取出将字段设置为 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);
            }
        });
    }

}
于 2010-12-17T14:54:33.870 回答
4

在为我工作UIManager.put("Slider.paintValue", false)之前打电话。initComponents()

于 2012-03-19T20:08:51.277 回答