Skip to content

Commit

Permalink
Update SearchTextField and add RemovableListCell
Browse files Browse the repository at this point in the history
Removed the resetSelection and show methods in SearchTextFieldHistoryPopup and SearchTextFieldHistoryPopupSkin, and changed the scope of SearchTextField in SearchTextFieldApp. Added new RemovableListCell component with dedicated CSS file. Updated search-text-field.css for hover state.
  • Loading branch information
leewyatt committed May 9, 2024
1 parent e85ee57 commit c05eea3
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dlsc.gemsfx.demo;

import com.dlsc.gemsfx.RemovableListCell;
import com.dlsc.gemsfx.SearchTextField;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
Expand All @@ -20,10 +21,14 @@

public class SearchTextFieldApp extends Application {

private SearchTextField field1;

@Override
public void start(Stage primaryStage) throws Exception {

SearchTextField field1 = new SearchTextField();
field1 = new SearchTextField();
field1.setCellFactory(param -> new RemovableListCell<>((listView, item) -> field1.removeHistory(item)));

SearchTextField field2 = new SearchTextField(true);

Label label = new Label("Max History Size:");
Expand Down
106 changes: 106 additions & 0 deletions gemsfx/src/main/java/com/dlsc/gemsfx/RemovableListCell.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.dlsc.gemsfx;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.materialdesign.MaterialDesign;

import java.util.Objects;
import java.util.function.BiConsumer;

/**
* A list cell that displays a remove button on the right side. The remove button is only
* visible when the mouse hovers over the cell. When the remove button is clicked, the
* onRemove callback is invoked.
*
* @param <T> the type of the list cell item
*/
public class RemovableListCell<T> extends ListCell<T> {

private final HBox containerBox;
private final Label label;

public RemovableListCell() {
getStyleClass().add("removable-list-cell");

label = new Label();

StackPane removeBtn = new StackPane(new FontIcon(MaterialDesign.MDI_CLOSE));
removeBtn.getStyleClass().add("remove-button");
removeBtn.setOnMouseClicked(this::onRemoveAction);

containerBox = new HBox(label, new Spacer(), removeBtn);
containerBox.getStyleClass().add("container-box");
containerBox.setAlignment(Pos.CENTER_LEFT);
}

public RemovableListCell(BiConsumer<ListView<T>, T> onRemove) {
this();
setOnRemove(onRemove);
}

@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);

if (item == null || empty) {
label.setText(null);

setText(null);
setGraphic(null);
} else {
label.setText(item.toString());

setText(null);
setGraphic(containerBox);
}
}

public void onRemoveAction(MouseEvent event) {
if (getOnRemove() != null) {

// clear selection if the item is selected
if (isSelected()) {
getListView().getSelectionModel().clearSelection();
}

getOnRemove().accept(getListView(), getItem());
}
}

private ObjectProperty<BiConsumer<ListView<T>, T>> onRemove;

/**
* A callback that is invoked when the remove button is clicked.
*
* @return the onRemoveProperty
*/
public final ObjectProperty<BiConsumer<ListView<T>, T>> onRemoveProperty() {
if (onRemove == null) {
onRemove = new SimpleObjectProperty<>(this, "onRemove");
}
return onRemove;
}

public final BiConsumer<ListView<T>, T> getOnRemove() {
return onRemove == null ? null : onRemoveProperty().get();
}

public final void setOnRemove(BiConsumer<ListView<T>, T> onRemove) {
onRemoveProperty().set(onRemove);
}

@Override
public String getUserAgentStylesheet() {
return Objects.requireNonNull(RemovableListCell.class.getResource("removable-list-cell.css")).toExternalForm();
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.dlsc.gemsfx.CustomPopupControl;
import com.dlsc.gemsfx.SearchTextField;
import javafx.scene.Node;
import javafx.scene.control.Skin;

import java.util.Objects;
Expand All @@ -25,14 +24,6 @@ public SearchTextFieldHistoryPopup(SearchTextField searchTextField) {
setHideOnEscape(true);
}

@Override
public void show(Node node) {
if (getSkin() instanceof SearchTextFieldHistoryPopupSkin skin) {
skin.resetSelection();
}
super.show(node);
}

protected Skin<?> createDefaultSkin() {
return new SearchTextFieldHistoryPopupSkin(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,6 @@ private void selectHistoryItem() {
}
}

/**
* Resets the selection of the ListView by focusing on it and selecting the first item, scrolling to the top if necessary.
*/
public void resetSelection() {
listView.requestFocus();

if (!listView.getItems().isEmpty()) {
listView.getSelectionModel().select(0);
listView.scrollTo(0);
listView.getFocusModel().focus(0);
}

}

public Node getNode() {
return listView;
}
Expand Down
36 changes: 36 additions & 0 deletions gemsfx/src/main/resources/com/dlsc/gemsfx/removable-list-cell.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.removable-list-cell .container-box {
-fx-padding: 2px 3px 2px 5px;
}

.removable-list-cell .remove-button {
visibility: hidden;
-fx-padding: 2px;
-fx-cursor: hand;
}

.removable-list-cell:hover {
-fx-background-color: #c9c9c9;
}

.removable-list-cell:hover .remove-button {
visibility: visible;
}

.removable-list-cell:empty {
-fx-background-color: transparent;
}

.removable-list-cell .remove-button .ikonli-font-icon {
-fx-icon-size: 1em;
}

.removable-list-cell:hover .remove-button .ikonli-font-icon,
.removable-list-cell:selected .remove-button .ikonli-font-icon,
.removable-list-cell .remove-button:pressed .ikonli-font-icon {
-fx-icon-color: -fx-text-background-color;
}

.removable-list-cell .remove-button:hover .ikonli-font-icon {
-fx-scale-x: 1.2;
-fx-scale-y: 1.2;
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@

.search-history-list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:hover {
-fx-background: -fx-accent;
-fx-background-color: -fx-selection-bar;
-fx-background-color: #c9c9c9;
}

.search-history-list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected,
Expand Down

0 comments on commit c05eea3

Please sign in to comment.