Package hs.javafx.control

Source Code of hs.javafx.control.Carousel

package hs.javafx.control;

import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.value.WeakChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.WeakListChangeListener;
import javafx.geometry.Orientation;
import javafx.scene.control.Control;
import javafx.scene.control.FocusModel;
import javafx.util.Callback;

public class Carousel<T> extends Control {
  private final ObjectProperty<ObservableList<T>> items = new SimpleObjectProperty<>();
  public final ObjectProperty<ObservableList<T>> itemsProperty() { return items; }
  public final ObservableList<T> getItems() { return items.get(); }

  private final ObjectProperty<Orientation> orientation = new SimpleObjectProperty<>(Orientation.HORIZONTAL);
  public final ObjectProperty<Orientation> orientationProperty() { return orientation; }
  public final Orientation getOrientation() { return orientation.get(); }

  private final ObjectProperty<Callback<Carousel<T>, CarouselCell<T>>> cellFactory = new SimpleObjectProperty<>();
  public final ObjectProperty<Callback<Carousel<T>, CarouselCell<T>>> cellFactoryProperty() { return cellFactory; }
  public final Callback<Carousel<T>, CarouselCell<T>> getCellFactory() { return cellFactory.get(); }

  private final ObjectProperty<FocusModel<T>> focusModel = new SimpleObjectProperty<>();
  public final ObjectProperty<FocusModel<T>> focusModelProperty() { return focusModel; }
  public final FocusModel<T> getFocusModel() { return focusModel.get(); }

  private final IntegerProperty visibleCellsCount = new SimpleIntegerProperty(30);
  public final IntegerProperty visibleCellsCountProperty() { return visibleCellsCount; }
  public final int getVisibleCellsCount() { return visibleCellsCount.get(); }

  private final DoubleProperty cellAlignment = new SimpleDoubleProperty(0.5);
  public final DoubleProperty cellAlignmentProperty() { return cellAlignment; }
  public final double getCellAlignment() { return cellAlignment.get(); }

  private final BooleanProperty reflectionEnabled = new SimpleBooleanProperty(true);
  public final BooleanProperty reflectionEnabledProperty() { return reflectionEnabled; }
  public final boolean getReflectionEnabled() { return reflectionEnabled.get(); }

  private final BooleanProperty clipReflections = new SimpleBooleanProperty(true);
  public final BooleanProperty clipReflectionsProperty() { return clipReflections; }
  public final boolean getClipReflections() { return clipReflections.get(); }

  private final DoubleProperty fieldOfViewRatio = new SimpleDoubleProperty(0.5);
  public final DoubleProperty fieldOfViewRatioProperty() { return fieldOfViewRatio; }
  public final double getFieldOfViewRatio() { return fieldOfViewRatio.get(); }

  private final DoubleProperty radiusRatio = new SimpleDoubleProperty(0.5);
  public final DoubleProperty radiusRatioProperty() { return radiusRatio; }
  public final double getRadiusRatio() { return radiusRatio.get(); }

  private final DoubleProperty viewDistanceRatio = new SimpleDoubleProperty(1.0);
  public final DoubleProperty viewDistanceRatioProperty() { return viewDistanceRatio; }
  public final double getViewDistanceRatio() { return viewDistanceRatio.get(); }

  private final DoubleProperty density = new SimpleDoubleProperty(0.02);
  public final DoubleProperty densityProperty() { return density; }
  public final double getDensity() { return density.get(); }

  private final DoubleProperty cellSizeRatio = new SimpleDoubleProperty(0.6);
  public final DoubleProperty cellSizeRatioProperty() { return cellSizeRatio; }
  public final double getCellSizeRatio() { return cellSizeRatio.get(); }

  private final ReadOnlyDoubleWrapper maxCellWidth = new ReadOnlyDoubleWrapper();
  public final ReadOnlyDoubleProperty maxCellWidthProperty() { return maxCellWidth.getReadOnlyProperty(); }
  public final double getMaxCellWidth() { return maxCellWidth.get(); }

