MVC(Model View Controller)设计模式在JavaFX中有着比Swing更好的表现方式。它使得程序界面设计和程序逻辑设计完全分开,便于代码的可读性和以后的可维护性。例子:
<?xml version="1.0" encoding="UTF-8"?>
<?language javascript?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.Scene?>
<!-- "id" serves to CSS, "fx:id" serves to controller(java or js) and CSS -->
<Scene xmlns:fx="http://javafx.com/fxml" width="300" height="275">
<fx:script source="info.js"/>
<GridPane styleClass="grid-pane">
<Text styleClass="welcome-text" text="%welcome"
GridPane.columnIndex="0" GridPane.rowIndex="0"
GridPane.columnSpan="2"/>
<Label text="%userName"
GridPane.columnIndex="0" GridPane.rowIndex="1"/>
<TextField
GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Label text="%password"
GridPane.columnIndex="0" GridPane.rowIndex="2"/>
<PasswordField
GridPane.columnIndex="1" GridPane.rowIndex="2"
onAction="#handlePFAction"/>
<HBox styleClass="h-box"
GridPane.columnIndex="1" GridPane.rowIndex="4">
<Button fx:id="submitButton" text="%signIn"
onAction="#handleSubmitButtonAction"/>
</HBox>
<Text fx:id="actionTarget"
GridPane.columnIndex="1" GridPane.rowIndex="6"/>
<!-- <gridLinesVisible>true</gridLinesVisible> -->
</GridPane>
<fx:script>
var System = java.lang.System;
var message = "this is the end of XML contents";
System.out.println(message);
</fx:script>
</Scene>
/* applies to the root node of Scene, it can specify global common properties */
.root {
-fx-background-image: url("background.jpg");
}
.label {
-fx-font-size: 12px;
-fx-font-weight: bold;
-fx-text-fill: #333333;
-fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );
}
.button {
-fx-text-fill: white;
-fx-font-family: "Arial Narrow";
-fx-font-weight: bold;
-fx-background-color: linear-gradient(#61a2b1, #2A5058);
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5,0,0,1 );
}
.button:hover, .button:armed { /* pseudo-classes */
-fx-background-color: linear-gradient(#2A5058, #61a2b1);
}
.grid-pane {
-fx-hgap: 10;
-fx-vgap: 10;
-fx-alignment: center;
-fx-grid-lines-visible: false;
-fx-padding: 25 25 10 25;
}
.h-box {
-fx-spacing: 10;
-fx-alignment: bottom-right;
}
.welcome-text {
-fx-font-size: 32px;
-fx-font-family: "Arial Black";
-fx-fill: #818181;
-fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7), 6,0,0,2 );
}
#actionTarget {
-fx-fill: FIREBRICK;
-fx-font-weight: bold;
-fx-effect: dropshadow( gaussian, rgba(255,255,255,0.5), 0,0,0,1 );
}
// Provide some necessary infos
importClass(java.lang.System);
var info = "starts loading of XML file";
System.out.println(info);
# This is a default resource bundle when a searching in getBundle() with the
# given locale fails.
title=Welcome FXML
welcome=Welcome
userName=User Name:
password=Password:
signIn=Sign In
actionTarget=Sign in button pressed
# This is a Chinese resource bundle. It is encoded by ISO-8859-1. In this case,
# characters that cannot be directly represented in ISO-8859-1 encoding can be
# written using Unicode escapes as defined in section 3.3 of The Java\u2122
# Language Specification.
title=\u6B22\u8FCEFXML
welcome=\u6B22\u8FCE
userName=\u7528\u6237\u540D\uFF1A
password=\u5BC6\u7801\uFF1A
signIn=\u767B\u9646
actionTarget=\u767B\u9646\u6309\u94AE\u88AB\u6309\u4E0B
# This is a en_US resource bundle.
title=Welcome FXML
welcome=Welcome
userName=User Name:
password=Password:
signIn=Sign In
actionTarget=Sign in button pressed
# This is a fr_FR resource bundle.
title=Bienvenue FXML
welcome=Bienvenue
userName=Identifiant:
password=Mot de Passe:
signIn=Se connecter
actionTarget=Bouton appuyé
package loginfxml;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.PauseTransition;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.text.Text;
import javafx.util.Duration;
/**
* It is often preferable to define more complex application logic in a
* compiled, strongly-typed language such as Java. For example, some complex
* event handlers and any other application logic.
* <p>
* It implements an <code>Initializable</code> interface, which defines
* <code>an initialize()</code> method. It will be called once on an
* implementing controller when the contents of its associated document have
* been completely loaded. It allows the implementing class to perform any
* necessary post-processing on the content.
*
* @author HAN
*
*/
public class Controller implements Initializable {
// If the controller member fields or methods are private or protected, it
// should be annotated so as to be accessible to markup. If they are public,
// the javafx.fxml.FXML annotation is not necessary.
@FXML
private Button submitButton;
@FXML
private Text actionTarget;
private ResourceBundle resources;
@FXML
private void handlePFAction() {
PauseTransition pressTime = new PauseTransition(Duration.millis(220));
pressTime.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
submitButton.disarm();
submitButton.fire();
}
});
submitButton.arm();
pressTime.play();
}
@FXML
private void handleSubmitButtonAction() {
actionTarget.setText(resources.getString("actionTarget"));
}
@Override
public void initialize(URL location, ResourceBundle resources) {
System.out.println("location: " + location);
System.out.println("resources: " + resources);
this.resources = resources;
System.out.println("to perform any necessary post-processing on the "
+ "content, which will be called once when the contents of "
+ "its associated document have been completely loaded");
// For example, to process lookup() method with the given CSS selector,
// which normally in java code should be placed after Stage.show(). Note
// that the button defined in FXML can not be invoked in Model java code
// file which is proven by my practice.
System.out.println("name of submit button: " + submitButton.getText());
System.out.println(submitButton.lookupAll(".button"));
Button button = (Button) submitButton.lookup(".button");
button.setText("Sign in");
System.out.println("new name of submit button: "
+ submitButton.getText());
}
}
package loginfxml;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Model extends Application {
public static void main(String[] args) {
System.out.println("程序首先执行的入口:" + Arrays.toString(args));
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Locale locale = getCurrentLocale();
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(Model.class.getResource("View.fxml"));
ResourceBundle resources = ResourceBundle.getBundle(
"loginfxml/MyResources", locale, Model.class.getClassLoader());
fxmlLoader.setResources(resources);
fxmlLoader.setController(new Controller());
Scene scene = (Scene) fxmlLoader.load();
scene.getStylesheets().add(
Model.class.getResource("login.css").toExternalForm());
stage.setTitle(resources.getString("title"));
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
private Locale getCurrentLocale() {
Map<String, String> namedParams = getParameters().getNamed();
String languageParam = namedParams.get("language");
String countryParam = namedParams.get("country");
Locale locale = Locale.getDefault();
if (languageParam != null && languageParam.trim().length() > 0) {
if (countryParam != null && countryParam.trim().length() > 0) {
locale = new Locale(languageParam.trim(), countryParam.trim());
} else {
locale = new Locale(languageParam.trim());
}
}
return locale;
}
}
所有资源下载链接:
运行结果(注:在命令行中设置语言包,或者在你的JNLP文件中设置以便Applet或者WebStart应用):