Package org.ugate.gui.components

Source Code of org.ugate.gui.components.TextFieldMenu

package org.ugate.gui.components;

import java.util.ArrayList;
import java.util.List;

import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Cursor;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.RadioMenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;

import org.ugate.gui.GuiUtil;

import com.sun.javafx.collections.NonIterableChange;

/**
* Text field with a label and context menu
*/
public class TextFieldMenu extends VBox {
 
  public static final double MENU_BUTTON_WIDTH = 12d;
  public static final double MENU_BUTTON_HEIGHT = 8d;
  private final ToggleGroup toggleGroup = new ToggleGroup();
  private final ContextMenu menu = new ContextMenu();
  private final Label label;
  private final TextField textField = new TextField();
  private final Region menuNewItemButton = new Region();
  private final Region menuRemoveItemButton = new Region();
  private final Region menuButton = new Region();
  private final ReadOnlyStringWrapper selectionWrapper = new ReadOnlyStringWrapper();
 
  /**
   * Constructor
   *
   * @param labelText the label for the text field
   * @param promptText the prompt text
   */
  public TextFieldMenu(final String labelText, final String promptText) {
    super(5d);
    if (labelText != null && !labelText.isEmpty()) {
      label = new Label(labelText);
      getChildren().add(label);
    } else {
      label = null;
    }
    textField.setPromptText(promptText);
    addMenuItems();
  }
 
