2013-09-19 2 views
1

Мы можем создать предварительно созданные мелкие и майоры, изменив Minor и MajorTicksSlider в JavaFX. Но я хочу, чтобы пользователь мог только выбрать предварительно настроенные значения, например, 2, 4, 8, 16, 32. У нас есть snapToTicks, чтобы решить одну проблему, ноJavaFX 2.2 настройка слайдерных ключей вручную

Как включить только определенные отметки или отключить другие?

Возможно, я мог отфильтровать только нужные значения из valueProperty, но есть ли более разумное решение или способ сделать это изначально?


Из-за ошибки в JavaFX 2.2 не представляется возможным форматировать метки в SliderClass, таким образом, вы должны использовать JavaFX 8. Значения по-прежнему вычисляются возможно и просто отображается неправильно.

добавить модифицированную версию для JavaFX 2.2

FunctionalSlider.java

общественного класса FunctionalSlider расширяет Slider { частный ReadOnlyDoubleWrapper functionValue = новый 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); } 
} 

ответ

2

Вот ответ, основанный на ранее примере кода из: JavaFX 2.2: Hooking Slider Drag n Drop Events.

slider value change logger

Образец расширяет Slider с FunctionalSlider класса, который принимает DoubleFunction в качестве аргумента. Приложения DoubleFunction создают пользовательские метки меток с помощью слайдера labelFormatter. DoubleFunction также поставляет значения в свойство functionValue, которое представляет значение функции, оцененной с заданным тиком. Код использует 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); } 
} 
+0

Я принимаю ваш ответ, как решение, но он не работает в JavaFX 2.2, но только в JavaFX 8 поскольку эта ошибка в SliderClass где верстальщик даже не применяется. Кажется, что я должен придерживаться JavaFX 2.2 некоторое время, пока Java 8 не выпустят. Функционально он все еще работает, хотя так и признаю мою благодарность. Я редактирую свой пост, чтобы добавить код для JFX 2.2 и уведомление. – thatsIch

+0

Очевидно, что в [отчете об ошибке] (https://javafx-jira.kenai.com/browse/RT-18448) он отмечен как разрешенный, но я все еще не могу заставить его работать, мой код неисправен? – thatsIch

+1

Исправлена ​​ошибка форматирования метки RT-18448 (https://javafx-jira.kenai.com/browse/RT-18448) в Lombard (это кодовое имя для выпуска JavaFX 8), ошибка присутствует в Выпуски JavaFX 2.2. – jewelsea

Смежные вопросы