2016-04-27 5 views
1

Я создаю мощный текстовый элемент управления, который использует WebView для отображения и HTMLEditor для редактирования. Когда я попытался добавить элемент управления пользовательского Scenebuilder контролирует было брошено исключение:Scenebuilder отклоняет Webview в пользовательском элементе управления

Exception for: com/spindotta/jfx/control/text/RichTextArea.class 

javafx.fxml.LoadException:

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) 

...

Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = LibraryFolderWatcher([library folder location]) 

...

at javafx.scene.web.WebEngine.checkThread(WebEngine.java:1216) 

...

Кажется, что Scenebuilder пытается создать экземпляр WebView, который, в свою очередь, пытается создать экземпляр WebEngine, для которого, как представляется, требуется поток приложений FX, который пользовательский элемент управления не генерирует.

Был бы благодарен за любые идеи/решение проблемы.

Спасибо!

ответ

1

SceneBuilder имеет встроенный механизм, который проверяет все банки в пользовательской библиотеке, ища пользовательские элементы управления.

Для любой конкретной банки, которая подразумевает проверку всех ее классов, поиск возможных элементов управления: конкретные классы, которые можно назначить с Node. Затем он создает экземпляр для них и пытается загрузить его на пути к классу. Если он будет работать, он будет добавлен в библиотечную панель.

В случае вашего настраиваемого элемента управления, который включает в себя узел WebView, это означает, что когда ваш контроль проверяется SceneBuilder, будет выполнен новый экземпляр WebView. На этом этапе вы получите исключение, вы упомянули:

Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = LibraryFolderWatcher() 
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236) 
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423) 
at javafx.scene.web.WebEngine.checkThread(WebEngine.java:1216) 
at javafx.scene.web.WebEngine.<init>(WebEngine.java:856) 
at javafx.scene.web.WebEngine.<init>(WebEngine.java:845) 
at javafx.scene.web.WebView.<init>(WebView.java:271) 

Так простое решение для этого будет позволяет пользовательский элемент управления должен быть загружен в потоке приложения JavaFX, когда загружается в режиме конструктора по SceneBuilder.

Этот небольшой пользовательский элемент управления работает для меня:

public class WebControl extends StackPane { 

    private WebView webView; 

    public WebControl() { 
     if (Platform.isFxApplicationThread()) { 
      init(); 
     } else { 
      // Intended for SceneBuilder 
      Platform.runLater(this::init); 
     } 
    } 

    private void init() { 
     webView = new WebView(); 
     WebEngine webEngine = webView.getEngine(); 
     webEngine.load("http://www.google.com"); 
     getChildren().add(webView); 
    } 

} 

WebControl

+0

@JPereda - Спасибо за ответ, и особенно для объяснения шаг за шагом процесса и как это привести к исключению. Это именно то, что я думал, что происходит, но ваше объяснение более ясно, потому что вы знаете, что делаете, и я ... нет. Относительно новый здесь, поэтому я не знаю, как дать вам кредит, был бы признателен, если бы вы могли прокомментировать, как это сделать. Благодаря! – jfr

+0

Просто примите ответ (нажмите на галочку рядом с ответом) как действительный и запустите его, если хотите. Это поможет другим найти его в качестве действительного источника, если они будут работать в одной и той же проблеме. –

+0

Очень важно, подумайте. – jfr

Смежные вопросы