在下面的示例中,滚动条的块增量设置为100.但是,实际值似乎是1到100之间的值,具体取决于您在轨迹栏上单击的位置。
运行示例时,请尝试多次在轨道中间大致单击以向下滚动。当我这样做时,我得到如下输出:
ScrollBar Max: 400.0
LayoutY: -100.0
LayoutY: -200.0
LayoutY: -300.0
LayoutY: -375.0 // this varies depending on the click location
无论我在哪里点击轨道,我都希望滚动单位改变100。 (即,一次只能看到一个标签)。
这是一个常见的滚动功能吗?如果有,有办法将其关闭吗?
以下是代码:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Orientation;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class ScrollBarSSCCE extends Application
{
@Override
public void start(Stage stage)
{
int labelWidth = 300;
int labelHeight = 100;
String[] styles =
{
"-fx-background-color: #336699;",
"-fx-background-color: #996633;",
"-fx-background-color: #ff0000;",
"-fx-background-color: #00ff00;",
"-fx-background-color: #0000ff;"
};
VBox vb = new VBox();
for (int i = 0; i < styles.length; i++)
{
Label label = new Label();
label.setPrefWidth( labelWidth );
label.setPrefHeight( labelHeight );
label.setStyle( styles[i] );
vb.getChildren().add( label );
}
ScrollBar sc = new ScrollBar();
sc.setOrientation(Orientation.VERTICAL);
sc.setLayoutX(labelWidth);
sc.setMin(0);
sc.setMax( (styles.length - 1) * labelHeight);
System.out.println("ScrollBar Max: " + sc.getMax());
sc.setPrefHeight( labelHeight );
sc.setUnitIncrement( labelHeight / 2 );
sc.setBlockIncrement( labelHeight );
sc.valueProperty().addListener(
(ObservableValue<? extends Number> ov, Number old_val, Number new_val) ->
{
double y = -new_val.doubleValue();
System.out.println("LayoutY: " + y);
vb.setLayoutY( y );
});
Group root = new Group();
root.getChildren().addAll(vb, sc);
Scene scene = new Scene(root, labelWidth+20, labelHeight);
stage.setScene(scene);
stage.setTitle("ScrollBar SSCCE");
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
答案 0 :(得分:1)
我无法给出一个很好的解释
System.out.println("block increment: " +sc.getBlockIncrement());
总是一样的,当我测试它时,它发生在双方下降或上升,我认为它与ScrollBar.adjustValue(position);
有关,所以如果我要提供一些我会说你最需要的时候调整Value
。
//in your value listener you can add these codes
if(new_val.doubleValue() > old_val.doubleValue()){ //going down
if(sc.getMax()-sc.getBlockIncrement() < Math.abs(y)){
sc.adjustValue(1);
}
}else{//going up
if(old_val.doubleValue() == sc.getBlockIncrement()){
sc.adjustValue(0);
}
}
我认为您可能希望将sc.setUnitIncrement(labelHeight/2);
设置为与sc.setBlockIncrement(labelHeight);
相同,因为该代码可能会破坏UnitIncrement
希望它能够:)
答案 1 :(得分:1)
ScrollBar.adjustValue(position)
方法负责此行为。
它基本上有三个步骤:
因为我总是想要&#34;新的价值&#34;我刚刚从adjustValue(...)
方法中删除了第3步。
以下是自定义ScrollBar
的代码:
ScrollBar sc = new ScrollBar()
{
@Override
public void adjustValue(double position)
{
// figure out the "value" associated with the specified position
double posValue = ((getMax() - getMin()) * Utils.clamp(0, position, 1)) + getMin();
double newValue;
if (Double.compare(posValue, getValue()) != 0)
{
if (posValue > getValue())
{
newValue = getValue() + getBlockIncrement();
}
else
{
newValue = getValue() - getBlockIncrement();
}
setValue( Utils.clamp(getMin(), newValue, getMax()) );
}
}
};