Tha*_*ngs 9 java inheritance javafx fxml
如果为视图使用FXML,如何正确扩展自定义JavaFX组件以添加或修改其GUI组件?
作为示例场景,假设我使用以下方法创建自定义JavaFX组件:
SpecializedButton.java(控制器)
package test;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
public class SpecializedButton extends HBox
{
@FXML private Button button;
@FXML private Label label;
public SpecializedButton()
{
FXMLLoader loader = new FXMLLoader( getClass().getResource( "SpecializedButton.fxml" ) );
loader.setRoot( this );
loader.setController( this );
try {
loader.load();
} catch ( IOException e ) {
throw new RuntimeException( e );
}
}
// specialized methods for this specialized button
// ...
public void doSomething() {
button.setText( "Did something!" );
}
}
Run Code Online (Sandbox Code Playgroud)
SpecializedButton.fxml(查看)
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>
<fx:root type="HBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane HBox.hgrow="ALWAYS">
<children>
<Label fx:id="label" text="Click to do something: " AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane HBox.hgrow="ALWAYS">
<children>
<Button fx:id="button" onAction="#doSomething" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</children>
</fx:root>
Run Code Online (Sandbox Code Playgroud)
MyApp.java
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MyApp extends Application
{
public static void main( String[] args )
{
launch( args );
}
public void start( Stage stage ) throws Exception
{
stage.setScene( new Scene( new SpecializedButton(), 300, 50 ) );
stage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
SpecializedButton类加载FXML视图(SpecializedButton.fxml)并充当它的控制器.
SpecializedButton FXML视图分别在左侧和右侧创建一个带有两个AnchorPanes和一个Label和Button的HBox.单击该按钮时,它会调用SpecializedButton控制器类中的doSomething().
问题
通过此设置,我使用FXML将视图与应用程序逻辑分开.
但是,如果我想创建一个扩展SpecializedButton 的新的HighlySpecializedButton类,我不知道如何"扩展"视图.
如果我想使用SpecializedButton视图,但是为HighlySpecializedButton修改它,我必须将视图代码复制到新的FXML文件中,导致重复的代码而不是正确的继承.
如果我没有使用FXML,而是在Java类中创建GUI组件,那么扩展该类将使我能够正确地继承和添加/修改超类中的组件.
我显然误解了一些关于JavaFX的非常重要的概念.
题
在这种情况下,FXML视图是如此"愚蠢",每当我想从自定义组件继承时,我必须创建一个全新的FXML视图吗?
或者,如果我误解了真正的问题,那么使用或不使用FXML创建可扩展自定义JavaFX组件的正确方法是什么?
我非常感谢任何见解.提前致谢!
根据我的理解,您希望能够扩展现有组件并避免复制和粘贴新组件的整个标记.
您可以使用@DefaultProperty注释为组件定义扩展点.看看ex javafx.scene.layout.Pane:有一个ObservableList getChildren()
定义的@DefaultProperty("children").这样,当您使用ex HBox(扩展窗格)作为组件的根元素时,所有子组件都将添加到children窗格定义的属性中.
以同样的方式,您可以在FXML中定义扩展点:
SpecializedButton.fxml(我为这个例子简化了一点)
<fx:root type="HBox">
<HBox>
<Label fx:id="label" text="Click to do something: " />
<HBox fx:id="extension"></HBox>
</HBox>
<HBox>
<Button fx:id="button" onAction="#doSomething"/>
</HBox>
</fx:root>
Run Code Online (Sandbox Code Playgroud)
这HBox fx:id="extension"将是我的延伸点:
@DefaultProperty(value = "extension")
public class SpecializedButton extends HBox
{
@FXML private HBox extension;
public ObservableList<Node> getExtension() {
return extension.getChildren();
}
// ... more component specific code
}
Run Code Online (Sandbox Code Playgroud)
SuperSpecializedButton.fxml
<fx:root type="SpecializedButton">
<Label text="EXTENDED HALLO"/>
</fx:root>
Run Code Online (Sandbox Code Playgroud)
和:
public class SuperSpecializedButton extends SpecializedButton
{
// ... more component specific code
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我只需要为超专用组件定义fxml.
此代码仅适用于JavaFX> = 2.1.事先,超类的组件注入不适用于FXMLLoader.
我在github上添加了一个工作示例:https://github.com/matrak/javafx-extend-fxml
| 归档时间: |
|
| 查看次数: |
11279 次 |
| 最近记录: |