impl.org.controlsfx.skin.AutoCompletePopup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of controlsfx Show documentation
Show all versions of controlsfx Show documentation
High quality UI controls and other tools to complement the core JavaFX distribution
/**
* Copyright (c) 2014, 2020, ControlsFX
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of ControlsFX, any associated website, nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package impl.org.controlsfx.skin;
import java.util.UUID;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.control.PopupControl;
import javafx.scene.control.Skin;
import javafx.stage.Window;
import javafx.util.StringConverter;
/**
* The auto-complete-popup provides an list of available suggestions in order
* to complete current user input.
*/
public class AutoCompletePopup extends PopupControl{
/***************************************************************************
* *
* Private fields *
* *
**************************************************************************/
private final ObservableList suggestions = FXCollections.observableArrayList();
private StringConverter converter;
/**
* The maximum number of rows to be visible in the popup when it is
* showing. By default this value is 10, but this can be changed to increase
* or decrease the height of the popup.
*/
private IntegerProperty visibleRowCount = new SimpleIntegerProperty(this, "visibleRowCount", 10);
/***************************************************************************
* *
* Inner classes *
* *
**************************************************************************/
/**
* Represents an Event which is fired when the user has selected a suggestion
* for auto-complete
*
* @param
*/
@SuppressWarnings("serial")
public static class SuggestionEvent extends Event {
public static final EventType> SUGGESTION
= new EventType<>("SUGGESTION" + UUID.randomUUID().toString()); //$NON-NLS-1$
private final TE suggestion;
public SuggestionEvent(TE suggestion) {
super(SUGGESTION);
this.suggestion = suggestion;
}
/**
* Returns the suggestion which was chosen by the user
* @return
*/
public TE getSuggestion() {
return suggestion;
}
}
/***************************************************************************
* *
* Constructors *
* *
**************************************************************************/
/**
* Creates a new AutoCompletePopup
*/
public AutoCompletePopup(){
this.setAutoFix(true);
this.setAutoHide(true);
this.setHideOnEscape(true);
getStyleClass().add(DEFAULT_STYLE_CLASS);
}
/***************************************************************************
* *
* Public API *
* *
**************************************************************************/
/**
* Get the suggestions presented by this AutoCompletePopup
* @return
*/
public ObservableList getSuggestions() {
return suggestions;
}
/**
* Show this popup right below the given Node
* @param node
*/
public void show(Node node){
if(node.getScene() == null || node.getScene().getWindow() == null)
throw new IllegalStateException("Can not show popup. The node must be attached to a scene/window."); //$NON-NLS-1$
if(isShowing()){
return;
}
Window parent = node.getScene().getWindow();
getScene().setNodeOrientation(node.getEffectiveNodeOrientation());
if (node.getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT) {
setAnchorLocation(AnchorLocation.CONTENT_TOP_RIGHT);
} else {
setAnchorLocation(AnchorLocation.CONTENT_TOP_LEFT);
}
this.show(
parent,
parent.getX() + node.localToScene(0, 0).getX() +
node.getScene().getX(),
parent.getY() + node.localToScene(0, 0).getY() +
node.getScene().getY() + node.getBoundsInParent().getHeight());
}
/**
* Set the string converter used to turn a generic suggestion into a string
*/
public void setConverter(StringConverter converter) {
this.converter = converter;
}
/**
* Get the string converter used to turn a generic suggestion into a string
*/
public StringConverter getConverter() {
return converter;
}
public final void setVisibleRowCount(int value) {
visibleRowCount.set(value);
}
public final int getVisibleRowCount() {
return visibleRowCount.get();
}
public final IntegerProperty visibleRowCountProperty() {
return visibleRowCount;
}
/***************************************************************************
* *
* Properties *
* *
**************************************************************************/
public final ObjectProperty>> onSuggestionProperty() { return onSuggestion; }
public final void setOnSuggestion(EventHandler> value) { onSuggestionProperty().set(value); }
public final EventHandler> getOnSuggestion() { return onSuggestionProperty().get(); }
private ObjectProperty>> onSuggestion = new ObjectPropertyBase>>() {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override protected void invalidated() {
setEventHandler(SuggestionEvent.SUGGESTION, (EventHandler)(Object)get());
}
@Override
public Object getBean() {
return AutoCompletePopup.this;
}
@Override
public String getName() {
return "onSuggestion"; //$NON-NLS-1$
}
};
/***************************************************************************
* *
* Stylesheet Handling *
* *
**************************************************************************/
public static final String DEFAULT_STYLE_CLASS = "auto-complete-popup"; //$NON-NLS-1$
@Override
protected Skin createDefaultSkin() {
return new AutoCompletePopupSkin<>(this);
}
}