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

JavaFX update ObservableList with extractor,用于UI中的非JavaFX线程

古凌
2023-03-14
ObservableList<Person> secondList = FXCollections.observableArrayList();
secondList.addAll(originalList);
originalList.addListener((ListChangeListener<? super Person>)change-> {
    while(change.next()) {
        if (change.wasRemoved()) {
            Platform.runLater(() -> secondList.subList(change.getFrom(), change.getFrom() + change.getRemovedSize()).clear());
        }

        if (change.wasAdded()) {
            Platform.runLater(() -> secondList.addAll(change.getFrom(), change.getAddedSubList()));
        }
    }
});
ListView<Person> listViewPerson = new ListView<>(secondList);
ObservableList<Person> secondList = FXCollections.observableArrayList(person -> new Observable[]{person.adultProperty()});
public PersonUI(Person person) {
    adult = new SimpleBooleanProperty(person.isAdult());
    person.adultProperty().addListener((observableValue, oldValue, newValue) -> {
        Platform.runLater(() -> this.adult.set(newValue));
    });
}

还有其他的解决办法吗?如果我目前的解决方案有任何问题,请指出。

共有1个答案

秦承安
2023-03-14
/**
 * A 1:1 transform of the sourceList that guarantees to fire change notification
 * on the fx-thread.
 * 
 * @author Jeanette Winzenburg, Berlin
 */
public class FXThreadTransformationList<E> extends TransformationList<E, E> {

    public FXThreadTransformationList(ObservableList<E> source) {
        super(source);
    }

    @Override
    protected void sourceChanged(Change<? extends E> c) {
        beginChange();
        while (c.next()) {
            if (c.wasPermutated()) {
                // tbd
            } else if (c.wasUpdated()) {
                update(c);
            } else if (c.wasReplaced()) {
                // tbd
            } else {
                addedOrRemoved(c);
            }
        }
        // commit on fx-thread
        endChangeOnFXThread();
    }

    public void endChangeOnFXThread() {
        Platform.runLater(() -> endChange());
    }

    private void addedOrRemoved(Change<? extends E> c) {
        if (c.wasRemoved()) {
            nextRemove(c.getFrom(), c.getRemoved());
        } else if (c.wasAdded()) {
            nextAdd(c.getFrom(), c.getTo());  
        } else {
            throw new IllegalStateException("expected either removed or added, but was:" + c);
        }
    }

    private void update(Change<? extends E> c) {
        for (int pos = c.getFrom(); pos < c.getTo(); pos++) {
            nextUpdate(pos);
        }
    }

    @Override
    public int getViewIndex(int index) {
        return index;
    }

    @Override
    public int getSourceIndex(int index) {
        return index;
    }

    @Override
    public E get(int index) {
        return getSource().get(index);
    }

    @Override
    public int size() {
        return getSource().size();
    }

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(FXThreadTransformationList.class.getName());
}
 类似资料:
  • 我有两个交织在一起的多线程问题。 我在使用spring boot的JavaFX桌面应用程序中有一个SplitPane。左边是树视图,右边是选项卡窗格。开始时,SplitPane设备位于右侧边缘,隐藏了TabPane。当用户在树中选择一个项目时,两件事将同时发生: 首先,根据选择,创建10个选项卡。选项卡因所选对象而异。每个选项卡都显示与选定对象相关的详细数据。大多数选项卡包含图表,但也包含文本。

  • 问题内容: 我有一个简单的JavaFX 2应用程序,带有2个按钮,分别是“开始”和“停止”。单击开始按钮后,我想创建一个后台线程,该线程将进行一些处理并随着时间的推移更新UI(例如进度条)。如果单击停止按钮,我希望线程终止。 我尝试使用从文档中收集的类来完成此操作。但是,每当我单击“开始”时,UI就会冻结/挂起,而不是保持正常。 她是来自主类的用于显示按钮的代码: 这是类的代码: 相当简单,但是每

  • 问题内容: 有没有办法在非UI线程中进行UI更改?简短的问题。 问题答案: 如果您不想使用AsyncTask,请在您的主要活动中尝试使用带有内部类(ResponseHandler)的观察者模式,对不起,我无法正确设置格式,但是我确定您知道

  • 在JavaFX(实际上是ScalaFX)应用程序中,我希望允许用户通过一系列键盘键调用命令。不管当前的键盘布局(语言)如何,这些命令都应该工作。例如,用户可能正在用泰文()键入,然后想通过按'escape'和's'(或':'和'w',vim样式)保存。 我怎样才能克服这个问题?我怎样才能知道是哪一个键被按下而不管语言? 类似的未回答问题:JavaFX KeyEvent和重音字符

  • 可能重复: Android:线程中的吐司 我从一个工作线程中调用一个帮助器类函数,其中我试图引发一个toast,但是我得到了下面的异常 我们不能从非 UI 线程中举杯庆祝吗?

  • 问题内容: 当用户选择在另一个线程中启动阻止进程的菜单项时,我试图在JavaFX 8应用程序中提供反馈。在我的实际应用程序中,它是文件下载,但是通过示例,我使用最少的代码创建了一个测试用例: 它的工作方式如下:当选择“开始”菜单项时,主菜单文本应立即更改为“正在运行…”,然后应附加“完成!”。经过5秒钟的模拟我的文件下载的睡眠。 实际上发生的是,即使我正在使用,在阻止过程完成 后 , 两个 文本更