  /**
   * Adds the menu item controls
   */
  protected void addMenuItems() {
//    setStyle("-fx-background-color: gray;");
//    menu.setId("choice-box-popup-menu");
    menu.getItems().addListener(new ListChangeListener<MenuItem>() {
      @Override
      public void onChanged(final Change<? extends MenuItem> c) {
        if (!(c instanceof NonIterableChange) && c.getRemovedSize() > 0 && textField.getText() != null &&
            !textField.getText().isEmpty()) {
          for (final MenuItem mi : c.getRemoved()) {
            if (mi.getText() != null && mi.getText().equals(textField.getText())) {
              setSelectionText(null);
            }
          }
        }
      }
    });
    //textField.getStyleClass().setAll("text-field-fx");
    textField.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
      @Override
      public void handle(final MouseEvent event) {
        if (GuiUtil.isPrimaryPress(event)) {
          toggleMenu();
        }
      }
    });
    menuButton.getStyleClass().setAll(new String[] { "menu-down-arrow" });
    menuButton.setMaxSize(MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT);
    menuButton.setCursor(Cursor.HAND);
    menuButton.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
      @Override
      public void handle(final MouseEvent event) {
        if (GuiUtil.isPrimaryPress(event)) {
          toggleMenu();
        }
      }
    });
    // new entry has been confirmed by clicking on the new choice button
    menuNewItemButton.getStyleClass().setAll(new String[] { "text-field-menu-add-choice" });
    menuNewItemButton.setMaxSize(MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT / 2d);
    menuNewItemButton.setCursor(Cursor.HAND);
    menuNewItemButton.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
      @Override
      public void handle(final MouseEvent event) {
        if (GuiUtil.isPrimaryPress(event)) {
          addMenuItems(textField.getText());
          select(textField.getText());
        }
      }
    });
    // remove selected item
    menuRemoveItemButton.getStyleClass().setAll(new String[] { "text-field-menu-remove-choice" });
    menuRemoveItemButton.setMaxSize(MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT / 2d);
    menuRemoveItemButton.setCursor(Cursor.HAND);
    menuRemoveItemButton.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
      @Override
      public void handle(final MouseEvent event) {
        if (GuiUtil.isPrimaryPress(event)) {
          selectOrRemove(textField.getText(), true);
        }
      }
    });
    final GridPane editMenu = new GridPane();
    editMenu.setAlignment(Pos.BOTTOM_RIGHT);
    editMenu.setPadding(new Insets(7d, 0, 0, 0));
    editMenu.setHgap(2d);
    editMenu.setVgap(5d);
    editMenu.add(menuNewItemButton, 0, 0);
    editMenu.add(menuRemoveItemButton, 0, 1);
    editMenu.setMaxSize(MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT);
    GridPane.setVgrow(menuNewItemButton, Priority.ALWAYS);
    GridPane.setVgrow(menuRemoveItemButton, Priority.NEVER);
    final StackPane textStack = new StackPane();
    textStack.setAlignment(Pos.BOTTOM_RIGHT);
    textStack.getChildren().addAll(textField, menuButton);
    final HBox textBox = new HBox(2d);
    textBox.getChildren().addAll(textStack, editMenu);
      getChildren().addAll(textBox);
  }
 
  /**
   * Toggles the menu
   */
  protected void toggleMenu() {
    if (menu.isShowing()) {
      menu.hide();
    } else {
      menu.show(textField, Side.BOTTOM, 0.0d, 0.0d);
    }
  }
 
  /**
   * Adds items to the menu
   *
   * @param selectFirstItem true to select the first ite
   * @param itemContents the menu item content(s)
   */
  public void addMenuItems(final Object... itemContents) {
    if (itemContents == null || itemContents.length == 0) {
      return;
    }
    final RadioMenuItem[] existingMenuItems = menu.getItems() != null ?
        menu.getItems().toArray(new RadioMenuItem[]{}) : new RadioMenuItem[]{};
    final List<MenuItem> its = new ArrayList<MenuItem>();
    boolean duplicate = false;
    for (final Object ic : itemContents) {
      duplicate = false;
      final RadioMenuItem mi = new RadioMenuItem(ic == null ? "" : ic.toString());
      for (final RadioMenuItem ei : existingMenuItems) {
        if (ei.getText().equals(mi.getText())) {
          duplicate = true;
          break;
        }
      }
      if (!duplicate) {
        mi.setId("choice-box-menu-item");
        mi.setToggleGroup(toggleGroup);
        mi.setOnAction(new EventHandler<ActionEvent>() {
          public void handle(final ActionEvent event) {
            setSelectionText(((MenuItem)event.getSource()).getText());
          }
        });
        its.add(mi);
      }
    }
    menu.getItems().addAll(its);
  }
 
  /**
   * Selects the menu item that matches the supplied content. Deselects all when null or no match
   * exists in the menu items.
   *
   * @param itemContent the item content to select from the menu items
   */
  public void select(final Object itemContent) {
    selectOrRemove(itemContent, false);
  }
 
  /**
   * Selects the menu item that matches the supplied content. Deselects all when null or no match
   * exists in the menu items.
   *
   * @param itemContent the item content to select from the menu items
   * @param remove true to remove false to select
   */
  protected void selectOrRemove(final Object itemContent, final boolean remove) {
    final RadioMenuItem[] existingMenuItems = menu.getItems() != null ?
        menu.getItems().toArray(new RadioMenuItem[]{}) : new RadioMenuItem[]{};
    String meuContent;
    RadioMenuItem removeItem = null;
    for (final RadioMenuItem ei : existingMenuItems) {
      meuContent = itemContent != null ? itemContent.toString() : null;
      if (meuContent != null && !meuContent.isEmpty() && meuContent.equals(ei.getText())) {
        if (remove) {
          removeItem = ei;
        } else {
          ei.setSelected(true);
          setSelectionText(ei.getText());
        }
      } else {
        ei.setSelected(false);
      }
    }
    if (removeItem != null) {
      menu.getItems().remove(removeItem);
      if (itemContent.equals(removeItem.getText())) {
        setSelectionText(null);
      }
    }
  }
 
  /**
   * Sets the selection text on the text input
   *
   * @param selectionText the selection text
   */
  protected void setSelectionText(final String selectionText) {
    // no binding because updates will occur when typing
    textField.setText(selectionText);
    selectionWrapper.set(selectionText);
  }
 
  /**
   * @return the selection property
   */
  public ReadOnlyStringProperty selectionProperty() {
    return selectionWrapper.getReadOnlyProperty();
  }
}
TOP

Related Classes of org.ugate.gui.components.TextFieldMenu

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.