FXML / FXMLLoader error diagnostic tool(s) sought

2020-02-12 14:49发布

问题:

overview

Hi, here's an outline use-case. I have a seemingly valid FXML file developed in JavaFX Scene Builder. It is by now a non-trivial chunk of XML and there are runtime load errors somewhere in the FXML file. Scene Builder works fine with the Preview option. I have a 'simple.fxml' file I use to verify that the controller is working as intended, that is same controls and events but without the extra FXML layouts. And I have and I am doing the cut-out-code and test loop to identify the XML with the problem. So I will get to the bottom of this at some point.

At present there are no errors showing in Scene Builder nor in the Netbeans FXML editor and I don't get an error with the load as in "JavaFX - loading FXML file error"(#1). All I get is an exception on end task in runnable, which says the loader threw an exception.

goal(s)

These errors happen. The question is what tools are available or under development to Troubleshoot FXML files?

Some thoughts, questions or options:

  1. Is this a bug? To mind mind something as black box as a loader ought to issue some kind of indicator like failure on line 246 or " ... Something that indicates where to look.
  2. What tricks, techniques or suggestions do you have for ways to find /resolve such errors faster?
    • Is there a place for using Include
  3. What hooks are there on FXMLLoader class to catch or trap errors before it all falls-down?
  4. Are there any facilities to log or diagnose the FXMLLoader processing?
  5. Has anyone written a custom FXMLLoader that could be used this way? (see #3).
    • I saw that FXML uses SAX, is it possible to wrap or hook the parser and give the FXMLLoader an alternate parser?
  6. Are there any static tools for analysing the FXML and Java application -- Like an FXML Lint or something?
  7. What indepth FXML load, parse, runtime information is available on how the FXML is processed.
  8. Are there or could some extra entry points be added-to or injected into the controller(s) to capture FXML load problems?
    • For example, can controllers be cascaded such that I can make a 'root controller' which might capture problems closer to the point of origin.

At present problems inside the FXML that are only uncovered at the time of loading are just time-consuming and unpredictable if the editors don't see anything. I'd like to see some diagnostic tools if anyone h

Further Insights

These are some relevant 'debugging' and 'troubleshooting' tips that come along during development. Perhaps some of these may find their way into a FXML Validator or Lint tool one day(?) The points are in no particular order, they are numbered for cross-reference purposes.

  1. Any controller identifiers in the FXML must be present and annotated in the Java code with @FXML. If an annotation is missing the FXML won't load.
  2. Every Java name annotated with @FXML should be in the FXML mark-up file. Say a label called, "myLabel": if the myLabel used in the code there will be a NullPointerException. The file will load, unlike case #1.
  3. Don't use the NetBeans "Compile on Save" compile option with JavaFX. It seem to generate spurious NullPointerException-s on seemingly correct code.
  4. If you rename/refactor your main app ensure you update the build target (e.g. maven or ant). Some IDE refactor code can miss that link.
  5. FXMLLoader() does give you one clue. If you catch the exception you can look at the "getMessage()" ...

    catch( Exception ex ){
           System.out.println("Exception on FXMLLoader.load()");
           System.out.println( ex.getMessage() );   //-- Doesn't show in stack dump
    }
    
  6. Check your typing on FXML resources. Small typos are the devil to identify and detect. This goes for any string that isn't checked by a compiler or lint, not just FXML.

    // These two line are not the same:
    Parent root;
    root = FXMLLoader.load(getClass().getResource("Samplle.fxml"));
    root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
    
  7. There exception.getMessage() is: "Location required", for that typo in #6.

  8. If you edit the FXML manually, ensure that you all relevant components.
  9. Remember to include the FXML namespace with "-d" files, e.g. needed on the outermost XML element.

    <TreeView id="treeView" fx:id="tree" xmlns:fx="http://javafx.com/fxml" ... >
    

Hope something helps. These are guesses based on small tests and trials. Please fix embedded assumptions of misunderstandings about how things actually work.

see also:

  1. JavaFX - loading FXML file error
  2. Android diagnostic tool for applications (use case)
  3. I would like to override FXMLLoader. How can I do that?
  4. How does FXMLLoader load the FXML's controller?
  5. Cannot locate the fxml error for JavaFX (use case)
  6. Class javafx.fxml.FXMLLoader
  7. JavaFX Architecture (PDF available), unfortunately there's nothing in here about FXML.
  8. Introduction to FXML
  9. FXMLLoader.java source code

回答1:

I had the same problem using SceneBuilder 2.0 and JavaFX2. The problem is that SceneBuilder generates JavaFX8 code. The code is valid but not 100% JavaFX2 compatible. Maybe that could be your problem. You should get an Exception from the FXMLLoader in which line the error is.



回答2:

Scenic View

Scenic View is a JavaFX application designed to make it simple to understand the current state of your application scenegraph, and to also easily manipulate properties of the scenegraph without having to keep editing your code. This lets you find bugs, and get things pixel perfect without having to do the compile-check-compile dance.

There is a good recommendation and description of Scenic View in this presentation:

  • Do It Yourself: Custom JavaFX Controls

update Scenic View works like a debugger or monitor for JavaFX applications. It won't help with FXML loader issues, as it investigates or monitors running scenes. Also I found the most recent version, v1.3.0, to be unstable on Windows 7 and Java 8, 64-bit.