2016-03-29 16 views
5

Ho un file FXML che definisce un'interfaccia utente JavaFX. All'interno del file FXML, ho il seguente:JavaFX Binding non riesce con "Impossibile eseguire il binding su oggetto non tipizzato".

... 
<Checkbox fx:id="myCheckbox" ... /> 
<Spinner disable="${myCheckbox.selected}" ... /> 
... 

Quando provo a caricare il mio file FXML con il seguente codice, ottengo un javafx.fxml.LoadException con il messaggio

Impossibile associare all'oggetto tipizzato.

final Class<?> controllerClass = ...; 
final FXMLLoader fxmlLoader = new FXMLLoader(); 
final String fxmlPath = controllerClass.getSimpleName() + ".fxml"; 
try (final InputStream fxmlStream = controllerClass.getResourceAsStream(fxmlPath)) { 
    fxmlLoader.load(fxmlStream); 
    final Object controller = fxmlLoader.<Object>getController(); 
    return controller 
} 

Qualcuno sa come modificare il FXML per disabilitare la mia filatore quando la casella è selezionata? So come fare questo in codice, ma voglio saperne di più sulla sintassi FXML. Dovrei anche aggiungere che quando rimuovo il tentativo di associazione delle proprietà da FXML, tutto si carica come previsto. Grazie.

EDIT

A causa del commento da @Groostav dicendo che deve essere qualcosa nella ... parte del codice, mi si avvicinò con un minimo, ad esempio riproducibile. Nel mio esempio, ci sono due file, che copierò nella loro interezza qui.

Main.java:

package test; 

import java.io.InputStream; 

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

public class Main extends Application { 
    public static void main(final String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage window) throws Exception { 
     final FXMLLoader fxmlLoader = new FXMLLoader(); 
     final String fxmlPath = "Example.fxml"; 
     final Parent root; 
     try (final InputStream fxmlStream = getClass().getResourceAsStream(fxmlPath)) { 
      root = (Parent)fxmlLoader.load(fxmlStream); 
     } 
     final Scene scene = new Scene(root); 
     window.setScene(scene); 
     window.show(); 
    } 
} 

Example.fxml:

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

<?import javafx.scene.control.CheckBox?> 
<?import javafx.scene.control.Spinner?> 
<?import javafx.scene.layout.HBox?> 

<HBox xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" 
     alignment="BASELINE_LEFT" spacing="15"> 
    <children> 
    <CheckBox fx:id="myCheckbox" text="Disable?" mnemonicParsing="false" /> 
    <Spinner disable="${myCheckbox.selected}" /> 
    </children> 
</HBox> 

Quando eseguo il metodo principale, ottengo il seguente output:

Exception in Application start method 
java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389) 
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) 
Caused by: java.lang.RuntimeException: Exception in Application start method 
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: javafx.fxml.LoadException: Cannot bind to untyped object. 
unknown path:12 

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2597) 
    at javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:103) 
    at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:299) 
    at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:235) 
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:749) 
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527) 
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2425) 
    at test.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) 
    ... 1 more 
Exception running application test.Main 

Se rimuovo lo disable="${myCheckbox.selected}" dal file FXML, tutto si carica come previsto. Inoltre, sono in grado di associare le proprietà nel codice. Perché non funziona e come posso modificare FXML per supportarlo? Sono in esecuzione su Windows 7 Enterprise SP1 x64, utilizzando Java SE JDK 8u92 x64.

+0

non sono sicuro che cosa è sbagliato, ho il codice quasi identico a lavorare, il problema non è con il FXML che hai postato, ma qualcosa in uno dei ' ... ''s – Groostav

+0

@Groostav Ho aggiunto un esempio minimo che riproduce il problema nel mio ambiente. Il mio esempio completo funziona per te? Se sì, quale OS/JDK stai usando? –

risposta

0

Sembra che non sia possibile impostare la proprietà disabilitata sullo Spinner utilizzando FXML in questo modo. Funziona bene su TextFields. Potrebbe trattarsi di un bug, suppongo che abbia a che fare con il caricatore che si aspetta un corpo per il tag Spinner che definisce ValueFactory, quindi lo Spinner non viene definito correttamente quando viene eseguito il tentativo di collegare lo stato CheckBox alla proprietà disable.

la seguente soluzione potrebbe aiutare:

<?xml version="1.0" encoding="UTF-8"?> 
<?language javascript?> 
<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.util.* ?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.* ?> 
<?import javafx.scene.layout.* ?> 
<?import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory?> 

<HBox xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" 
     alignment="BASELINE_LEFT" spacing="15"> 
    <fx:script> 
    function handleCheckBoxAction(event) { 
     mySpinner.disable = (! mySpinner.disabled); 
    } 
    </fx:script> 
    <children> 
    <CheckBox fx:id="myCheckbox" text="Disable?" mnemonicParsing="false" onAction="handleCheckBoxAction(event);" /> 
    <Spinner fx:id="mySpinner"> 
     <valueFactory> 
     <SpinnerValueFactory.IntegerSpinnerValueFactory min="0" max="10"/> 
     </valueFactory> 
    </Spinner> 
    </children> 
</HBox>