Работая на платформе NetBeans, Swing является королем. JavaFX — наследный принц. Однако некоторые разработчики избегают разработки элементов управления с графическим интерфейсом JavaFX на платформе NetBeans, поскольку Swing доступен по умолчанию. Что ж, можно разработать формы JavaFX и просто заменить стандартные панели NetBeans. В следующем руководстве объясняется, как разработчик может принять форму графического интерфейса JavaFX и FXML, разработанные с использованием Scene Builder, и заменить визуальную панель мастера платформы NetBeans с минимальными усилиями.
Этот учебник основан на следующих предыдущих записях:
http://netbeans.dzone.com/articles/javafx-fxml-meets-netbeans
http://netbeans.dzone.com/articles/how-embed-javafx-chart-visual
Если вы ищете вторую часть этого учебника по Wizard / JavaFX, перейдите сюда:
http://netbeans.dzone.com/articles/how-integrate-javafx-netbeans-part5
Теперь, почему эта концепция будет полезна? Хорошо, рассмотрим группу разработчиков, в которой новые Java-приложения пишутся на JavaFX. Зачем переписывать полезные классы Panel на Swing, чтобы использовать их в мастере платформы NetBeans? Зачем создавать новые разработки в Swing, чтобы быть совместимыми с приложением платформы NetBeans? Приложения на платформе NetBeans прекрасно поддерживают рендеринг JavaFX с Swing. Вот как:
Сначала вам нужно будет немного подготовиться к настройке приложения для этого урока. Сделайте следующее:
- Создайте графический интерфейс JavaFX. Создайте новый графический интерфейс JavaFX FXML с помощью SceneBuilder. Добавьте необходимые элементы управления и сгенерируйте файл FXML и класс контроллера.
- Обновите свой класс контроллера, расширив JFXPanel. Это часть модели Swing Interop, которую мы все знаем и любим. Вам также потребуется @Override метод getName (), чтобы среда мастера могла обновить заголовок текущего шага.
- Инкапсулируйте поля / значения. Создайте общедоступные методы, которые обеспечат платформу Wizard полями, которые необходимо передать от панели к панели. Это то же самое, что вам нужно сделать со стандартным классом Swan Wizard JPanel.
Код для вашего класса контроллера все еще выполняется без проблем в вашем приложении JavaFX, но теперь совместим с Swing Interop. Код может выглядеть так:
package jfxwizpanel.jfxwiz; import java.io.File; import java.net.URL; import java.util.ResourceBundle; import javafx.embed.swing.JFXPanel; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.stage.FileChooser; /** * * @author SPhillips (King of Australia) */ public class WizPanelController extends JFXPanel implements Initializable { @FXML // fx:id="browseButton" private Button browseButton; // Value injected by FXMLLoader @FXML // fx:id="pathText" private TextField pathText; //Field that Path is stored in private String filePath = ""; //some value to pass to the next Wizard panel // Handler for Button[fx:id="browseButton"] onAction public void handleButtonAction(ActionEvent event) { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Select File"); //Show open file dialog File file = fileChooser.showOpenDialog(null); if(file!=null) { setFilePath(file.getPath()); pathText.setText(filePath); } } @Override // This method is called by the FXMLLoader when initialization is complete public void initialize(URL fxmlFileLocation, ResourceBundle resources) { assert browseButton != null : "fx:id=\"browseButton\" was not injected: check your FXML file 'WizPanel.fxml'."; assert pathText != null : "fx:id=\"pathText\" was not injected: check your FXML file 'WizPanel.fxml'."; // initialize your logic here: all @FXML variables will have been injected } @Override //This method is used by Wizard Framework to generate list of steps public String getName() { return "FXML JFXPanel"; } /** * @return the filePath */ public String getFilePath() { return filePath; } /** * @param filePath the filePath to set */ public void setFilePath(String filePath) { this.filePath = filePath; } }
И когда вы запускаете этот код в приложении JavaFX FXML, вы получаете что-то вроде следующего снимка экрана:
- Создайте приложение платформы NetBeans. Создайте новое приложение на платформе NetBeans и добавьте новый модуль. Добавьте мастера с помощью мастера «Wizard».
- Включите JavaFX Runtime. Создайте модуль-оболочку библиотеки NetBeans, включающий «jfxrt.jar», и установите зависимость от него в модуле, описанном выше.
- Класс Copy Controller и файл FXML. Начиная с NetBeans 7.3, вы не можете реорганизовать копирование этих файлов из вашего проекта FXF JavaFX в ваш пакет приложений на платформе NetBeans. После ручного копирования этих двух файлов вам потребуется вручную заменить путь к пакету как в классе Controller, так и в строке fx: controller в файле FXML.
Ваш код FXML теперь может выглядеть примерно так:
<?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.geometry.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.web.*?> <AnchorPane id="AnchorPane" prefHeight="410.0" prefWidth="582.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxwizard.jfxwiz.WizPanelController"> <children> <VBox id="VBox" prefHeight="410.0000999999975" prefWidth="582.0" spacing="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <children> <AnchorPane id="AnchorPane"> <children> <RadioButton layoutX="161.0" layoutY="14.0" mnemonicParsing="false" prefWidth="134.0" text="Prefer Swing" /> <RadioButton layoutX="14.0" layoutY="14.0" mnemonicParsing="false" prefWidth="134.0" selected="true" text="Prefer JavaFX" /> </children> </AnchorPane> <AnchorPane prefHeight="45.0" prefWidth="310.0"> <children> <Button fx:id="browseButton" layoutX="486.0" mnemonicParsing="false" onAction="#handleButtonAction" prefHeight="45.0" prefWidth="72.0" text="Browse" /> <TextField fx:id="pathText" layoutX="14.0" layoutY="4.0" prefHeight="41.0" prefWidth="461.0" /> </children> </AnchorPane> <AnchorPane prefHeight="272.0" prefWidth="572.0"> <children> <HTMLEditor prefHeight="272.0" prefWidth="572.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> </children> </AnchorPane> </children> <padding> <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> </padding> </VBox> </children> </AnchorPane>
- Замените панель Swing на контроллер FXML. На этом этапе вы можете заменить автоматически сгенерированный класс Swing JPanel, который обычно загружается классом управления Wizard, на ваш контроллер JavaFX FXML. Помните, что мы расширили JFXPanel, и это окупается здесь. Все, что нам нужно сделать сейчас, это следовать нашей стандартной технике Swing Interop. Однако на этот раз мы должны использовать наш шаблон Platform.runLater () в методе getComponent () класса контроллера Wizard.
Ниже приведен соответствующий код после обновления. Обратите внимание, как мало мы должны были изменить:
public class JfxwizWizardPanel1 implements WizardDescriptor.Panel<WizardDescriptor> { /** * The visual component that displays this panel. If you need to access the * component from this class, just use getComponent(). */ //private JfxwizVisualPanel1 component; public WizPanelController component; //Replaces original autogenerated JPanel class // Get the visual component for the panel. In this template, the component // is kept separate. This can be more efficient: if the wizard is created // but never displayed, or not all panels are displayed, it is better to // create only those which really need to be visible. @Override public WizPanelController getComponent() { if (component == null) { component = new WizPanelController(); //return new JFXPanel controller Platform.setImplicitExit(false); Platform.runLater(new Runnable() { @Override public void run() { createScene(); //standard Swing Interop Pattern } }); } return component; } private void createScene() { try { URL location = getClass().getResource("WizPanel.fxml"); //same FXML copied from JavaFX app FXMLLoader fxmlLoader = new FXMLLoader(); fxmlLoader.setLocation(location); fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()); Parent root = (Parent) fxmlLoader.load(location.openStream()); Scene scene = new Scene(root); component.setScene(scene); component = (WizPanelController) fxmlLoader.getController(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } }
На этом этапе вы сможете решить любые проблемы с импортом, скомпилировать и запустить. Вы должны увидеть, что ваш JavaFX GUI красиво загружен в рамке Wizard Dialog, как на скриншоте ниже:
Здорово, что вы можете загружать графические интерфейсы JavaFX в свои мастера. Но вы ничего не сделали с информацией, поэтому вы фактически не использовали среду WizardDescriptor. Узнайте, как это сделать, в следующей части руководства Wizard / JavaFX здесь:
http://netbeans.dzone.com/articles/how-integrate-javafx-netbeans-part5