2016-03-29 7 views
5

Mam plik FXML definiujący interfejs użytkownika JavaFX. W pliku FXML, mam następujące:Wiązanie JavaFX nie działa z "Nie można powiązać z obiektem bez typu".

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

Kiedy próbuję załadować mój plik FXML z następującego kodu, otrzymuję javafx.fxml.LoadException z komunikatem

nie może wiązać się bez typu obiektu.

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 
} 

Czy ktoś wie jak zmodyfikować FXML wyłączyć mojej tarczy, gdy jest zaznaczone pole wyboru? Wiem, jak to zrobić w kodzie, ale chcę dowiedzieć się więcej o składni FXML. Powinienem także dodać, że gdy usuwam próbę powiązania właściwości z FXML, wszystko ładuje się zgodnie z oczekiwaniami. Dzięki.

EDIT

związku z komentarzem @Groostav mówiąc, że musi to być coś w części ... kodu, wpadłem minimalnej, powtarzalny przykład. W moim przykładzie są dwa pliki, które skopiuję w całości tutaj.

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> 

Kiedy uruchomić główną metodę, pojawia się następujący komunikat:

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 

Jeśli usuniemy disable="${myCheckbox.selected}" z pliku FXML, wszystko ładuje się zgodnie z oczekiwaniami. Ponadto jestem w stanie powiązać właściwości w kodzie. Dlaczego to nie działa i jak mogę zmodyfikować FXML, aby to wspierać? Pracuję na Windows 7 Enterprise SP1 x64, używając Java SE JDK 8u92 x64.

+0

Nie jestem pewien, co jest źle, mam prawie identyczny kod działa, problem nie jest z FXML pan pisał, ale coś w jednym z ' ... '' – Groostav

+0

@Groostav Dodałem minimalny przykład, który odtwarza problem w moim środowisku. Czy mój pełny przykład działa dla ciebie? Jeśli tak, jakiego OS/JDK używasz? –

Odpowiedz

0

Wygląda na to, że w ten sposób nie można ustawić wyłączonej właściwości Spinnera przy użyciu FXML. Działa dobrze na TextFields. Może to być błąd, myślę, że ma to coś wspólnego z ładowaczem oczekującym ciała dla znacznika Spinnera definiującego ValueFactory, więc Spinner nie jest poprawnie zdefiniowany, kiedy próba połączenia stanu CheckBox z właściwością Disable zostanie przeprowadzona.

Poniższe obejście może pomóc:

<?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> 
Powiązane problemy