All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tentackle.fx.component.FxComboBox Maven / Gradle / Ivy

/*
 * Tentackle - https://tentackle.org.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

package org.tentackle.fx.component;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Skin;
import javafx.scene.control.skin.ComboBoxListViewSkin;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import org.tentackle.fx.CaseConversion;
import org.tentackle.fx.FxContainer;
import org.tentackle.fx.FxTextComponent;
import org.tentackle.fx.ModelToViewListener;
import org.tentackle.fx.ShortLongTextCellFactory;
import org.tentackle.fx.ValueTranslator;
import org.tentackle.fx.ViewToModelListener;
import org.tentackle.fx.bind.FxComponentBinding;
import org.tentackle.fx.component.delegate.FxComboBoxDelegate;
import org.tentackle.fx.table.FxTableCell;
import org.tentackle.fx.table.FxTreeTableCell;
import org.tentackle.misc.ShortLongText;

import java.lang.reflect.Type;
import java.util.List;
import java.util.function.Function;

/**
 * Extended {@link ComboBox}.
 *
 * @author harald
 * @param  the type
 */
public class FxComboBox extends ComboBox implements FxTextComponent {

  private Boolean deselectAllowed;
  private boolean shortLongTextEnabled = true;


  /**
   * Creates a default FxComboBox instance with an empty {@link #itemsProperty() items} list and default
   * selection model.
   */
  public FxComboBox() {
    addEventFilter(KeyEvent.KEY_PRESSED, this::filterKeyPressed);
  }


