在javafx 8中设置和使用时间轴之外的变量

时间:2014-08-01 14:13:18

标签: java javafx-8

我正在尝试编写一个javafx应用程序来观看系统剪贴板:

package sample;

import javafx.event.ActionEvent;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.util.Duration;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;

public class Main extends Application {

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

        final Clipboard clipboard = Clipboard.getSystemClipboard();
        final String oldString = "";
        final String newString = "";
        Timeline repeatTask = new Timeline(new KeyFrame(Duration.millis(200), new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                if (clipboard.hasString()) {
                    newString = clipboard.getString();
                    if(oldString != newString) {
                        System.out.printf("String changed in clipboard: " + newString);
                        oldString = newString;
                    }
                    else {
                        System.out.println("String not changed.");
                    }
                }
            }
        }));
        repeatTask.setCycleCount(Timeline.INDEFINITE);
        repeatTask.play();
    }


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

问题是我需要将剪贴板的旧内容存储在时间轴对象之外,我需要对它们进行更改,但是一旦它们设置为final - 就像java要求那样 - 不再可能进行修改。 / p>

1 个答案:

答案 0 :(得分:2)

您可以将oldString作为Application类的字段:

private String oldString = "";

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

    final Clipboard clipboard = Clipboard.getSystemClipboard();
    Timeline repeatTask = new Timeline(new KeyFrame(Duration.millis(200), new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            if (clipboard.hasString()) {
                String newString = clipboard.getString();
                if(!oldString.equals(newString)) {
                    System.out.printf("String changed in clipboard: " + newString);
                    oldString = newString;
                }
                else {
                    System.out.println("String not changed.");
                }
            }
        }
    }));
    repeatTask.setCycleCount(Timeline.INDEFINITE);
    repeatTask.play();
}

这是有效的,因为当您访问oldString时,您实际上正在访问this.oldString,其中this是最终的。

另请注意,要比较字符串,您应使用oldString.equals(newString)而非比较对象标识(== / !=)。

此外,如果您使用的是Java 8,则可以使用ReactFX删除Timeline样板:

private String oldString = "";

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

    final Clipboard clipboard = Clipboard.getSystemClipboard();
    EventStreams.ticks(Duration.ofMillis(200)).subscribe(tick -> {
        if (clipboard.hasString()) {
            String newString = clipboard.getString();
            if(!oldString.equals(newString)) {
                System.out.printf("String changed in clipboard: " + newString);
                oldString = newString;
            }
            else {
                System.out.println("String not changed.");
            }
        }
    });
}

有关使用ReactFX中的计时器的详细信息,请参阅我的博文http://tomasmikula.github.io/blog/2014/06/04/timers-in-javafx-and-reactfx.html