Use a custom MVC pattern with a lot of convenient tricks
The User Interface layer is composed by three main components :
Each of these must do predefined tasks to maintain a good Separation of Concerns (SoC).
Short UML Diagram:
Models are directly synchronized with the UIFacade and can send & receive Waves, they can also use any other components.
The goal of Models is to retrieve data from other layers, and to define Business Logic (business rules, authorizations ...).
The Model automatically build its attached view.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | public final class SampleModel extends DefaultModel<SampleModel, SampleView> { /** The class logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(SampleModel. class ); /** * {@inheritDoc} */ @Override protected void initModel() { LOGGER.debug( "Init Sample Model" ); // Put the code to initialize your model here } /** * {@inheritDoc} */ @Override protected void initInnerModels() { // Put the code to initialize inner models here (if any) } /** * {@inheritDoc} */ @Override protected void bind() { // Put the code to manage model object binding (if any) } /** * {@inheritDoc} */ @Override protected void processWave( final Wave wave) { // Process a wave action, you must listen the wave type before } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | package org.jrebirth.af.sample.ui; import javafx.scene.control.Button; import javafx.scene.control.LabelBuilder; import javafx.scene.layout.BorderPane; import javafx.scene.layout.FlowPaneBuilder; import org.jrebirth.af.core.exception.CoreException; import org.jrebirth.af.core.ui.AbstractView; import org.jrebirth.af.core.ui.annotation.OnMouse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The class <strong>SampleView</strong>. * * @author */ public final class SampleView extends AbstractView<SampleModel, BorderPane, SampleController> { /** The class logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(SampleView. class ); /** Button used to trigger the SampleCommand. */ @OnMouse (OnMouse.MouseType.Clicked) private Button defaultCommand; /** Button used to trigger the SampleUICommand. */ private Button uiCommand; /** Button used to trigger the SamplePoolCommand. */ private Button pooledCommand; /** * Default Constructor. * * @param model the controls view model * * @throws CoreException if build fails */ public SampleView( final SampleModel model) throws CoreException { super (model); } /** * {@inheritDoc} */ @Override protected void initView() { this .defaultCommand = new Button( "Trigger a default Command into JIT" ); this .uiCommand = new Button( "Trigger an UI Command into JAT" ); this .pooledCommand = new Button( "Trigger a pooled Command into JTP" ); getRootNode().setCenter( LabelBuilder.create() .text( "JRebirth Sample" ) .build() ); getRootNode().setBottom(FlowPaneBuilder.create().children( this .defaultCommand, this .uiCommand, this .pooledCommand ).build()); } /** * {@inheritDoc} */ @Override public void start() { LOGGER.debug( "Start the Sample View" ); // Custom code to process when the view is displayed the first time } /** * {@inheritDoc} */ @Override public void reload() { LOGGER.debug( "Reload the Sample View" ); // Custom code to process when the view is displayed the 1+n time } /** * {@inheritDoc} */ @Override public void hide() { LOGGER.debug( "Hide the Sample View" ); // Custom code to process when the view is hidden } /** * Return the button that trigger the default command. * * @return the button that trigger the default command */ Button getDefaultCommand() { return this .defaultCommand; } /** * Return the button that trigger the UI command. * * @return the button that trigger the UI command */ Button getUiCommand() { return this .uiCommand; } /** * Return the button that trigger the pooled command. * * @return the button that trigger the pooled command */ Button getPooledCommand() { return this .pooledCommand; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | package org.jrebirth.af.sample.ui; import javafx.scene.input.MouseEvent; import org.jrebirth.af.core.exception.CoreException; import org.jrebirth.af.core.ui.AbstractController; import org.jrebirth.af.core.ui.adapter.DefaultMouseAdapter; import org.jrebirth.af.core.wave.WaveBuilder; import org.jrebirth.af.core.wave.WaveGroup; import org.jrebirth.af.sample.command.SampleCommand; import org.jrebirth.af.sample.command.SamplePoolCommand; import org.jrebirth.af.sample.command.SampleUICommand; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The class <strong>SampleController</strong>. * * @author */ public final class SampleController extends AbstractController<SampleModel, SampleView> { /** The class logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(SampleController. class ); /** * Default Constructor. * * @param view the view to control * * @throws CoreException if an error occurred while creating event handlers */ public SampleController( final SampleView view) throws CoreException { super (view); } /** * {@inheritDoc} */ @Override protected void initEventAdapters() throws CoreException { // Manage Ui Command Button linkCommand(getView().getUiCommand(), MouseEvent.MOUSE_CLICKED, SampleUICommand. class ); // Use the inner class addAdapter( new SampleMouseAdapter()); } /** * {@inheritDoc} */ @Override protected void initEventHandlers() throws CoreException { // Listen events // Manage Pooled Command Button getView().getPooledCommand().setOnMouseClicked(getHandler(MouseEvent.MOUSE_CLICKED)); } /** * Manage Mouse click of widget that have annotation. * * @param event the mouse event */ void onMouseClicked( final MouseEvent event) { LOGGER.debug( "MouseClicked => Call Sample Command" ); // Manage Default Command Button getModel().getCommand(SampleCommand. class ).run(); } /** * The class <strong>SampleMouseAdapter</strong>. */ private class SampleMouseAdapter extends DefaultMouseAdapter<SampleController> { @Override public void mouseClicked( final MouseEvent mouseEvent) { super .mouseClicked(mouseEvent); LOGGER.debug( "MouseClicked => Call Sample Pool Command" ); getModel().sendWave( WaveBuilder.create() .waveGroup(WaveGroup.CALL_COMMAND) .relatedClass(SamplePoolCommand. class ) .build() ); } } } |