当前位置: 首页 > 知识库问答 >
问题:

带历史记录功能的JavaFX可编辑组合框

益富
2023-03-14

我正在尝试制作一个JavaFXComboBox,它能记住用户输入的条目的历史记录。添加新条目可以,但从下拉菜单中选择则不行。

简而言之,我正在努力让控制权

  1. 将最近键入的条目添加到顶部,作为组合框的第一项
  2. 清除下一个条目的文本字段部分
  3. 组合框中选择项目后,将把所选内容复制到文本字段,而不修改组合框的项目

添加新项目工作正常,这是复制以前的条目到字段被证明是令人沮丧的。

我能找到的唯一类似问题是javafx combobox项目列表问题,不幸的是,它的解决方案并没有解决我的问题。

密码

import java.util.LinkedList;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;


public class HistoryField<String> extends ComboBox<String> {
    public final static int DEFAULT_MAX_ENTRIES = 256;

    //Data members
    private int maxSize;
    private final ObservableList<String> history;

   //Default constructor
    public HistoryField() {
        this(DEFAULT_MAX_ENTRIES, (String[]) null);
    }

    public HistoryField(int maxSize, String ... entries) {
        super(FXCollections.observableList(new LinkedList<>()));
        this.setEditable(true);

        this.maxSize = maxSize;
        this.history = this.getItems();


        //Populate list with entries (if any)
        if (entries != null) {
            for (int i = 0; ((i < entries.length) && (i < this.maxSize)); i++) {
                this.history.add(entries[i]);
            }
         }

        this.valueProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
            if ((oldValue == null) && (newValue != null)) {                
                if (this.getSelectionModel().getSelectedIndex() < 0) {
                    this.getItems().add(0, newValue);
                    this.getSelectionModel().clearSelection();
                }
            } else {

                //This throws IndexOutOfBoundsException
                this.getSelectionModel().clearSelection();
            }
        });
    }
}

考试班

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class HistoryFieldTest extends Application {
    private HistoryField<String> historyField;

    @Override
    public void start(Stage primaryStage) {        
        this.historyField = new HistoryField<>();

        BorderPane root = new BorderPane();
        root.setBottom(historyField);

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setTitle("History Field Test");
        primaryStage.setScene(scene);

        primaryStage.show();
    }

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

谢谢你!

共有1个答案

刘建中
2023-03-14

尝试以下更新的HistoryField类。我做了一些改变。

首先,不要传递字符串的varargs,只需传递所需的数组即可。然后,您可以使用数组将数组转换为列表,为组合框做好准备。asList()方法。

此外,我简化了向列表中添加新项目的过程。侦听器现在只会在列表中添加一个尚不存在的项。

您也从未处理过max_size情况,所以我添加了一个简单的检查,以便在到达max_size后删除旧条目。

只有将项目添加到列表中时,才会清除该字段;你的问题不清楚这是否是你想要的行为。

public class HistoryField extends ComboBox<String> {

    private final static int DEFAULT_MAX_ENTRIES = 5;

    //Data members
    private int maxSize;
    private final ObservableList<String> history;

    //Default constructor
    public HistoryField() {
        this(DEFAULT_MAX_ENTRIES, null);
    }

    /* Changed parameter to an array instead of list of Strings */
    public HistoryField(int maxSize, String[] entries) {
        this.setEditable(true);

        this.maxSize = maxSize;

        /* Convert the passed array to a list and populate the dropdown */
        if (entries != null) {
            history = FXCollections.observableArrayList(Arrays.asList(entries));
        } else {
            history = FXCollections.observableArrayList();
        }

        setItems(history);

        this.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {

                // Check if value already exists in list
                if (!this.history.contains(newValue)) {
                    this.history.add(0, newValue);

                    // If the max_size has been reached, remove the oldest item from the list
                    if (this.history.size() > maxSize) {
                        this.history.remove(history.size() - 1);
                    }

                    System.out.println(history);

                    // Clear the selection when new item is added
                    this.getSelectionModel().clearSelection();
                }
            }
        });
    }
}
 类似资料:
  • 我正在尝试使用一个可编辑的组合框。因为我想添加一个用于按回车键的监听器。我尝试了下面的选项,但都不起作用。:( < code>cmb_year是组合框对象。

  • 读取播放历史信息 调用地址 http://api.bilibili.cn/history 返回 返回值字段 字段类型 字段说明 results int 返回的记录总数目 list object 返回数据 返回字段 “list” 子项 返回值字段 字段类型 字段说明 aid int 视频编号 typeid int 视频分类ID typename string 视频分类名称 title string

  • 历史记录 控制台维护 Elasticsearch 成功执行的最后500个请求列表。点击窗口右上角的时钟图标即可查看历史记录。这个图标会打开历史记录面板,您可以在其中查看历史请求。您也可以在这里选择一个请求,它将被添加到编辑器中当前光标所在的位置。 图 9. 历史记录面板

  • 3.3.1.1. 同步的文件历史记录 微力同步记录对文件的添加,修改、删除的操作记录,通过历史记录列表可查看时间时间及发生设备,如下: 事件时间,显示添加、修改、删除等操作发生的时间; 文件时间,显示该文件的最后修改时间; 操作类型,显示此次针对该文件所进行的操作的类型; 发生设备,显示进行此操作的设备名称; 目录,显示该文件所属同步目录; 清空历史记录,点击后可清除所有记录,此操作仅清除记录而已

  • 13. 交互式输入的编辑和历史记录 某些版本的 Python 解释器支持编辑当前的输入行和历史记录,类似于在 Korn shell 和 GNU Bash shell 中看到的功能。这是使用GNU Readline库实现的,它支持 Emacs 风格和 vi 风格的编辑。这个库有它自己的文档,在这里我不就重复了;然而,基本原理很容易解释。本章讲述的交互式编辑和历史记录功能在 Unix 版本和 Cygw

  • 入口: 在路线规划右上角,有历史记录入口,无论“单路线规划”、“多路线规划”的结果,都会自动进行记录,点击进入该界面 在“路线规划”模块下展开二级模块“历史记录”,可以点击进入 历史记录列表 支持按照时间搜索记录 支持单个删除记录 支持一键删除全部记录 支持点击查看规划历史详情 历史详情 记录规划人、规划时间、规划结果 结果详情界面回放、支持点击查看