  /**
   * Returns whether deselect is allowed via delete or backspace key.
* If null, it is determined according to type and/or mandatory property. * If the type is a primitive or the component is mandatory, deselect is not allowed. * Otherwise it is allowed by default. * * @return true if allowed, null if determined from type and/or mandatory property */ public Boolean isDeselectAllowed() { return deselectAllowed; } /** * Sets whether deselect is allowed via delete or backspace key. * * @param deselectAllowed true if allowed, null if determined from type and/or mandatory property */ public void setDeselectAllowed(Boolean deselectAllowed) { this.deselectAllowed = deselectAllowed; } /** * Returns whether two-column list view enabled for items implementing {@link org.tentackle.misc.ShortLongText}. * * @return true if enabled (default) */ public boolean isShortLongTextEnabled() { return shortLongTextEnabled; } /** * Sets whether the listview popup should display items implementing {@link org.tentackle.misc.ShortLongText} * as two columns.
* This feature is enabled by default. * * @param shortLongTextEnabled true to enable, false to disable */ public void setShortLongTextEnabled(boolean shortLongTextEnabled) { this.shortLongTextEnabled = shortLongTextEnabled; } /** * Filter keyboard events. * * @param event the key event */ protected void filterKeyPressed(KeyEvent event) { if (!isDisabled()) { if (isEditable()) { if (event.getCode() == KeyCode.BACK_SPACE && event.isShiftDown() && !event.isControlDown() && !event.isAltDown() && !event.isMetaDown()) { // shift BACKSPACE -> clear editor contents event.consume(); getEditor().clear(); } } else { // deselect by DELETE- or BACKSPACE-key (with or without shift) in non-editable comboboxes if (getDelegate().isDeselectAllowed() && !event.isAltDown() && !event.isControlDown() && !event.isMetaDown() && !event.isShortcutDown() && (event.getCode() == KeyCode.DELETE || event.getCode() == KeyCode.BACK_SPACE)) { event.consume(); getSelectionModel().clearSelection(); } } } } @Override protected Skin createDefaultSkin() { return new ComboBoxListViewSkin<>(this) { @Override public Node getPopupContent() { if (isShortLongTextEnabled() && getCellFactory() == null && isTypeOfShortLongText()) { setCellFactory(createShortLongTextCellFactory()); } return super.getPopupContent(); } }; } /** * Creates a {@link ShortLongTextCellFactory}. * * @return the cell factory */ protected ShortLongTextCellFactory createShortLongTextCellFactory() { return new ShortLongTextCellFactory<>(); } /** * Returns whether the combobox' type implements {@link ShortLongText}. * * @return true if implements {@link ShortLongText} */ protected boolean isTypeOfShortLongText() { boolean shortLong = false; List items = getItems(); if (items != null && !items.isEmpty()) { // check item shortLong = items.get(0) instanceof ShortLongText; } else { Class clazz = getType(); if (clazz != null) { // no items, use the binding type shortLong = ShortLongText.class.isAssignableFrom(clazz); } } return shortLong; } // @wurblet delegate Include $currentDir/fxtextcomponent.include ////GEN-BEGIN:delegate private /**/FxComboBoxDelegate/**/ delegate; // @wurblet < Inject ${classname}Delegate /** * Creates the delegate. * * @return the delegate */ protected /**/FxComboBoxDelegate/**/ createDelegate() { // @wurblet < Inject ${classname}Delegate return new /**/FxComboBoxDelegate/**/(this); // @wurblet < Inject ${classname}Delegate } @Override public /**/FxComboBoxDelegate/**/ getDelegate() { // @wurblet < Inject ${classname}Delegate if (delegate == null) { setDelegate(createDelegate()); } return delegate; } /** * Sets the delegate.
* Useful for application specific needs. * * @param delegate the delegate */ public void setDelegate(/**/FxComboBoxDelegate/**/ delegate) { // @wurblet < Inject ${classname}Delegate this.delegate = delegate; } // @wurblet component Include $currentDir/component.include // @wurblet textcomponent Include $currentDir/textcomponent.include //
//GEN-END:delegate ////GEN-BEGIN:textcomponent @Override public void setColumns(int columns) { getDelegate().setColumns(columns); } @Override public int getColumns() { return getDelegate().getColumns(); } @Override public void setMaxColumns(int maxColumns) { getDelegate().setMaxColumns(maxColumns); } @Override public int getMaxColumns() { return getDelegate().getMaxColumns(); } @Override public void setAutoSelect(boolean autoSelect) { getDelegate().setAutoSelect(autoSelect); } @Override public boolean isAutoSelect() { return getDelegate().isAutoSelect(); } @Override public void setPattern(String pattern) { getDelegate().setPattern(pattern); } @Override public String getPattern() { return getDelegate().getPattern(); } @Override public boolean isLenient() { return getDelegate().isLenient(); } @Override public void setLenient(boolean lenient) { getDelegate().setLenient(lenient); } @Override public void setScale(int scale) { getDelegate().setScale(scale); } @Override public int getScale() { return getDelegate().getScale(); } @Override public void setUnsigned(boolean unsigned) { getDelegate().setUnsigned(unsigned); } @Override public boolean isUnsigned() { return getDelegate().isUnsigned(); } @Override public void setUTC(boolean utc) { getDelegate().setUTC(utc); } @Override public boolean isUTC() { return getDelegate().isUTC(); } @Override public void setCaseConversion(CaseConversion caseConversion) { getDelegate().setCaseConversion(caseConversion); } @Override public CaseConversion getCaseConversion() { return getDelegate().getCaseConversion(); } @Override public void setFiller(char filler) { getDelegate().setFiller(filler); } @Override public char getFiller() { return getDelegate().getFiller(); } @Override public void setTextAlignment(Pos textAlignment) { getDelegate().setTextAlignment(textAlignment); } @Override public Pos getTextAlignment() { return getDelegate().getTextAlignment(); } @Override public void setValidChars(String validChars) { getDelegate().setValidChars(validChars); } @Override public String getValidChars() { return getDelegate().getValidChars(); } @Override public void setInvalidChars(String invalidChars) { getDelegate().setInvalidChars(invalidChars); } @Override public String getInvalidChars() { return getDelegate().getInvalidChars(); } @Override public void setTextConverter(Function textConverter) { getDelegate().setTextConverter(textConverter); } @Override public Function getTextConverter() { return getDelegate().getTextConverter(); } @Override public void setErrorOffset(Integer errorOffset) { getDelegate().setErrorOffset(errorOffset); } @Override public Integer getErrorOffset() { return getDelegate().getErrorOffset(); } @Override public void mapErrorOffsetToCaretPosition() { getDelegate().mapErrorOffsetToCaretPosition(); } @Override public void autoSelect() { getDelegate().autoSelect(); } ////GEN-END:textcomponent ////GEN-BEGIN:component @Override public FxContainer getParentContainer() { return getDelegate().getParentContainer(); } @Override public void setValueTranslator(ValueTranslator valueTranslator) { getDelegate().setValueTranslator(valueTranslator); } @Override public ValueTranslator getValueTranslator() { return getDelegate().getValueTranslator(); } @Override public void invalidateSavedView() { getDelegate().invalidateSavedView(); } @Override public boolean isSavedViewObjectValid() { return getDelegate().isSavedViewObjectValid(); } @Override public V getViewValue() { return getDelegate().getViewValue(); } @Override public void setViewValue(Object value) { getDelegate().setViewValue(value); } @Override public void setType(Class type) { getDelegate().setType(type); } @Override public Class getType() { return getDelegate().getType(); } @Override public void setGenericType(Type type) { getDelegate().setGenericType(type); } @Override public Type getGenericType() { return getDelegate().getGenericType(); } @Override public void updateView() { getDelegate().updateView(); } @Override public void updateModel() { getDelegate().updateModel(); } @Override public void addModelToViewListener(ModelToViewListener listener) { getDelegate().addModelToViewListener(listener); } @Override public void removeModelToViewListener(ModelToViewListener listener) { getDelegate().removeModelToViewListener(listener); } @Override public void addViewToModelListener(ViewToModelListener listener) { getDelegate().addViewToModelListener(listener); } @Override public void removeViewToModelListener(ViewToModelListener listener) { getDelegate().removeViewToModelListener(listener); } @Override public void setMandatory(boolean mandatory) { getDelegate().setMandatory(mandatory); } @Override public boolean isMandatory() { return getDelegate().isMandatory(); } @Override public BooleanProperty mandatoryProperty() { return getDelegate().mandatoryProperty(); } @Override public void setBindingPath(String bindingPath) { getDelegate().setBindingPath(bindingPath); } @Override public String getBindingPath() { return getDelegate().getBindingPath(); } @Override public void setComponentPath(String componentPath) { getDelegate().setComponentPath(componentPath); } @Override public String getComponentPath() { return getDelegate().getComponentPath(); } @Override public void setBinding(FxComponentBinding binding) { getDelegate().setBinding(binding); } @Override public FxComponentBinding getBinding() { return getDelegate().getBinding(); } @Override public void setChangeable(boolean changeable) { getDelegate().setChangeable(changeable); } @Override public boolean isChangeable() { return getDelegate().isChangeable(); } @Override public ReadOnlyBooleanProperty changeableProperty() { return getDelegate().changeableProperty(); } @Override public void setContainerChangeable(boolean containerChangeable) { getDelegate().setContainerChangeable(containerChangeable); } @Override public void setContainerChangableIgnored(boolean containerChangeableIgnored) { getDelegate().setContainerChangableIgnored(containerChangeableIgnored); } @Override public boolean isContainerChangeableIgnored() { return getDelegate().isContainerChangeableIgnored(); } @Override public void setViewModified(boolean viewModified) { getDelegate().setViewModified(viewModified); } @Override public boolean isViewModified() { return getDelegate().isViewModified(); } @Override public BooleanProperty viewModifiedProperty() { return getDelegate().viewModifiedProperty(); } @Override public void triggerViewModified() { getDelegate().triggerViewModified(); } @Override public void saveView() { getDelegate().saveView(); } @Override public Object getSavedViewObject() { return getDelegate().getSavedViewObject(); } @Override public Object getViewObject() { return getDelegate().getViewObject(); } @Override public void setViewObject(Object viewObject) { getDelegate().setViewObject(viewObject); } @Override public void setBindable(boolean bindable) { getDelegate().setBindable(bindable); } @Override public boolean isBindable() { return getDelegate().isBindable(); } @Override public void setHelpUrl(String helpUrl) { getDelegate().setHelpUrl(helpUrl); } @Override public String getHelpUrl() { return getDelegate().getHelpUrl(); } @Override public void showHelp() { getDelegate().showHelp(); } @Override public String toGenericString() { return getDelegate().toGenericString(); } @Override public void setError(String error) { getDelegate().setError(error); } @Override public String getError() { return getDelegate().getError(); } @Override public void setErrorTemporary(boolean errorTemporary) { getDelegate().setErrorTemporary(errorTemporary); } @Override public boolean isErrorTemporary() { return getDelegate().isErrorTemporary(); } @Override public void showErrorPopup() { getDelegate().showErrorPopup(); } @Override public void hideErrorPopup() { getDelegate().hideErrorPopup(); } @Override public void setInfo(String info) { getDelegate().setInfo(info); } @Override public String getInfo() { return getDelegate().getInfo(); } @Override public void showInfoPopup() { getDelegate().showInfoPopup(); } @Override public void hideInfoPopup() { getDelegate().hideInfoPopup(); } @Override public boolean isModelUpdated() { return getDelegate().isModelUpdated(); } @Override public void setTableCell(FxTableCell tableCell) { getDelegate().setTableCell(tableCell); } @Override public FxTableCell getTableCell() { return getDelegate().getTableCell(); } @Override public void setTreeTableCell(FxTreeTableCell treeTableCell) { getDelegate().setTreeTableCell(treeTableCell); } @Override public FxTreeTableCell getTreeTableCell() { return getDelegate().getTreeTableCell(); } ////GEN-END:component }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy