Commit ec458224 authored by George Adrian Stoica's avatar George Adrian Stoica

tagsbar

added the tagsbar implementation from
https://github.com/goxr3plus/JavaFX-TagsBar
parent 2a9ca324
package simpleex.ui.tags;
import java.util.SortedSet;
import java.util.TreeSet;
import javafx.geometry.Side;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.IndexRange;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
/**
* @author GOXR3PLUS
* https://github.com/goxr3plus/JavaFX-TagsBar
*/
public class AutoCompleteTextField extends TextField {
/** The existing auto complete entries. */
private final SortedSet<String> entries = new TreeSet<>();
/** The pop up used to select an entry. */
private ContextMenu contextMenu = new ContextMenu();
private int maximumEntries = 15;
private StringBuilder sb = new StringBuilder();
private int lastLength;
// Constructor
public AutoCompleteTextField() {
// TextChanged Listener
textProperty().addListener(l -> {
if (getText().length() == 0)
contextMenu.hide();
else {
if (entries.size() > 0) {
populatePopup();
if (!contextMenu.isShowing()) {
contextMenu.show(AutoCompleteTextField.this, Side.BOTTOM, 0, 0);
// Request focus on first item
if (!contextMenu.getItems().isEmpty())
contextMenu.getSkin().getNode().lookup(".menu-item:nth-child(1)").requestFocus();
}
} else
contextMenu.hide();
}
});
// FocusListener
focusedProperty().addListener(l -> {
lastLength = 0;
sb.delete(0, sb.length());
contextMenu.hide();
});
}
/**
* Get the existing set of autocomplete entries.
*
* @return The existing autocomplete entries.
*/
public SortedSet<String> getEntries() {
return entries;
}
// TODO ---------------This method not works perfect needs to be redone....
public void buggedMethod() {
// KeyReleased Listener
setOnKeyReleased(key -> {
KeyCode k = key.getCode();
// this variable is used to bypass the auto complete process if the
// length is the same. this occurs if user types fast, the length of
// textfield will record after the user has typed after a certain
// delay.
if (lastLength != (getLength() - getSelectedText().length()))
lastLength = getLength() - getSelectedText().length();
// Not causing problems by these buttons
if (key.isControlDown() || k == KeyCode.BACK_SPACE || k == KeyCode.RIGHT || k == KeyCode.LEFT
|| k == KeyCode.DELETE || k == KeyCode.HOME || k == KeyCode.END || k == KeyCode.TAB)
return;
IndexRange ir = getSelection();
sb.delete(0, sb.length());
sb.append(getText());
// remove selected string index until end so only unselected text
// will be recorded
try {
sb.delete(ir.getStart(), sb.length());
} catch (Exception e) {
e.printStackTrace();
}
String originalLowered = getText().toLowerCase();
// Select the first Matching
for (String s : entries)
if (s.toLowerCase().startsWith(originalLowered)) {
try {
setText(s);
} catch (Exception e) {
setText(sb.toString());
}
positionCaret(sb.toString().length());
selectEnd();
break;
}
});
}
/**
* Populate the entry set with the given search results.
*
* @param sortedSet
* The set of matching strings.
*/
private void populatePopup() {
contextMenu.getItems().clear();
String text = getText().toLowerCase();
// Filter the first maximumEntries matching the text
entries.stream().filter(string -> {
return string.toLowerCase().startsWith(text);
}).limit(maximumEntries).forEach(s -> {
// Add the element
MenuItem item = new MenuItem(s);
item.setOnAction(a -> {
setText(s);
positionCaret(getLength());
});
contextMenu.getItems().add(item);
});
// Entries to be shown
// for (int i = 0; i < count; i++) {
// final String result = searchResult.get(i);
// Label entryLabel = new Label(result);
// CustomMenuItem item = new CustomMenuItem(entryLabel, true);
// item.setOnAction(a->{
// setText(result);
// contextMenu.hide();
// });
// menuItems.add(item);
// }
}
}
\ No newline at end of file
This diff is collapsed.
# JavaFX-TagsBar
Until now javaFX hadn't a TagsBar so here is a simple implementation.
## IMAGE(using css)
![Demostration](http://i.stack.imgur.com/qL6FD.png)
### Code source is https://github.com/goxr3plus/JavaFX-TagsBar
\ No newline at end of file
package simpleex.ui.tags;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
* @author GOXR3PLUS
* https://github.com/goxr3plus/JavaFX-TagsBar
*/
public class Snippet extends Application {
@Override
public void start(Stage primaryStage) {
// All the musicGenres
List<String> genres = Arrays.asList("50s", "60s", "70s", "80s", "90s", "Adult Contemporary", "African",
"Alternative", "Ambient", "Americana", "Baladas", "Bass", "Big Band", "Big Beat", "Bluegrass", "Blues ",
"Bollywood", "Breakbeat", "Breakcore", "Breaks", "Calypso", "Caribbean", "Celtic", "Chill", "Zouk");
TagsBar tagBar = new TagsBar();
tagBar.getEntries().addAll(genres);
// Root
VBox root = new VBox();
root.getChildren().addAll(tagBar);
root.setMinSize(300, 400);
// Scene
Scene scene = new Scene(root, 500, 500);
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
// PrimaryStage
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
package simpleex.ui.tags;
import java.util.SortedSet;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
/**
* @author GOXR3PLUS
* https://github.com/goxr3plus/JavaFX-TagsBar
*/
public class TagsBar extends HBox {
private HBox hBox = new HBox();
private ScrollPane scrollPane = new ScrollPane(hBox);
private AutoCompleteTextField field = new AutoCompleteTextField();
// Constructor
public TagsBar() {
getStyleClass().setAll("tags-bar");
// hBox
hBox.setStyle(" -fx-spacing:3px;");
// scrollPane
scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
// field
field.setPromptText("tag...");
field.setMinSize(120, 30);
field.setBackground(null);
field.setOnAction(evt -> {
String text = field.getText();
// No Duplicates allowed
if (!text.isEmpty() && getEntries().contains(text) && !hBox.getChildren().stream()
.anyMatch(s -> ((Tag) s).getTag().toLowerCase().equals(text.toLowerCase())))
hBox.getChildren().add(new Tag(text));
field.clear();
});
getChildren().addAll(scrollPane, field);
}
/**
* Returns all the tags of TagsBar
*
* @return
*/
public ObservableList<Node> getTags() {
return hBox.getChildren();
}
/**
* Get the existing set of auto complete entries.
*
* @return The existing auto complete entries.
*/
public SortedSet<String> getEntries() {
return field.getEntries();
}
/**
* Clears all the tags
*
*/
public void clearAllTags() {
hBox.getChildren().clear();
}
/**
* Add this tag if it doesn't exist
*
* @param tag
*/
public void addTag(String tag) {
if (!hBox.getChildren().stream().anyMatch(s -> ((Tag) s).getTag().toLowerCase().equals(tag.toLowerCase())))
hBox.getChildren().add(new Tag(tag));
}
/**
* @author SuperGoliath TagClass
*/
public class Tag extends HBox {
private Label textLabel = new Label();
private Label iconLabel = new Label(null, new ImageView(new Image(getClass().getResourceAsStream("x.png"))));
// Constructor
public Tag(String tag) {
getStyleClass().add("tag");
// drag detected
setOnDragDetected(event -> {
/* allow copy transfer mode */
Dragboard db = startDragAndDrop(TransferMode.MOVE);
/* put a string on dragboard */
ClipboardContent content = new ClipboardContent();
content.putString("#c" + getTag());
db.setDragView(snapshot(null, new WritableImage((int) getWidth(), (int) getHeight())), getWidth() / 2,
0);
db.setContent(content);
event.consume();
});
// drag over
setOnDragOver((event) -> {
/*
* data is dragged over the target accept it only if it is not
* dragged from the same imageView and if it has a string data
*/
if (event.getGestureSource() != this && event.getDragboard().hasString())
event.acceptTransferModes(TransferMode.MOVE);
event.consume();
});
// drag dropped
setOnDragDropped(event -> {
boolean sucess = false;
if (event.getDragboard().hasString() && event.getDragboard().getString().startsWith("#c")) {
String currentTag = getTag();
setTag(event.getDragboard().getString().replace("#c", ""));
((Tag) event.getGestureSource()).setTag(currentTag);
sucess = true;
}
event.setDropCompleted(sucess);
event.consume();
});
// drag done
setOnDragDone(event -> {
if (event.getTransferMode() == TransferMode.MOVE) {
// System.out.println("Source"+event.getGestureSource() + "
// /Target:" + event.getGestureTarget());
}
event.consume();
});
// textLabel
textLabel.getStyleClass().add("label");
textLabel.setText(tag);
// textLabel.setMinWidth(getTag().length() * 6);
// iconLabel
iconLabel.setOnMouseReleased(r -> {
hBox.getChildren().remove(this);
});
getChildren().addAll(textLabel, iconLabel);
}
public String getTag() {
return textLabel.getText();
}
public void setTag(String text) {
textLabel.setText(text);
}
}
}
\ No newline at end of file
/*******************************************************************************
* ToolTips!!! *
******************************************************************************/
.tooltip{
-fx-background-color: yellow;
-fx-text-fill:black;
-fx-font-size:12.0;
-fx-effect: dropshadow( three-pass-box, black, 10.0, 0.0, 0.0, 0.0);
}
/*******************************************************************************
* CSS Styles for the Layouts.. *
******************************************************************************/
.scroll-pane .viewport {
-fx-background-color: transparent;
}
.scroll-pane {
-fx-background-color:transparent;
}
.scroll-bar{
-fx-background-color: transparent;
/*-fx-background-radius:2.0em;*/
}
.scroll-bar:horizontal .increment-arrow {
-fx-background-color: black;
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
-fx-padding: 0.3em;
-fx-rotate: -90.0;
}
.scroll-bar:horizontal .decrement-arrow {
-fx-background-color: black;
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
-fx-padding: 0.3em;
-fx-rotate: 90.0;
}
.scroll-bar:vertical .increment-arrow {
-fx-background-color: rgb(211.0,211.0,211.0);
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
-fx-padding: 0.3em;
-fx-rotate: 0.0;
}
.scroll-bar:vertical .decrement-arrow {
-fx-background-color: rgb(211.0,211.0,211.0);
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
-fx-padding: 0.3em;
-fx-rotate: -180.0;
}
.scroll-bar:vertical .increment-button,
.scroll-bar:vertical .decrement-button {
-fx-background-color:transparent;
}
.scroll-bar:horizontal .increment-button,
.scroll-bar:horizontal .decrement-button {
-fx-background-color:transparent;
}
/*******************************************************************************
* CSS Styles for the TextField and Search-Box.... *
******************************************************************************/
.text-field {
-fx-background-color: black;
-fx-background-insets:3.0;
-fx-background-radius: 5.0;
-fx-text-fill:white;
-fx-font-size:15.0;
}
.text-field:focused{
-fx-background-color: orange, black;
-fx-background-insets: -0.1, 2.0;
}
/*******************************************************************************
* CSS Styles for the TextArea *
******************************************************************************/
/*******************************************************************************
* CSS Styles for the TagsBar *
******************************************************************************/
.tags-bar {
-fx-background-color:white;
-fx-background-radius:15.0px;
-fx-min-height: 45.0;
-fx-alignment:center-right;
-fx-spacing: 3.0px;
-fx-padding: 3.0px;
}
.tags-bar .tag {
-fx-background-color:black;
-fx-background-radius:10.0px;
-fx-alignment: center;
-fx-padding:1.0px;
-fx-cursor:hand;
}
.tags-bar .tag .label{
-fx-text-fill:white;
-fx-font-size:14.0px;
}
.text-field,.text-area {
-fx-prompt-text-fill:white;
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment