swing:JSlider,但具有粗略/精细控制?
我有一个JSlider,有65536个不同的值。它对于粗调整和非常精细的调整(+/- 1使用上/下箭头)非常有效,但是在中间是非常差的。swing:JSlider,但具有粗略/精细控制?,swing,jslider,Swing,Jslider,我有一个JSlider,有65536个不同的值。它对于粗调整和非常精细的调整(+/- 1使用上/下箭头)非常有效,但是在中间是非常差的。 有没有更好的办法?我可以模糊地想象用两个滑块一个进行粗略+精细的调整,但我真的不知道如何让它们一起工作。用JSpinner代替JSlider怎么样?使用SpinnerNumberModel,您可以设置步长,甚至可以动态更改步长 如果可以使用多个控件,甚至可以使用两个微调器,一个用于设置值,另一个用于设置第一个微调器使用的步长 例如,我从中获取代码,并将其修改为
有没有更好的办法?我可以模糊地想象用两个滑块一个进行粗略+精细的调整,但我真的不知道如何让它们一起工作。用
JSpinner
代替JSlider
怎么样?使用SpinnerNumberModel
,您可以设置步长,甚至可以动态更改步长
如果可以使用多个控件,甚至可以使用两个微调器,一个用于设置值,另一个用于设置第一个微调器使用的步长
例如,我从中获取代码,并将其修改为使用两个jspinner
,而不是一个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());
}
});
我还必须做一些不太有趣的更改,例如为步长微调器创建标签,将新标签和新微调器添加到容器中,以及更改stateChanged()此
上的
方法将事件源强制转换为JSpinner
而不是强制转换为JSlider
当然,您可以对此进行进一步阐述,例如增加“步长”微调器的步长(例如,您可以通过单击将步长从1更改为101)。您还可以使用不同的控件而不是JSpinner
来设置步长,例如组合框
最后,为了使这一切真正易于使用,您可能希望连接一些击键加速器(可能通过菜单?),这样您就可以更改步长,而无需将鼠标或键盘焦点从一个微调器移动到另一个微调器
编辑:考虑到无论如何都必须使用JSlider
,您是否知道可以使用PgUp/PgDn上下移动总范围的1/10
如果要更改十分之一的金额(例如使其成为动态的),则需要重写方法BasicSliderUI.scrollByBlock()
下面是一个示例,我刚刚将JSlider
的UI类改写为1/4的步长,而不是1/10:
//创建滑块。
JSlider framesPerSecond=新的JSlider(JSlider.HORIZONTAL,
FPS_最小值、FPS_最大值、FPS_初始值);
framesPerSecond.setUI(新的javax.swing.plaf.metal.MetalSliderUI(){
私有静态最终整数滑块_分数=4;
/**
*此代码是从中剪切、粘贴和修改的
*{@linkjavax.swing.plaf.basic.BasicSliderUI#scrollByBlock(int)。
*我应该为剪切和粘贴感到羞耻,但是谁硬编码了魔法
*原始代码中的数字“10”应该比我更羞愧。;-)
*
*@param方向
*+1或-1
*/
@凌驾
公共无效滚动块(最终整数方向){
同步(滑块){
int oldValue=slider.getValue();
int blockIncrement=(slider.getMaximum()-slider.getMinimum())/slider\u分数;
if(blockIncrement slider.getMinimum()){
块增量=1;
}
int delta=块增量*((方向>0)?正滚动:负滚动);
slider.setValue(旧值+增量);
}
}
});
从这里开始,用一个由另一个滑块或微调器设置的变量替换常量
SLIDER\u FRACTION
,不是很难吗?谢谢,我也喜欢微调器,但我需要在这个应用程序中使用一个滑块。也许微调器+滑块组合会很好。如果你一定要使用滑块,那么也许你可以通过动态修改勾号间距并启用“捕捉到勾号”行为来获得所需的行为?我不确定这与使用滑块上的箭头键如何交互,但值得研究。好的,我找到了一种方法,只需使用JSlider
,并相应地编辑了我的答案。感谢您挑战我找到答案更好的解决方案。:-)
//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);
}
}
});