在JavaFX中实现标签栏

GOX*_*LUS 15 java tags javafx

答案的示范:( 5月29日凌晨3点10分回答)

**10/7/2016** you can find the code on GitHub上

示例标签图像

回答前的实际问题:( 5月22日19:53问)

标题可能不是太大,但我想要做的是在JavaFX中这样的事情:

例子

YouTube:

YouTube代码示例

StackOverFlow(具有和自动完成):

StackOverflow标签示例

问题: 我不需要为此编写代码.相反,我想知道如何使用JavaFX和一些想法实现这一目标.

fab*_*ian 13

对于标签,您可以使用HBox包含Text(标签名称)节点和Button(删除按钮(X))的自定义样式.通过使用背景和边框,您可以获得所需的标签外观.

onAction按钮的处理程序应从其父级中删除标记...

对于整个标签栏,您可以使用另一个HBox.使用适当的边框以获得正确的外观.除了标签添加一个TextField没有背景的最后一个元素,并设置Hgrow的那个属性TextField,以Priotity.ALWAYS覆盖可用空间的其余部分.

这个onAction处理程序TextField添加了新标签并清除了内容TextField.

您可以使用ControlsFX的自动完成功能,TextField或者自己实现自定义外观...

public class TagBar extends HBox {

    private final ObservableList<String> tags;
    private final TextField inputTextField;

    public ObservableList<String> getTags() {
        return tags;
    }

    public TagBar() {
        getStyleClass().setAll("tag-bar");
        getStylesheets().add(getClass().getResource("style.css").toExternalForm());
        tags = FXCollections.observableArrayList();
        inputTextField = new TextField();
        inputTextField.setOnAction(evt -> {
            String text = inputTextField.getText();
            if (!text.isEmpty() && !tags.contains(text)) {
                tags.add(text);
                inputTextField.clear();
            }
        });

        inputTextField.prefHeightProperty().bind(this.heightProperty());
        HBox.setHgrow(inputTextField, Priority.ALWAYS);
        inputTextField.setBackground(null);

        tags.addListener((ListChangeListener.Change<? extends String> change) -> {
            while (change.next()) {
                if (change.wasPermutated()) {
                    ArrayList<Node> newSublist = new ArrayList<>(change.getTo() - change.getFrom());
                    for (int i = change.getFrom(), end = change.getTo(); i < end; i++) {
                        newSublist.add(null);
                    }
                    for (int i = change.getFrom(), end = change.getTo(); i < end; i++) {
                        newSublist.set(change.getPermutation(i), getChildren().get(i));
                    }
                    getChildren().subList(change.getFrom(), change.getTo()).clear();
                    getChildren().addAll(change.getFrom(), newSublist);
                } else {
                    if (change.wasRemoved()) {
                        getChildren().subList(change.getFrom(), change.getFrom() + change.getRemovedSize()).clear();
                    }
                    if (change.wasAdded()) {
                        getChildren().addAll(change.getFrom(), change.getAddedSubList().stream().map(Tag::new).collect(Collectors.toList()));
                    }
                }
            }
        });
        getChildren().add(inputTextField);
    }

    private class Tag extends HBox {

        public Tag(String tag) {
            getStyleClass().setAll("tag");
            Button removeButton = new Button("X");
            removeButton.setOnAction((evt) -> tags.remove(tag));
            Text text = new Text(tag);
            HBox.setMargin(text, new Insets(0, 0, 0, 5));
            getChildren().addAll(text, removeButton);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

style.css文件

.tag-bar {
    -fx-border-color: blue;
    -fx-spacing: 3;
    -fx-padding: 3;
    -fx-max-height: 30;
}

.tag-bar .tag {
    -fx-background-color: lightblue;
    -fx-alignment: center;
}

.tag-bar .tag .button {
    -fx-background-color: transparent;
}
Run Code Online (Sandbox Code Playgroud)
@Override
public void start(Stage primaryStage) {
    Button btn = new Button("Sort");

    StackPane.setAlignment(btn, Pos.BOTTOM_CENTER);

    TagBar tagBar = new TagBar();

    btn.setOnAction((ActionEvent event) -> {
        FXCollections.sort(tagBar.getTags());
    });

    Button btn2 = new Button("add \"42\"");
    btn2.setOnAction(evt -> {
        if (!tagBar.getTags().contains("42")) {
            tagBar.getTags().add("42");
        }
    });

    VBox root = new VBox();
    root.getChildren().addAll(tagBar, btn, btn2);
    root.setPrefSize(300, 400);

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}
Run Code Online (Sandbox Code Playgroud)


GVA*_*Art 6

简单实现这段代码!

import ....

public class Main extends Application {

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

        BorderPane root = new BorderPane();
        HBox tagsPane = new HBox(10);
        tagsPane.setStyle("-fx-border-color: #F1F1F1;" +
                "          -fx-border-width: 1px;" +
                "          -fx-border-radius: 10;" +
                "          -fx-border-insets: 5");
        root.setBottom(tagsPane);

        TextField textField = new TextField();
        textField.setPromptText("Tag name - ENTER to add");
        textField.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                tagButton(tagsPane, textField.getText());
                textField.clear();
            }
        });

        root.setTop(textField);

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 450, 275));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }

    //little image as 15x15 for example
    Image toUse = new Image("sample/delete.png");

    //box is the pane where this buttons will be placed
    public void tagButton(HBox box,String tag){
        ImageView closeImg = new ImageView(toUse);
        Button result = new Button(tag,closeImg);
        result.setPrefHeight(20);
        result.setContentDisplay(ContentDisplay.RIGHT);

        result.setOnAction(event -> box.getChildren().remove(result));
        box.getChildren().add(result);
}
Run Code Online (Sandbox Code Playgroud)

}

在此输入图像描述

此外,如果您需要不同的事件来点击标签并点击"X",您可以像这样实现tagButton:

public void tagButton(HBox box,String tag){
    ImageView closeImg = new ImageView(toUse);
    HBox button = new HBox();
    button.setStyle("-fx-padding:4;" +
            "        -fx-border-width: 2;" +
            "        -fx-border-color: black;" +
            "        -fx-border-radius: 4;" +
            "        -fx-background-color: f1f1f1;" +
            "        -fx-border-insets: 5;");
    button.setPrefHeight(20);
    button.getChildren().addAll(new Label(tag),closeImg);

    closeImg.setOnMouseClicked(event -> 
            box.getChildren().remove(button)
    );
    button.setOnMouseClicked(event -> {
        //doSomethig
    });

    box.getChildren().add(button);
}
Run Code Online (Sandbox Code Playgroud)