2009-12-29 28 views
0

我有一个JSlider与65536不同的值。它适用于粗调和非常精细的调整(+/- 1使用上/下箭头),但在中间很差。swing:JSlider但粗略/精细控制?

有没有什么会更好?我可以隐约想象用2个滑块进行粗调+精细调整,但无法真正弄清楚如何让他们一起工作。

回答

1

如何使用JSpinner而不是JSlider?使用SpinnerNumberModel,您可以设置步长,甚至可以动态更改步长。

如果您有多个控件,您甚至可以有两个微调器,一个用于设置数值,另一个用于设置第一个微调器使用的步长。

对于这样的一个例子,我把SliderDemo代码从Swing slider tutorial和改性它,而不是使用两个JSpinners而不是一个单一的JSlider。下面是我改变了代码的最有趣的部分:

//Create the slider^H^H^H^H^H^H spinners. 
// JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL, 
//          FPS_MIN, FPS_MAX, FPS_INIT); 
final int initStep = 1; 
final SpinnerNumberModel animationModel = new SpinnerNumberModel(FPS_INIT, 
                   FPS_MIN, 
                   FPS_MAX, 
                   initStep); 
final SpinnerNumberModel stepSizeModel = new SpinnerNumberModel(initStep, 
                   1, 
                   10, 
                   1); 
final JSpinner framesSpinner = new JSpinner(animationModel); 
framesSpinner.addChangeListener(this); 

final JSpinner stepSpinner = new JSpinner(stepSizeModel); 
stepSpinner.addChangeListener(new ChangeListener() 
{ 
    public void stateChanged(ChangeEvent arg0) 
    { 
     animationModel.setStepSize(stepSizeModel.getNumber()); 
    } 
}); 

我也不得不做出一堆不太有趣的变化,如创建为步长微调标签,添加新标签和新的微调器并更改方法this,以将事件来源转换为JSpinner,而不是将其转换为JSlider

当然,您可以详细阐述此问题,例如增加步长微调器的步长(例如,以便您可以通过单击将步长从1更改为101)。您还可以使用其他控件而不是JSpinner来设置步长,例如组合框。

最后,为了使这一切非常容易使用,您可能需要连接一些按键加速器(可能通过菜单?),以便您可以更改步长而无需实际移动鼠标或键盘焦点一个微调到另一个。

编辑:既然你必须使用一个JSlider不管是什么,你知道,你可以用PgUp/PgDn键上下移动1/10 日总范围的

如果你想改变那个1/10 th的数量(比如使它变成动态的),那么你需要重写方法BasicSliderUI.scrollByBlock()

这里就是我刚刚推翻的UI类JSlider的步骤由1/4范围一个例子,而不是1/10

//Create the slider. 
JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL, 
             FPS_MIN, FPS_MAX, FPS_INIT); 
framesPerSecond.setUI(new javax.swing.plaf.metal.MetalSliderUI() { 

    private static final int SLIDER_FRACTION = 4; 

    /** 
    * This code is cut, paste, and modified from 
    * {@link javax.swing.plaf.basic.BasicSliderUI#scrollByBlock(int). 
    * I should be ashamed of cutting and pasting, but whoever hardcoded the magic 
    * number "10" in the original code should be more ashamed than me. ;-) 
    * 
    * @param direction 
    *   either +1 or -1 
    */ 
    @Override 
    public void scrollByBlock(final int direction) { 
     synchronized(slider) { 
      int oldValue = slider.getValue(); 
      int blockIncrement = (slider.getMaximum() - slider.getMinimum())/SLIDER_FRACTION; 
      if (blockIncrement <= 0 && slider.getMaximum() > slider.getMinimum()) { 
       blockIncrement = 1; 
      } 
      int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL); 
      slider.setValue(oldValue + delta);   
     } 
    } 
}); 

从这里用另一个滑块或微调器设置的变量代替常量SLIDER_FRACTION不会太难,是不是?

+0

谢谢,我也喜欢spinners,但我需要在这个应用程序中的滑块。也许一个微调+滑块组合会很好。 – 2010-03-03 16:35:08

+0

如果您绝对必须使用滑块,那么也许您可以通过动态修改滴答间距并启用捕捉到滴答行为来获得所需的行为?我不确定这是如何与使用滑块上的箭头键相互作用的,但值得研究。 – 2010-03-04 01:15:42

+0

好吧,我想出了一个方法来做这件事,只是'JSlider',我相应地编辑了我的答案。感谢您挑战我寻找更好的解决方案。 :-) – 2010-03-04 02:43:00