2016-07-25 11 views
1

Verzeihen Sie, wenn das, was ich fragen, offensichtlich ist, aber ich kann nicht herausfinden, wie man eine Bindung in einem StyleClassedTextArea, mit RichTextFx erstellen. Was ich tun möchte, ist, den Bereich und einen Knopf zu haben (der irgendeine Textverarbeitung auslöst) und die Taste zu deaktivieren, wenn der Bereich leer ist. Mein Code ist der folgendeRichTextFx: Wie füge ich eine Bindung zu StyleClassedTextArea hinzu?

Main.java

package application; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.stage.Stage; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 

public class Main extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     try { 
      Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));    
      Scene scene = new Scene(root); 
      scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); 
      primaryStage.setScene(scene); 
      primaryStage.show(); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

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

Controller.java

package application; 

import java.net.URL; 
import java.util.ResourceBundle; 
import org.fxmisc.richtext.StyleClassedTextArea; 
import javafx.beans.binding.Bindings; 
import javafx.beans.value.ObservableStringValue; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.Button; 

public class Controller implements Initializable { 
    @FXML private StyleClassedTextArea mainArea; 
    @FXML private Button processButton; 
    @Override 
    public void initialize(URL arg0, ResourceBundle arg1) { 
     // TODO Auto-generated method stub 
     processButton.disableProperty().bind(Bindings.isEmpty((ObservableStringValue) mainArea.textProperty())); 
    } 
} 

Main.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Button?> 
<?import javafx.scene.layout.AnchorPane?> 
<?import javafx.scene.layout.VBox?> 
<?import org.fxmisc.richtext.StyleClassedTextArea?> 


<AnchorPane prefHeight="308.0" prefWidth="291.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="application.Controller"> 
    <children> 
     <VBox layoutY="6.0" prefHeight="308.0" prefWidth="291.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 
     <children> 
      <StyleClassedTextArea fx:id="mainArea" /> 
      <Button fx:id="processButton" mnemonicParsing="false" text="process" /> 
     </children> 
     </VBox> 
    </children> 
</AnchorPane> 

und dies, weil mainTextArea.textProperty() kehrt ObservableValue<String>, wenn ich werfe es eine Ausnahme mit dem folgenden Stack-Trace wirft

javafx.fxml.LoadException: 
/C:/Users/dcg601/workspace/javafx/bin/application/Main.fxml 

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104) 
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097) 
    at application.Main.start(Main.java:22) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863) 
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326) 
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294) 
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) 
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: java.lang.ClassCastException: org.reactfx.value.SuspendableValWrapper cannot be cast to javafx.beans.value.ObservableStringValue 
    at application.Controller.initialize(Controller.java:20) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548) 
    ... 17 more 
+0

Versuchen Sie eine explizite Umwandlung: 'processButton.disableProperty(). Bind (Bindings.isEmpty ((ObservableStringValue) mainTextArea.textPropert y())); ' –

+0

@AndreyM Leider funktioniert nicht, eine seltsame Ausnahme zu werfen. Ich bearbeitete meine Frage einschließlich eines MCVE –

+0

Nun, der Fehler sagt mit anderen Worten, dass es nicht gegossen werden kann :) –

Antwort

1

Es ist verrückt, aber es funktioniert:

@Override 
public void initialize(URL arg0, ResourceBundle arg1) { 
    // TODO Auto-generated method stub 
    ObservableValue<String> qwer = mainArea.textProperty(); 

    ObservableStringValue qwerQ = new ObservableStringValue() { 
     public String get() { return qwer.getValue(); } 
     public String getValue() { return qwer.getValue(); } 
     public void addListener(InvalidationListener listener) { 
      qwer.addListener(listener); 
     } 
     public void removeListener(InvalidationListener listener) { 
      qwer.removeListener(listener); 
     } 
     public void addListener(ChangeListener<? super String> listener) { 
      qwer.addListener(listener); 
     } 
     public void removeListener(ChangeListener<? super String> listener) { 
      qwer.removeListener(listener); 
     } 
    }; 

    processButton.disableProperty().bind(Bindings.isEmpty(qwerQ)); 
} 

Aber wahrscheinlich besser, einen einfachen Zuhörer hinzuzufügen:

mainArea.textProperty().addListener((ov, oldv, newv) -> { 
    processButton.setDisable(newv.isEmpty()); 
}); 
+0

Danke, es funktioniert, obwohl ich das Listener-Muster bevorzugen werde –