java slider gkwr,JavaFX 2.2手动配置Slider刻度

该博客介绍了如何在JavaFX中创建一个定制的Slider,使得用户只能选择预设的特定值,如2, 4, 8, 16, 32。通过扩展Slider类并使用DoubleFunction来实现自定义的刻度标签和值。示例代码展示了如何设置SnapToTicks以及监听valueChangingProperty来过滤和记录用户操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

We can create pre-created Minor and Major Ticks by modifying the Minor and MajorTicks of the Slider in JavaFX. But I want to enable the user only to select pre-configured values by me like 2, 4, 8, 16, 32. We have snapToTicks to solve one problem, but

How do I enable only specific tick marks or disable the others?

I could probably filter only the wanted values out from valueProperty but is there either a smarter solution or a way to do it natively?

Due to a bug in JavaFX 2.2 it is not possible to format the labels in the SliderClass, thus you need to use JavaFX 8. The values are still calculated probably and just displayed wrongly.

I add a modified version for JavaFX 2.2

FunctionalSlider.java

public class FunctionalSlider extends Slider {

private ReadOnlyDoubleWrapper functionValue = new ReadOnlyDoubleWrapper();

public FunctionalSlider() {

this.valueProperty().addListener(new ChangeListener() {

@Override

public void changed(ObservableValue extends Number> observable, Number oldValue, Number newValue) {

functionValue.set(Math.pow(2, getValue()));

}

});

this.setLabelFormatter(new StringConverter() {

@Override

public Double fromString(String string) {

return 0.0;

}

@Override

public String toString(Double object) {

return String.format("%1$.0f", Math.pow(2, object));

}

});

}

public double getFunctionValue() {

return functionValue.get();

}

public ReadOnlyDoubleProperty functionValueProperty() {

return functionValue.getReadOnlyProperty();

}

}

FunctionalSliderSample

public class FunctionalSliderSample extends Application {

private final ListView startLog = new ListView();

private final ListView endLog = new ListView();

@Override public void start(Stage stage) throws Exception {

Pane logsPane = createLogsPane();

Slider slider = createMonitoredSlider();

VBox layout = new VBox(10);

layout.setAlignment(Pos.CENTER);

layout.setPadding(new Insets(10));

layout.getChildren().setAll(

slider,

logsPane

);

VBox.setVgrow(logsPane, Priority.ALWAYS);

stage.setTitle("Slider Value Change Logger");

stage.setScene(new Scene(layout));

stage.show();

}

private Slider createMonitoredSlider() {

final FunctionalSlider slider = new FunctionalSlider();

slider.setMin(0);

slider.setValue(1);

slider.setMax(5);

slider.setMajorTickUnit(1);

slider.setMinorTickCount(0);

slider.setShowTickMarks(true);

slider.setShowTickLabels(true);

slider.setSnapToTicks(true);

slider.setMinHeight(Slider.USE_PREF_SIZE);

slider.valueChangingProperty().addListener(new ChangeListener() {

@Override

public void changed(ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) {

slider.setValue(Math.round(slider.getValue()));

String valueString = String.format("%1$.0f", slider.getFunctionValue());

if (slider.valueChangingProperty().get()) {

startLog.getItems().add(valueString);

}

else {

endLog.getItems().add(valueString);

}

}

});

return slider;

}

private HBox createLogsPane() {

HBox logs = new HBox(10);

logs.getChildren().addAll(

createLabeledLog("Start", startLog),

createLabeledLog("End", endLog)

);

return logs;

}

public Pane createLabeledLog(String logName, ListView log) {

Label label = new Label(logName);

label.setLabelFor(log);

VBox logPane = new VBox(5);

logPane.getChildren().setAll(

label,

log

);

logPane.setAlignment(Pos.TOP_LEFT);

return logPane;

}

public static void main(String[] args) { launch(args); }

}

解决方案

Here is an answer based on earlier sample code from: JavaFX 2.2: Hooking Slider Drag n Drop Events.

tWUiv.png

The sample extends Slider with a FunctionalSlider class that takes a DoubleFunction as an argument. Applications of the DoubleFunction create custom tick labels using a slider labelFormatter. The DoubleFunction also supplies values to a functionValue property which represents the value of the function evaluated at a given tick mark. The code uses Java 8.

import javafx.application.Application;

import javafx.beans.property.*;

import javafx.geometry.*;

import javafx.scene.Scene;

import javafx.scene.control.*;

import javafx.scene.layout.*;

import javafx.stage.Stage;

import javafx.util.StringConverter;

import java.util.function.DoubleFunction;

class FunctionalSlider extends Slider {

private ReadOnlyDoubleWrapper functionValue = new ReadOnlyDoubleWrapper();

public FunctionalSlider(DoubleFunction function) {

valueProperty().addListener(observable ->

functionValue.set(

function.apply(getValue())

)

);

setLabelFormatter(new StringConverter() {

@Override

public String toString(Double x) {

return String.format(

"%1$.0f",

function.apply(x)

);

}

@Override

public Double fromString(String s) {

return null;

}

});

}

public double getFunctionValue() {

return functionValue.get();

}

public ReadOnlyDoubleProperty functionValueProperty() {

return functionValue.getReadOnlyProperty();

}

}

public class FunctionalSliderSample extends Application {

private final ListView startLog = new ListView<>();

private final ListView endLog = new ListView<>();

@Override public void start(Stage stage) throws Exception {

Pane logsPane = createLogsPane();

Slider slider = createMonitoredSlider();

VBox layout = new VBox(10);

layout.setAlignment(Pos.CENTER);

layout.setPadding(new Insets(10));

layout.getChildren().setAll(

slider,

logsPane

);

VBox.setVgrow(logsPane, Priority.ALWAYS);

stage.setTitle("Slider Value Change Logger");

stage.setScene(new Scene(layout));

stage.show();

}

private Slider createMonitoredSlider() {

final FunctionalSlider slider = new FunctionalSlider(

x -> Math.pow(2, x)

);

slider.setMin(0);

slider.setValue(1);

slider.setMax(5);

slider.setMajorTickUnit(1);

slider.setMinorTickCount(0);

slider.setShowTickMarks(true);

slider.setShowTickLabels(true);

slider.setSnapToTicks(true);

slider.setMinHeight(Slider.USE_PREF_SIZE);

slider.valueChangingProperty().addListener(observable -> {

slider.setValue(Math.round(slider.getValue()));

String valueString = String.format(

"%1$.2f",

slider.getFunctionValue()

);

if (slider.valueChangingProperty().get()) {

startLog.getItems().add(

valueString

);

} else {

endLog.getItems().add(

valueString

);

}

});

return slider;

}

private HBox createLogsPane() {

HBox logs = new HBox(10);

logs.getChildren().addAll(

createLabeledLog("Start", startLog),

createLabeledLog("End", endLog)

);

return logs;

}

public Pane createLabeledLog(String logName, ListView log) {

Label label = new Label(logName);

label.setLabelFor(log);

VBox logPane = new VBox(5);

logPane.getChildren().setAll(

label,

log

);

logPane.setAlignment(Pos.TOP_LEFT);

return logPane;

}

public static void main(String[] args) { launch(args); }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值