Pergunta

Eu estou tentando escrever um aplicativo javafx para assistir a área de transferência do sistema:

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);
    }
}

O problema é que eu preciso armazenar o conteúdo anterior da área de transferência fora do cronograma objeto, e preciso fazer alterações para eles, mas, depois de se definir como final -- como java requer -- modificação não é mais possível.

Foi útil?

Solução

Você pode ter oldString como um campo da sua classe de Aplicação:

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();
}

Isto funciona, porque quando você acessar oldString, você está, na verdade, acessando this.oldString, onde this é final.

Observe também que para comparar seqüências de caracteres, você deve usar oldString.equals(newString) em vez de comparar objeto de identidades (==/!=).

Além disso, se você estiver usando o Java 8, você pode livrar-se da linha de tempo clichê usando ReactFX:

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.");
            }
        }
    });
}

Para obter mais informações sobre como utilizar o temporizador de ReactFX, veja o meu post de blog http://tomasmikula.github.io/blog/2014/06/04/timers-in-javafx-and-reactfx.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top