  private final ReadOnlyDoubleWrapper maxCellHeight = new ReadOnlyDoubleWrapper();
  public final ReadOnlyDoubleProperty maxCellHeightProperty() { return maxCellHeight.getReadOnlyProperty(); }
  public final double getMaxCellHeight() { return maxCellHeight.get(); }

  public Carousel() {
    getStyleClass().setAll("carousel");

    ObservableList<T> observableArrayList = FXCollections.observableArrayList();

    items.set(observableArrayList);
    focusModel.set(new CarouselFocusModel<>(this));

    maxCellWidth.bind(new DoubleBinding() {
      {
        bind(orientation);
        bind(cellSizeRatio);
        bind(widthProperty());
        bind(heightProperty());
      }

      @Override
      protected double computeValue() {
        return getCellSizeRatio() * (getOrientation() == Orientation.HORIZONTAL ? getHeight() : getWidth());
      }
    });

    maxCellHeight.bind(new DoubleBinding() {
      {
        bind(orientation);
        bind(cellSizeRatio);
        bind(widthProperty());
        bind(heightProperty());
      }

      @Override
      protected double computeValue() {
        return getCellSizeRatio() * (getOrientation() == Orientation.HORIZONTAL ? getHeight() : getWidth());
      }
    });
  }

  @Override
  protected String getUserAgentStylesheet() {
    return "css/Carousel.css";
  }

  static class CarouselFocusModel<T> extends FocusModel<T> {
    private final Carousel<T> carousel;

    private ChangeListener<ObservableList<T>> itemsListener = new ChangeListener<ObservableList<T>>() {
      @Override
      public void changed(ObservableValue<? extends ObservableList<T>> observableValue, ObservableList<T> old, ObservableList<T> current) {
        updateItemsObserver(current, current);
      }
    };

    private WeakChangeListener<ObservableList<T>> weakItemsListener = new WeakChangeListener<>(this.itemsListener);

    private final ListChangeListener<T> itemsContentListener = new ListChangeListener<T>() {
      @Override
      public void onChanged(ListChangeListener.Change<? extends T> change) {
        change.next();

        int i = change.getFrom();
        if(getFocusedIndex() == -1 || i > getFocusedIndex()) {
          return;
        }

        change.reset();
        boolean bool1 = false;
        boolean bool2 = false;
        int j = 0;
        int k = 0;
        while(change.next()) {
          bool1 |= change.wasAdded();
          bool2 |= change.wasRemoved();
          j += change.getAddedSize();
          k += change.getRemovedSize();
        }

        if((bool1) && (!bool2)) {
          focus(getFocusedIndex() + j);
        }
        else if((!bool1) && (bool2)) {
          focus(getFocusedIndex() - k);
        }
      }
    };

    private WeakListChangeListener<T> weakItemsContentListener = new WeakListChangeListener<>(this.itemsContentListener);

    public CarouselFocusModel(Carousel<T> carousel) {
      if(carousel == null) {
        throw new IllegalArgumentException("Carousel can not be null");
      }

      this.carousel = carousel;
      this.carousel.itemsProperty().addListener(this.weakItemsListener);
      if(carousel.getItems() != null) {
        this.carousel.getItems().addListener(this.weakItemsContentListener);
      }
    }

    private void updateItemsObserver(ObservableList<T> oldList, ObservableList<T> currentList) {
      if(oldList != null) {
        oldList.removeListener(this.weakItemsContentListener);
      }
      if(currentList != null) {
        currentList.addListener(this.weakItemsContentListener);
      }
    }

    @Override
    protected int getItemCount() {
      return isEmpty() ? -1 : carousel.getItems().size();
    }

    @Override
    protected T getModelItem(int paramInt) {
      if(isEmpty() || paramInt < 0 || paramInt >= getItemCount()) {
        return null;
      }

      return carousel.getItems().get(paramInt);
    }

    private boolean isEmpty() {
      return carousel == null || carousel.getItems() == null;
    }
  }
}
TOP

Related Classes of hs.javafx.control.Carousel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.