
com.guigarage.flatterfx.skin.FlatterComboBoxSkin Maven / Gradle / Ivy
The newest version!
package com.guigarage.flatterfx.skin;
import java.util.ArrayList;
import java.util.UUID;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ComboBoxBase;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.util.Callback;
import javafx.util.StringConverter;
import com.guigarage.flatterfx.FlatterFX;
import com.guigarage.flatterfx.FlatterInputType;
import com.guigarage.flatterfx.overlay.OverlayPane;
import com.guigarage.flatterfx.overlay.OverlayType;
import com.guigarage.flatterfx.skin.touch.FlatterTouchComboBoxBehavior;
import com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior;
import com.sun.javafx.scene.control.behavior.KeyBinding;
import com.sun.javafx.scene.control.skin.ComboBoxBaseSkin;
public class FlatterComboBoxSkin extends ComboBoxBaseSkin {
private ListView popup;
private ListCell buttonCell;
private ChangeListener selectionBindingListener;
private UUID popupShowId;
public FlatterComboBoxSkin(ComboBoxBase comboBox) {
super(comboBox, getBehavior(comboBox));
if (!(comboBox instanceof ComboBox>)) {
throw new RuntimeException(
"FlatterComboBoxSkin only works with ComboBox");
}
buttonCell = getCombobox().getButtonCell() != null ? getCombobox()
.getButtonCell() : getDefaultCellFactory().call(getPopup());
buttonCell.setMouseTransparent(true);
buttonCell.updateListView(getPopup());
}
private static ComboBoxBaseBehavior getBehavior(ComboBoxBase comboBox) {
if(FlatterFX.getInstance().getInputType().equals(FlatterInputType.TOUCH)) {
return new ComboBoxBaseBehavior<>(comboBox, new ArrayList());
}
return new FlatterTouchComboBoxBehavior<>(comboBox);
}
protected ComboBox getCombobox() {
return (ComboBox) getSkinnable();
}
private ChangeListener getSelectionBindingListener() {
if (selectionBindingListener == null) {
selectionBindingListener = new ChangeListener() {
@Override
public void changed(
ObservableValue extends Number> observable,
Number oldValue, Number newValue) {
getCombobox().getSelectionModel().select(
newValue.intValue());
}
};
}
return selectionBindingListener;
}
private void bindComboBoxSelectionToPopupSelection() {
getPopup().getSelectionModel().selectedIndexProperty()
.addListener(getSelectionBindingListener());
}
private void unbindComboBoxSelectionFromPopupSelection() {
getPopup().getSelectionModel().selectedIndexProperty()
.removeListener(getSelectionBindingListener());
}
public ListView getPopup() {
if (popup == null) {
popup = new ListView<>();
popup.cellFactoryProperty().bind(
getCombobox().cellFactoryProperty());
popup.itemsProperty().bind(getCombobox().itemsProperty());
getCombobox().getSelectionModel().selectedIndexProperty()
.addListener(new ChangeListener() {
@Override
public void changed(
ObservableValue extends Number> observable,
Number oldValue, Number newValue) {
unbindComboBoxSelectionFromPopupSelection();
popup.getSelectionModel().select(
newValue.intValue());
if (newValue.intValue() > -1) {
buttonCell.setItem(null);
buttonCell.updateIndex(newValue.intValue());
}
bindComboBoxSelectionToPopupSelection();
}
});
bindComboBoxSelectionToPopupSelection();
}
return popup;
}
private boolean updateDisplayText(ListCell cell, T item, boolean empty) {
if (empty) {
if (cell == null)
return true;
cell.setGraphic(null);
cell.setText(null);
return true;
} else if (item instanceof Node) {
Node currentNode = cell.getGraphic();
Node newNode = (Node) item;
if (currentNode == null || !currentNode.equals(newNode)) {
cell.setText(null);
cell.setGraphic(newNode);
}
return newNode == null;
} else {
// run item through StringConverter if it isn't null
StringConverter c = getCombobox().getConverter();
// prompt text used to be displayed in the display text of a
// non-editable node, but was removed as per RT-29284
String s = item == null ? /* comboBox.getPromptText() */""
: (c == null ? item.toString() : c.toString(item));
cell.setText(s);
cell.setGraphic(null);
return s == null || s.isEmpty();
}
}
private Callback, ListCell> getDefaultCellFactory() {
return new Callback, ListCell>() {
@Override
public ListCell call(ListView listView) {
return new ListCell() {
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
updateDisplayText(this, item, empty);
}
};
}
};
}
@Override
public Node getDisplayNode() {
return buttonCell;
}
@Override
public void show() {
if (popupShowId == null) {
popupShowId = FlatterFX.getInstance()
.getOverlayLayer(getSkinnable().getScene())
.show("Select", new Image(OverlayPane.class.getResource("defaultListIcon.png").toString()), getPopup(), OverlayType.POPUP);
}
}
@Override
public void hide() {
if (popupShowId != null) {
FlatterFX.getInstance().getOverlayLayer(getSkinnable().getScene())
.hide(popupShowId);
popupShowId = null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy