Fxml Controller: Model View Controller With S W I N G And J F X - Last Part -


Thành viên VIP
(Continue of Fxml Model: Model View Controller With S W I N G And J F X - Part 5 - )

The last part is about the Controller. As you're already familiar with "the Controller" in the previous Parts Controller is applied to regulate and to direct interaction between users and the MVC presentation. In technical term it is the "Dependency Injection" or DI.

What is it, the DI? Normally Java GUI components (AWT, SWING and JFX) consist of Button, Input Field, Label, Panel, Pane, etc. These components are passive -meaning they are "dead" as you so will. Modern Software Technology allows SW designers to prepare some "placeholders" (or for the layman: stencils) so that one could develop his own ideas and insert them into the placeholders. It's a kind of "Pattern Design" in professional jargon. And the Idea insertion is the Dependency Injection. Plain and simple under an abstruse voodoo terminology.

In reality a Button is used by a user to trigger an event (e.g. light on/off, TV on/off, etc.) GUI application is no other thing than a mimicry of reality. To do that Software designer and developer materialize the events with EventListeners that listen to a certain event (e.g. a mouse click on the button surface) and perform the designated action (e.g. sending a sound, etc.)
Structural view
!  event/action   !		 SWING			 !		  JavaFX			!
!  actionEvent	! ActionListener			! onAction				   !
!  keyEvent	   ! KeyListener			   ! onKey....				  !
!  mouseEvent	 ! MouseListener			 ! onMouse...				 !
!  ...			! ...					   ! ...						!
Note: the suffix ... after Onkey or onMouse could be, for example, Pressed
	  -> onKeyPressed or onMousePressed
JFX MVC-Controller can be either an implementation of the interface Initializable or none. However, when FXMLLoader starts to load the model FXML it looks for the Controller (fx:controller="MyController") and tries to find the method initialize() for an eventual user-defined initialization of the JFX components. This initialize() method is optional.

One important aspect is the declaration of public or private or protected. It doesn't matter what attribute you use. It's the matter of using purpose. All "public" methods can be inadvertently interfered by outsiders. Hence it's safe to declare them "private".

JFX variables (i.e. components) and methods that are declared or used in FXML model must be preceded by the annotation @FXML. Otherwise weird exceptions could be thrown. Let's examine the following Controller
public class fxmlFrameController  {
	Button But1;
	TextArea TxtA1;
	TextField TxtF1;
	private boolean on = false;
	private void click( ) {
	  But1.setBackground(new Background(new BackgroundFill(on? Color.YELLOW:Color.LIME,
						 CornerRadii.EMPTY, Insets.EMPTY)));
	  TxtA1.appendText("\nButton was clicked. Color changed to:"+(on?"YELLOW":"GREEN"));
	  on = !on;
	private void read() {
	  TxtA1.appendText("\nName is:"+TxtF1.getText());
	private void initialize() {
	  But1.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY,
This fxmlFrameController uses 3 JFX components declared and instantiated by FXML model (i.e. FXMLLoader): Button But1, TextArea TxtA1 and TextField TxtF1 and 2 "dependency-injected" methods: click() and read(). Both could be declared "public", too.
The method initialize() is nowhere invoked. Neither in the controller, nor in the FXML model (see below), nor in the view (see below). It is discreetly executed by the FXMLLoader. In this case the Button background should have the color yellow at start.

The FXML Model
<AnchorPane id="AnchorPane" fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity"
		  minHeight="-Infinity" minWidth="-Infinity" prefHeight="670.0" prefWidth="380.0"
		  xmlns:fx="https://congdongjava.com/forum/" fx:controller="fxmlFrameController">
  <Label fx:id="Lab1" text = "Please click" prefHeight="50.0" prefWidth="100.0"
		 layoutX="10" layoutY="5" />
  <Button fx:id="But1" onAction="#click" text="JFXButton" prefHeight="50.0" prefWidth="100.0"
		 layoutX="90" layoutY="5" />
  <Label fx:id="Lab2" text = "Name:" prefHeight="30.0" prefWidth="100.0"
		 layoutX="10" layoutY="65" />
  <TextField fx:id="TxtF1" prefWidth="250" prefHeight="30.0" onAction="#read"
		 layoutX="90" layoutY="65" />
  <Label text = "This is an IT man in Background" prefHeight="14.0" prefWidth="200.0"
		 layoutX="56" layoutY="195" />
  <Label fx:id="Lab4" text = "ReportArea" prefHeight="14.0" prefWidth="100.0"
		 layoutX="150" layoutY="460" />
  <TextArea fx:id="TxtA1" prefHeight="165.0" prefWidth="350.0"
		 layoutX="15" layoutY="490" />
	   <URL value="@frame.css" />
and the View
public class FrameFXML extends Application {
  public void start(Stage stage) throws Exception {
	FXMLLoader fxml = new FXMLLoader(getClass().getResource("frame.fxml"));
	AnchorPane root = fxml.load();
	stage.setScene(new Scene(root));
WHY Model-View-Controller? One can brawl about this issue. From the "performance point of view" MVC causes a lot of overheads (dynamic loading and compiling during the start phase) and excessive codes (3 or 4 modules with css). On the other hand, the maintenance and "rapid" development:
- The Model is in plain text. Any enhancement or correction can be done directly without having to recompile the whole package.
- The View is relatively simple. It requires almost NO maintenance.
- The Controller is the part that requires maintenance and "hard work". Most of the enhancements or corrections are done in this part. And -compared to the big "monolithic" codes- it's a "piece of cake".

Nevertheless I have to emphasize that working with MVC requires a lot of GUI development experience. Using IDE (Netbeans, Eclipse, Intellij, etc.) for GUI development at the very beginning is at the first glance very "convenient", but not much GUI experience is gained here.

I hope you've enjoyed this heavy-digesting theme. And since JFX becomes an Open System and if you do have interest on OpenJFX then click HERE