我一直在寻找如何在 javafx 中制作 resposnvie 应用程序,通过谷歌搜索,我找到了一种将子节点绑定到其父大小的方法,我不知道这是否是制作响应式设计的正确方法。例如,为了使我使用过的标签具有响应性
Label price=new Label("price");
name.styleProperty().bind(Bindings.concat("-fx-font-size: ",
fontSize.asString(), ";")); //where font size is
fontSize.bind(scene.widthProperty().add(scene.heightProperty()).divide(100));
private DoubleProperty fontSize = new SimpleDoubleProperty(10);
但是今天我找到了另一种方法可以通过使用 jfoenix responsiveHandler 类进行响应式设计,但是作为 java 代码的初学者,我不知道如何将我的 fxml 与此类链接,所以任何人都可以解释如何将我的 fxml 页面与此链接用于制作响应式 javafx 页面的伪类。
JFXResponsiveHandler 类
public class JFXResponsiveHandler {
public static final PseudoClass PSEUDO_CLASS_EX_SMALL = PseudoClass.getPseudoClass("extreme-small-device");
public static final PseudoClass PSEUDO_CLASS_SMALL = PseudoClass.getPseudoClass("small-device");
public static final PseudoClass PSEUDO_CLASS_MEDIUM = PseudoClass.getPseudoClass("medium-device");
public static final PseudoClass PSEUDO_CLASS_LARGE = PseudoClass.getPseudoClass("large-device");
public JFXResponsiveHandler(Stage stage, PseudoClass pseudoClass) {
scanAllNodes(stage.getScene().getRoot(), PSEUDO_CLASS_LARGE);
}
private void scanAllNodes(Parent parent, PseudoClass pseudoClass){
parent.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>
(){
@Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends Node> c) {
while (c.next())
if (!c.wasPermutated() && !c.wasUpdated())
for (Node addedNode : c.getAddedSubList())
if(addedNode instanceof Parent)
scanAllNodes((Parent) addedNode,pseudoClass);
}
});
for (Node component : parent.getChildrenUnmodifiable()) {
if (component instanceof Pane) {
((Pane)component).getChildren().addListener(new ListChangeListener<Node>(){
@Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends Node> c) {
while (c.next()) {
if (!c.wasPermutated() && !c.wasUpdated()) {
for (Node addedNode : c.getAddedSubList()) {
if(addedNode instanceof Parent)
scanAllNodes((Parent) addedNode,pseudoClass);
}
}
}
}
});
//if the component is a container, scan its children
scanAllNodes((Pane) component, pseudoClass);
} else if (component instanceof ScrollPane){
((ScrollPane)component).contentProperty().addListener((o,oldVal,newVal)-> {
scanAllNodes((Parent) newVal,pseudoClass);
});
//if the component is a container, scan its children
if(((ScrollPane)component).getContent() instanceof Parent){
scanAllNodes((Parent) ((ScrollPane)component).getContent(), pseudoClass);
}
} else if (component instanceof Control) {
//if the component is an instance of IInputControl, add to list
((Control)component).pseudoClassStateChanged(PSEUDO_CLASS_EX_SMALL, pseudoClass == PSEUDO_CLASS_EX_SMALL);
((Control)component).pseudoClassStateChanged(PSEUDO_CLASS_SMALL, pseudoClass == PSEUDO_CLASS_SMALL);
((Control)component).pseudoClassStateChanged(PSEUDO_CLASS_MEDIUM, pseudoClass == PSEUDO_CLASS_MEDIUM);
((Control)component).pseudoClassStateChanged(PSEUDO_CLASS_LARGE, pseudoClass == PSEUDO_CLASS_LARGE);
}
}
}
}
我的示例课
public class MainClass extends Application {
@Override
public void start(Stage primaryStage) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("demo.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
scene.widthProperty().addListener(new ChangeListener<Number>() { // i know usually we use this codes to get screen size
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
System.out.println("Width: " + newSceneWidth.doubleValue());
int width=newSceneWidth.intValue();
sc.setWidth(width);
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
System.out.println("Height: " + newSceneHeight);
int height=newSceneHeight.intValue();
sc.setHeight(height); } });
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}}
我的示例 FXML
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button mnemonicParsing="false" text="Hello plese make me responsive" />
<ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="https://www.google.co.in/search?q=imageview&rlz=1C1CHWL_enIN763IN763&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiTo7SxmMDWAhVEtI8KHb-bAIUQ_AUICigB&biw=1366&bih=613#imgrc=-TvmJxWfQMJLQM:" />
</image>
</ImageView>
<Label text="Iam Label Plese make me responsive" />
默认示例 css
.button {
-fx-pref-width: 50px;
-fx-background-color: #44B449;
-fx-background-radius: 50px;`
-fx-pref-height: 50px;
-fx-text-fill: white;
-fx-border-color: WHITE;
-fx-border-radius: 50px;
-fx-border-width: 4px;
}
请任何人解释如何使用我在 vbox、css(小、中、大 - 不知道如何)和 JFXResponsivehandler 类中设计的这个示例 fxml 节点为我以及那些正在寻找在 javaFX 中创建响应式设计的人制作响应式页面。先感谢您。答案将不胜感激。