【问题标题】:Remove value displaying over thumb in JSlider删除在 JSlider 中显示在拇指上的值
【发布时间】:2011-05-26 12:58:12
【问题描述】:

我的 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);

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

这里有什么 Swing 大师可以让我摆脱困境吗?

【问题讨论】:

  • 嗯,我不能这样做,因为这是商业代码。此外,我唯一要做的就是创建一个 JSlider,然后尝试设置它。 SSCCE 在这里并不真正适用。

标签: java swing jslider


【解决方案1】:

在调用initComponents() 之前调用UIManager.put("Slider.paintValue", false) 对我有用。

【讨论】:

    【解决方案2】:

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

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

    现在,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);
                }
            });
        }
    
    }

    【讨论】:

    • 天哪,为什么我不能想到使用反射来做到这一点?我认为您的解决方案可能有效。一旦我有时间测试它,我会告诉你并标记问题已回答:)
    • 伙计,你真的救了我的命。很抱歉不能在这个问题上悬赏,我真的很想给你更多的代表。在这里回答了很多问题之后,这是我问的第一个问题,我很高兴。再次感谢!
    • 没问题。 :) 在这种情况下,Reflection 经常来救援真是太可怕了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2019-12-16
    • 2023-03-25
    相关资源
    最近更新 更多