JavaFX 2.2手动配置Slider滴答 [英] JavaFX 2.2 configuring Slider ticks manually

查看:141
本文介绍了JavaFX 2.2手动配置Slider滴答的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以通过修改未成年人 滑块中的专业提示 JavaFX.但是我想让用户只能由我选择2, 4, 8, 16, 32之类的预配置值.我们有 snapToTicks 来解决一个问题,但

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?

我可能只能从 valueProperty ,但是有没有更聪明的解决方案或本地解决方案?

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?

由于JavaFX 2.2中的错误,无法在SliderClass中格式化标签,因此您需要使用JavaFX8.可能仍会计算值,并且显示错误.

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.

我为JavaFX 2.2添加了修改版本

I add a modified version for JavaFX 2.2

FunctionalSlider.java

公共类FunctionalSlider扩展了Slider { 私有ReadOnlyDoubleWrapper functionValue = new ReadOnlyDoubleWrapper();

public class FunctionalSlider extends Slider { private ReadOnlyDoubleWrapper functionValue = new ReadOnlyDoubleWrapper();

public FunctionalSlider() {
    this.valueProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
            functionValue.set(Math.pow(2, getValue()));
        }
    });

    this.setLabelFormatter(new StringConverter<Double>() {
        @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<String> startLog = new ListView<String>();
    private final ListView<String> endLog   = new ListView<String>();

    @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<Boolean>() {

            @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<String> 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.

该示例通过滑块进行了扩展带有 DoubleFunction FunctionalSlider类>作为参数. DoubleFunction的应用程序使用滑块 Java 8 .

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<Double> function) {
    valueProperty().addListener(observable ->
        functionValue.set(
            function.apply(getValue())
        )
    );

    setLabelFormatter(new StringConverter<Double>() {
      @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<String> startLog = new ListView<>();
    private final ListView<String> 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<String> 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); }
}

这篇关于JavaFX 2.2手动配置Slider滴答的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