【问题标题】:JavaFX - How to periodically read xml file and update TableViewJavaFX - 如何定期读取 xml 文件并更新 TableView
【发布时间】:2018-10-31 00:42:29
【问题描述】:

我面临的问题是我希望我的 TableView 在 XML 文件更新后刷新。当数据被修改时,TableView 会立即更新,当用户退出并重新打开应用程序时,新数据应该是存在的。但我希望此更新是“自动的”,这样如果 2 个用户中的一个进行更改,其他用户正在运行的应用程序也会自动反映该更改。

我想定期读取 XML 文件,但我没有运气。我正在使用 DOM 来读取文件。我还没有查看 ScheduledService,但它似乎是一个潜在的解决方案。 我还添加了一个“刷新数据”按钮,它调用了我在 XML 文件中读取的类,但这也不起作用。有什么提示吗?

【问题讨论】:

  • Java WatchService 将在这里提供帮助。本质上,它会在监视文件被修改时触发一个事件。

标签: xml dom javafx tableview


【解决方案1】:

您可以使用WatchService API 来监视文件夹。这可以在任何时候添加、删除或修改文件时触发事件。

这里有一个快速的 MCVE 来演示。在此示例中,我们将只注意对现有文件的修改:

import java.io.IOException;
import java.nio.file.*;

import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

public class Main {

    public static void main(String[] args) {

        // Launch the watcher in a background thread
        new Thread(() -> {
            try {
                setupWatcher();
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

    }

    public static void setupWatcher() throws IOException, InterruptedException {

        System.out.println("Listening for changes to DATA.XML");

        // Set the directory we want to watch for changes
        Path dir = Paths.get("your/path");

        // Create the WatchService
        WatchService watchService = FileSystems.getDefault().newWatchService();

        // Only watch for modifications (ignore new or deleted files)
        dir.register(watchService, ENTRY_MODIFY);

        // The WatchKey will collect any events from the WatchService. We want this to run indefinitely so we wrap in
        // an infinite loop
        while (true) {
            // Gets the latest event
            WatchKey watchKey = watchService.take();

            // When a change is found, let's find out what kind and act appropriately
            if (watchKey != null) {

                // For each event triggered
                watchKey.pollEvents().forEach(watchEvent -> {

                    // Get the filename of the file that was modified
                    String filename = watchEvent.context().toString();

                    // If it is the file we care about, do something
                    if (filename.equalsIgnoreCase("DATA.XML")) {

                        // Do your update of the TableView here
                        System.out.println("DATA.XML has been changed!");
                    }

                });

                // After the event was processed, reset the watchKey
                watchKey.reset();
            }
        }

    }
}

可以在 JavaDocs 或this tutorial 中找到更多信息。

【讨论】:

  • 感谢您的回复!但是我收到java.nio.file.NotDirectoryException: U:\test.xml 的错误。我不完全知道这意味着什么,除了它意味着文件不是目录。我以为我只需要把我的路径放在那里?
  • 确保你的路径中没有包含文件名。
  • 谢谢!是的,我刚得到它。我只是输入了`U:\`,现在当我进行更改时,WatchService 会打印出“TEST.XML 已更改!”在我本地运行的两个应用程序上都很棒,但不幸的是,另一个应用程序没有更新它的 tableview ......我正在努力思考我能做什么。该文件有一个监听器并且正在工作,所以我仍然需要解析 xml 文件并检索更改,对吗?
  • 好吧,这仍然是你来实现的。
【解决方案2】:

您可能希望使用 Java WatchService 在文件内容更改时收到通知。见Oracle docs

这里还有一个tutorial 展示了如何使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2017-07-22
    • 1970-01-01
    相关资源
    最近更新 更多