├── .gitignore ├── README.md ├── build.gradle ├── components ├── README.md ├── atom │ ├── button │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── fxcomponents │ │ │ └── atom │ │ │ │ └── button │ │ │ │ ├── ButtonType.java │ │ │ │ └── ButtonView.java │ │ │ └── resources │ │ │ ├── button.css │ │ │ └── plus_sign.png │ ├── datepicker │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── fxcomponents │ │ │ └── atom │ │ │ │ └── datepicker │ │ │ │ ├── DatePickerComponent.java │ │ │ │ └── DatePickerView.java │ │ │ └── resources │ │ │ ├── datepicker.css │ │ │ └── datepicker.fxml │ ├── dropdown │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── fxcomponents │ │ │ └── atom │ │ │ │ └── dropdown │ │ │ │ ├── DropdownComponent.java │ │ │ │ ├── DropdownView.java │ │ │ │ └── DropdownViewModel.java │ │ │ └── resources │ │ │ ├── dropdown.css │ │ │ └── dropdown.fxml │ ├── table │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── fxcomponents │ │ │ └── atom │ │ │ │ └── table │ │ │ │ ├── Column.java │ │ │ │ ├── TableAtomView.java │ │ │ │ ├── TableComponent.java │ │ │ │ └── TableViewModel.java │ │ │ └── resources │ │ │ ├── table.css │ │ │ └── table.fxml │ ├── text │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── fxcomponents │ │ │ └── atom │ │ │ │ └── text │ │ │ │ ├── TextComponent.java │ │ │ │ ├── TextType.java │ │ │ │ ├── TextView.java │ │ │ │ └── TextViewModel.java │ │ │ └── resources │ │ │ └── text.css │ └── textfield │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ ├── fxcomponents │ │ └── atom │ │ │ └── textfield │ │ │ ├── TextFieldComponent.java │ │ │ ├── TextFieldView.java │ │ │ └── TextFieldViewModel.java │ │ └── resources │ │ ├── text_field.css │ │ └── text_field.fxml ├── base │ ├── AComponent.java │ ├── Component.java │ ├── ComponentMountException.java │ ├── ComponentState.java │ ├── ConfigurableComponent.java │ ├── DirectChildrens.java │ ├── EasyBinding.java │ ├── EmptyChecker.java │ ├── FXMLComponent.java │ ├── FXMLParentComponent.java │ ├── FXMLSimpleComponent.java │ ├── FieldErrorException.java │ ├── FieldValidator.java │ ├── FieldView.java │ ├── FieldViewModel.java │ ├── Item.java │ ├── JavaSimpleComponent.java │ ├── MVVMView.java │ ├── MVVMViewModel.java │ ├── Obsolete.java │ ├── ParentComponent.java │ ├── ParentView.java │ ├── Synchronizable.java │ ├── View.java │ ├── ViewModel.java │ ├── ViewModelSynchronisation.java │ └── checker │ │ ├── CINFormatCheck.java │ │ ├── Checker.java │ │ └── NotEmptyCheck.java ├── baseold │ ├── build.gradle │ ├── build │ │ ├── classes │ │ │ └── java │ │ │ │ └── main │ │ │ │ └── mg │ │ │ │ └── fxComponent │ │ │ │ └── base │ │ │ │ ├── AComponent.class │ │ │ │ ├── Component.class │ │ │ │ ├── ComponentRoute.class │ │ │ │ ├── EasyBinding.class │ │ │ │ ├── MVVMView.class │ │ │ │ ├── MVVMViewModel.class │ │ │ │ ├── Synchronizable.class │ │ │ │ ├── View.class │ │ │ │ ├── ViewModel.class │ │ │ │ └── ViewModelSynchronisation.class │ │ ├── libs │ │ │ └── base-0.1.jar │ │ └── tmp │ │ │ ├── compileJava │ │ │ └── previous-compilation-data.bin │ │ │ └── jar │ │ │ └── MANIFEST.MF │ └── src │ │ └── main │ │ └── java │ │ └── mg │ │ └── fxComponent │ │ └── base │ │ ├── AComponent.java │ │ ├── Component.java │ │ ├── ComponentRoute.java │ │ ├── EasyBinding.java │ │ ├── MVVMView.java │ │ ├── MVVMViewModel.java │ │ ├── Synchronizable.java │ │ ├── View.java │ │ ├── ViewModel.java │ │ └── ViewModelSynchronisation.java ├── build.gradle ├── product_item │ ├── build.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── mg │ │ │ └── fxComponent │ │ │ └── productItem │ │ │ ├── ProductItemComponent.java │ │ │ ├── ProductItemVM.java │ │ │ └── ProductItemView.java │ │ └── resources │ │ └── fxml │ │ ├── images │ │ ├── money.png │ │ ├── noodle.png │ │ └── stack.png │ │ └── product_item.fxml └── window │ ├── build.gradle │ └── src │ └── main │ ├── java │ └── mg │ │ └── fxComponent │ │ └── windowComponent │ │ ├── WindowComponent.java │ │ ├── WindowComponentVM.java │ │ └── WindowComponentView.java │ └── resources │ └── fxml │ ├── window.fxml │ └── window_style │ ├── colors.css │ ├── components.css │ └── layout.css ├── core ├── README.md ├── build.gradle └── src │ └── main │ └── java │ └── mg │ └── salesManagement │ └── core │ ├── Main.java │ └── Product.java ├── enma └── src │ └── main │ └── java │ └── fxcomponents │ └── enma │ ├── Button.java │ └── Main.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── previews └── preview.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .settings/ 3 | core/bin/ 4 | core/build/ 5 | components/window/build/ 6 | components/product_item/build/ 7 | components/product_item/bin/ 8 | components/window/bin/ 9 | components/base/bin/ 10 | components/base/build/ 11 | .gradle/ 12 | components/window/.classpath 13 | components/window/.project 14 | components/.classpath 15 | components/.project 16 | components/window/.project 17 | components/window/.classpath 18 | core/.classpath 19 | core/.project 20 | components/base/.classpath 21 | components/base/.project 22 | components/product_item/.classpath 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FxComponents 2 | 3 | A reusable javafx components collection. 4 | 5 | ## About the project 6 | 7 | Reusing our code is a luxury in the code world. In the case of a JavaFx project, 8 | we would like to be able to reuse for example our beautiful login interface, 9 | our custom window, our product add form, ... with their animations, their behavior 10 | without having to rewrite everything. 11 | 12 | We can copy the files that constitute them (our fxml and our controller) but we must 13 | also solve the problems of import which is still an additional annoying task and source of error. 14 | 15 | We would like to be able to reuse our components and enjoy them without 16 | having to rectify anything. For example, in the case of a login component, 17 | we would like to be able to retrieve only the username and password and know 18 | if the user has clicked on the login button or not. Or display an error message 19 | when the information is incorrect without having to touch the view codes. 20 | 21 | We would like to focus only on the logic of this component and not its 22 | behavior because others have already done it for us. 23 | 24 | This will also allow us to divide the tasks during development. While others 25 | will be in charge of creating the interface itself and its behavior, 26 | others will be able to focus on the logic of this view like if the fields are empty, 27 | the error to be displayed should be this, or if the authentication information 28 | is wrong the error should be this. 29 | 30 | This architecture is known as Model View ViewModel or MVVM. 31 | 32 | So how do we make our components as reusable as possible? There are many 33 | solutions but in this project, I use Gradle. 34 | 35 | By isolating each component in a Gradle project, we can isolate each component 36 | perfectly. The components will also be distributable in jar library. 37 | 38 | ## Want a demo? 39 | 40 | Run the following command : 41 | ./gradlew core:run 42 | 43 | ## extract of the components currently created: 44 | ![a window component with some product item components](previews/preview.png) 45 | 46 | The code is open source, you can modify it to your liking. 47 | 48 | See you soon! 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | group 'mg.salesManagement' 3 | version '0.1' 4 | } 5 | 6 | 7 | subprojects { 8 | 9 | plugins { 10 | id 'application' 11 | id 'org.openjfx.javafxplugin' version '0.0.10' 12 | } 13 | 14 | sourceCompatibility = 11 15 | targetCompatibility = 11 16 | 17 | javafx { 18 | version = "16-ea+1" 19 | modules = [ 'javafx.controls', 'javafx.fxml' ] 20 | } 21 | 22 | repositories { 23 | mavenCentral() 24 | } 25 | 26 | application { 27 | mainClass = 'mg.salesManagement.core.Main' 28 | } 29 | 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | Contain all our components. 2 | -------------------------------------------------------------------------------- /components/atom/button/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/atom/button/src/main/fxcomponents/atom/button/ButtonType.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.button; 2 | 3 | 4 | public enum ButtonType { 5 | PRIMARY, SECONDARY, TRANSPARENT, MINI, BORDER_ONLY; 6 | } 7 | -------------------------------------------------------------------------------- /components/atom/button/src/main/fxcomponents/atom/button/ButtonView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.button; 2 | 3 | import javafx.fxml.FXML; 4 | import javafx.scene.control.Button; 5 | import relia.arsf.component.base.View; 6 | 7 | 8 | public class ButtonView extends View { 9 | @FXML private Button button; 10 | 11 | public ButtonView(ButtonViewModel viewModel) { 12 | super(viewModel); 13 | } 14 | 15 | @Override 16 | public void sync_with_view_model() { 17 | sync_text(); 18 | sync_width(); 19 | sync_button_type(); 20 | sync_click(); 21 | } 22 | 23 | private void sync_width() { 24 | this.button.prefWidthProperty().bind( 25 | this.viewModel.width() ); 26 | } 27 | 28 | private void sync_button_type() { 29 | button_type_updated( this.viewModel.button_type().get() ); 30 | 31 | this.viewModel.button_type().addListener((obs, last_button_type, button_type) -> { 32 | if (button_type != null) button_type_updated( button_type ); 33 | }); 34 | } 35 | 36 | private void button_type_updated(ButtonType button_type) { 37 | // use switch instead 38 | if( button_type.equals(ButtonType.MINI) ) convert_to_button_mini(); 39 | if( button_type.equals(ButtonType.SECONDARY) ) convert_to_button_secondary(); 40 | else if( button_type.equals(ButtonType.PRIMARY) ) convert_to_primary_button(); 41 | else if( button_type.equals(ButtonType.TRANSPARENT) ) convert_to_transparent_button(); 42 | else if( button_type.equals(ButtonType.BORDER_ONLY) ) convert_to_border_only_button(); 43 | } 44 | 45 | private void convert_to_button_mini() { 46 | reset_type_style(); 47 | } 48 | 49 | private void convert_to_border_only_button() { 50 | reset_type_style(); 51 | this.button.getStyleClass().add("button-border-only"); 52 | } 53 | 54 | private void convert_to_button_secondary() { 55 | reset_type_style(); 56 | this.button.getStyleClass().add("button-secondary"); 57 | } 58 | 59 | private void convert_to_primary_button() { 60 | reset_type_style(); 61 | this.button.getStyleClass().add("button-primary"); 62 | } 63 | private void convert_to_transparent_button() { 64 | reset_type_style(); 65 | this.button.getStyleClass().add("button-transparent"); 66 | } 67 | 68 | private void reset_type_style() { 69 | this.button.getStyleClass().remove("button-primary"); 70 | this.button.getStyleClass().remove("button-transparent"); 71 | this.button.getStyleClass().remove("button-secondary"); 72 | this.button.getStyleClass().remove("button-border-only"); 73 | } 74 | 75 | 76 | 77 | private void sync_text() { 78 | this.button.textProperty().set(this.viewModel.text().get()); 79 | this.viewModel.text().addListener((obs,old,text) -> { 80 | this.button.setText( text ); 81 | }); 82 | } 83 | 84 | private void sync_click() { 85 | this.button.setOnAction( event -> { 86 | this.viewModel.on_action(); 87 | }); 88 | } 89 | 90 | } 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /components/atom/button/src/main/resources/button.css: -------------------------------------------------------------------------------- 1 | /* Reset */ 2 | .button { 3 | -fx-padding: 0; 4 | -fx-border: none; 5 | -fx-background-color: transparent; 6 | -fx-background-insets: none; 7 | -fx-min-height: 36px; 8 | -fx-pref-height: 36px; 9 | -fx-max-height: 36px; 10 | } 11 | 12 | .button:hover { 13 | -fx-cursor: hand; 14 | } 15 | 16 | 17 | .button-danger { 18 | -fx-border-width: 0; 19 | 20 | -fx-background-color: red; 21 | -fx-background-radius: 5px; 22 | -fx-text-fill: #fafafa; 23 | 24 | -fx-font-weight: bold; 25 | -fx-padding: 0 12px 0 12px; 26 | -fx-content-display: text-only; 27 | } 28 | 29 | .button-primary { 30 | -fx-border-width: 0; 31 | 32 | -fx-background-color: #06C76B; 33 | -fx-background-radius: 5px; 34 | -fx-text-fill: #fafafa; 35 | 36 | -fx-font-weight: bold; 37 | -fx-padding: 0 12px 0 12px; 38 | -fx-content-display: text-only; 39 | } 40 | 41 | .button-secondary { 42 | -fx-border-color: #D6D6D6; 43 | -fx-border-width: 1px; 44 | -fx-border-radius: 5px; 45 | -fx-padding: 0 12px 0 12px; 46 | 47 | -fx-background-color: #FAFAFA; 48 | -fx-background-radius: 5px; 49 | -fx-font-weight: bold; 50 | -fx-content-display: text-only; 51 | } 52 | 53 | .button-transparent { 54 | -fx-border-color: transparent; 55 | -fx-padding: 0 12px 0 12px; 56 | 57 | -fx-background-color: transparent; 58 | -fx-content-display: text-only; 59 | } 60 | 61 | .button-transparent:hover { 62 | -fx-font-weight: bold; 63 | } 64 | 65 | .button-border-only { 66 | -fx-padding: 0 12px 0 12px; 67 | 68 | -fx-background-color: transparent; 69 | -fx-border-color: #D6D6D6; 70 | -fx-content-display: text-only; 71 | 72 | -fx-font-weight: bold; 73 | -fx-border-radius: 5px; 74 | } 75 | 76 | .button-border-only:hover { 77 | -fx-font-weight: bold; 78 | } 79 | -------------------------------------------------------------------------------- /components/atom/button/src/main/resources/plus_sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/atom/button/src/main/resources/plus_sign.png -------------------------------------------------------------------------------- /components/atom/datepicker/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/atom/datepicker/src/main/fxcomponents/atom/datepicker/DatePickerComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.datepicker; 2 | 3 | import java.util.List; 4 | 5 | import javafx.fxml.FXML; 6 | import javafx.scene.control.DatePicker; 7 | import javafx.scene.control.Label; 8 | import relia.arsf.component.base.AComponent; 9 | import relia.arsf.component.base.FXMLComponent; 10 | import relia.arsf.component.base.View; 11 | import relia.arsf.component.base.checker.Checker; 12 | 13 | 14 | @AComponent 15 | public class DatePickerComponent extends FXMLComponent { 16 | 17 | 18 | public DatePickerComponent( String component_name, String label ) { 19 | 20 | super( 21 | component_name, 22 | "/atomes/datepicker/datepicker.fxml", 23 | new DatePickerView(new DatePickerViewModel(label)) 24 | ); 25 | } 26 | 27 | public DatePickerComponent(String component_name, String label, List checkers) { 28 | super( 29 | component_name, 30 | "/atomes/datepicker/datepicker.fxml", 31 | new DatePickerView(new DatePickerViewModel(label, checkers)) 32 | ); 33 | } 34 | 35 | 36 | public boolean check() { 37 | return getViewModel().check(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /components/atom/datepicker/src/main/fxcomponents/atom/datepicker/DatePickerView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.datepicker; 2 | 3 | import javafx.collections.ListChangeListener; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.DatePicker; 6 | import javafx.scene.control.Label; 7 | import relia.arsf.component.base.FieldView; 8 | import relia.arsf.component.base.MVVMView; 9 | 10 | 11 | @MVVMView 12 | public class DatePickerView extends FieldView { 13 | @FXML private DatePicker datepicker; 14 | @FXML private Label label, label_error; 15 | 16 | public DatePickerView(DatePickerViewModel viewModel) { 17 | super(viewModel); 18 | } 19 | 20 | @Override 21 | public void sync_with_view_model() { 22 | update_field_label(); 23 | sync_label(); 24 | sync_error(); 25 | sync_value(); 26 | } 27 | 28 | private void sync_label() { 29 | this.label.textProperty().bind( this.viewModel.label() ); 30 | } 31 | 32 | private void sync_value() { 33 | // from view 34 | 35 | this.datepicker.valueProperty().addListener((obs,old,value) -> { 36 | this.viewModel.setDate(value); 37 | this.viewModel.setValue(value.toString()); 38 | System.out.println("value " + value.toString()); 39 | }); 40 | 41 | // from view model 42 | this.viewModel.dateProperty().addListener((obs,old,value) -> { 43 | this.datepicker.setValue( value ); 44 | }); 45 | } 46 | 47 | public void update_field_label() { 48 | this.label.textProperty().bind( 49 | this.viewModel.label() ); 50 | } 51 | 52 | public void sync_error() { 53 | this.viewModel.getErrors().addListener( 54 | (ListChangeListener) change -> { 55 | show_errors(); 56 | }); 57 | } 58 | 59 | public void show_errors() { 60 | this.label_error.setStyle("-fx-text-fill: red"); 61 | 62 | if ((this.viewModel).getErrors().isEmpty()) { 63 | this.label_error.setText(""); 64 | 65 | } else { 66 | this.viewModel.getErrors().forEach(System.out::println); 67 | this.label_error.setText( this.viewModel.getErrors().get(0)); 68 | } 69 | } 70 | 71 | } 72 | 73 | -------------------------------------------------------------------------------- /components/atom/datepicker/src/main/resources/datepicker.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: lato; 3 | src: url('../fonts/lato/Lato-Bold.ttf'); 4 | } 5 | 6 | .root { 7 | -fx-spacing: 6px; 8 | } 9 | 10 | .text { 11 | -fx-font-family: 'lato'; 12 | } 13 | 14 | .date-picker { 15 | -fx-background-color: transparent; 16 | -fx-background-insents: 0; 17 | -fx-border-color: rgba(29, 28, 29, 0.5); 18 | -fx-border-width: 1px; 19 | -fx-border-radius: 5px; 20 | -fx-pref-height: 36px; 21 | -fx-padding: 0 12px 0 12px; 22 | } 23 | -------------------------------------------------------------------------------- /components/atom/datepicker/src/main/resources/datepicker.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /components/atom/dropdown/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/atom/dropdown/src/main/fxcomponents/atom/dropdown/DropdownComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.dropdown; 2 | 3 | import relia.arsf.component.base.AComponent; 4 | import relia.arsf.component.base.Component; 5 | import relia.arsf.component.base.FXMLComponent; 6 | 7 | 8 | @AComponent 9 | public class DropdownComponent extends FXMLComponent { 10 | 11 | public DropdownComponent(String name) { 12 | super( 13 | name, 14 | "/atomes/dropdown/dropdown.fxml", 15 | new DropdownView(new DropdownViewModel()) 16 | ); 17 | } 18 | 19 | public DropdownComponent(String name, String label) { 20 | super( 21 | name, 22 | "/atomes/dropdown/dropdown.fxml", 23 | new DropdownView(new DropdownViewModel(label)) 24 | ); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /components/atom/dropdown/src/main/fxcomponents/atom/dropdown/DropdownView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.dropdown; 2 | 3 | import javafx.fxml.FXML; 4 | import javafx.scene.control.ComboBox; 5 | import javafx.scene.control.Label; 6 | import relia.arsf.component.base.Item; 7 | import relia.arsf.component.base.MVVMView; 8 | import relia.arsf.component.base.View; 9 | 10 | 11 | @MVVMView 12 | public class DropdownView extends View { 13 | @FXML private Label label; 14 | @FXML private ComboBox combobox; 15 | 16 | 17 | public DropdownView(DropdownViewModel viewModel) { 18 | super(viewModel); 19 | } 20 | 21 | 22 | @Override 23 | public void sync_with_view_model() { 24 | sync_label(); 25 | sync_items(); 26 | sync_selected_item(); 27 | } 28 | 29 | 30 | private void sync_label() { 31 | this.label.textProperty().bind( this.viewModel.label() ); 32 | } 33 | 34 | 35 | private void sync_items() { 36 | this.combobox.setItems( this.viewModel.getItems() ); 37 | } 38 | 39 | 40 | private void sync_selected_item() { 41 | // from view 42 | this.combobox.getSelectionModel().selectedItemProperty().addListener( 43 | (obs, old, selected_item) -> { 44 | System.out.println("[TEST] from view - combox gox selected item changed to " + selected_item); 45 | this.viewModel.setSelected_item( selected_item ); 46 | } 47 | ); 48 | 49 | // from view model 50 | this.viewModel.selected_item().addListener((obs,old, selected_item) -> { 51 | if (selected_item != null) 52 | this.combobox.getSelectionModel().select( selected_item ); 53 | }); 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /components/atom/dropdown/src/main/fxcomponents/atom/dropdown/DropdownViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.dropdown; 2 | 3 | import java.util.List; 4 | 5 | import javafx.beans.property.ObjectProperty; 6 | import javafx.beans.property.SimpleObjectProperty; 7 | import javafx.beans.property.SimpleStringProperty; 8 | import javafx.beans.property.StringProperty; 9 | import javafx.collections.FXCollections; 10 | import javafx.collections.ObservableList; 11 | import relia.arsf.component.base.Item; 12 | import relia.arsf.component.base.MVVMViewModel; 13 | import relia.arsf.component.base.ViewModel; 14 | 15 | 16 | @MVVMViewModel 17 | public class DropdownViewModel extends ViewModel { 18 | private final StringProperty label = new SimpleStringProperty(); 19 | private final ObservableList items = FXCollections.observableArrayList(); 20 | private final ObjectProperty selected_item = new SimpleObjectProperty<>(); 21 | 22 | 23 | public DropdownViewModel() { } 24 | 25 | public DropdownViewModel(String label) { 26 | this.label.set( label ); 27 | } 28 | 29 | 30 | // getters and setters 31 | 32 | public ObservableList getItems() { 33 | return items; 34 | } 35 | 36 | public void setItems(List items) { 37 | this.items.setAll(items); 38 | } 39 | 40 | public ObjectProperty selected_item() { 41 | return selected_item; 42 | } 43 | 44 | public Item geSelected_item() { 45 | return selected_item.get(); 46 | } 47 | 48 | public void setSelected_item(Item item) { 49 | selected_item.set(item); 50 | } 51 | 52 | public StringProperty label() { 53 | return label; 54 | } 55 | 56 | public String getLabel() { 57 | return this.label.get(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /components/atom/dropdown/src/main/resources/dropdown.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: lato; 3 | src: url('../fonts/lato/Lato-Bold.ttf'); 4 | } 5 | 6 | .root { 7 | -fx-spacing: 6px; 8 | } 9 | 10 | .dropdown-label { 11 | -fx-font-family: 'lato'; 12 | -fx-font-weight: bold; 13 | } 14 | 15 | .combo-box { 16 | -fx-background-color: #FAFAFA; 17 | -fx-background-radius: 5px; 18 | -fx-background-insets: 0px; 19 | -fx-min-height: 36px; 20 | -fx-pref-height: 36px; 21 | -fx-max-height: 36px; 22 | 23 | -fx-border-color: #D6D6D6; 24 | -fx-border-width: 1px; 25 | -fx-border-radius: 5px; 26 | } 27 | -------------------------------------------------------------------------------- /components/atom/dropdown/src/main/resources/dropdown.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /components/atom/table/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/atom/table/src/main/fxcomponents/atom/table/Column.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.table; 2 | 3 | 4 | /** 5 | * Column for the table component. 6 | * It associate the column name with the property name 7 | */ 8 | public class Column { 9 | private final int rank; 10 | private final String column_name, property_name; 11 | 12 | public Column(int rank, String column_name, String property_name) { 13 | this.rank = rank; 14 | this.column_name = column_name; 15 | this.property_name = property_name; 16 | } 17 | 18 | // getters 19 | 20 | public int getRank() { 21 | return rank; 22 | } 23 | 24 | public String getColumn_name() { 25 | return column_name; 26 | } 27 | 28 | public String getProperty_name() { 29 | return property_name; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /components/atom/table/src/main/fxcomponents/atom/table/TableAtomView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.table; 2 | 3 | import javafx.collections.ListChangeListener; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.TableColumn; 6 | import javafx.scene.control.TableView; 7 | import javafx.scene.control.cell.PropertyValueFactory; 8 | import relia.arsf.component.base.View; 9 | 10 | 11 | /** 12 | * T represent the type of the table items 13 | */ 14 | 15 | public class TableAtomView extends View> { 16 | @FXML private TableView tableview; 17 | 18 | public TableAtomView(TableViewModel viewModel) { 19 | super(viewModel); 20 | } 21 | 22 | 23 | @Override 24 | public void sync_with_view_model() { 25 | generate_columns(); 26 | sync_items(); 27 | listen_tableview_selected_item(); 28 | } 29 | 30 | 31 | 32 | private void sync_items() { 33 | this.viewModel.getItems().addListener((ListChangeListener) change -> { 34 | // not a good idea but it work 35 | // of course if the size of the items is small 36 | update_table_items(); 37 | }); 38 | } 39 | 40 | private void update_table_items() { 41 | this.tableview.setItems( this.viewModel.getItems() ); 42 | } 43 | 44 | private void listen_tableview_selected_item() { 45 | this.tableview.getSelectionModel().selectedItemProperty().addListener((obs, old, selected) -> { 46 | this.viewModel.selected_item().set(selected); 47 | }); 48 | } 49 | 50 | 51 | /** 52 | * The type of the column is same as the TableView 53 | * and the type of the content is an Object 54 | */ 55 | private void generate_columns() { 56 | this.tableview.getColumns().clear(); 57 | 58 | this.viewModel.getMapping_column_property().forEach( (column) -> { 59 | this.tableview.getColumns().add( create_column(column) ); 60 | }); 61 | } 62 | 63 | 64 | private TableColumn create_column(Column column) { 65 | 66 | TableColumn table_column = new TableColumn<>(); 67 | table_column.setText( column.getColumn_name() ); 68 | table_column.setCellValueFactory( new PropertyValueFactory<>(column.getProperty_name()) ); 69 | 70 | return table_column; 71 | 72 | } 73 | 74 | public TableView getTableview() { 75 | return tableview; 76 | } 77 | 78 | } 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /components/atom/table/src/main/fxcomponents/atom/table/TableComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.table; 2 | 3 | import relia.arsf.component.base.AComponent; 4 | import relia.arsf.component.base.FXMLComponent; 5 | import relia.arsf.component.taskpayer.ItemTaxePayerList; 6 | 7 | import java.util.List; 8 | 9 | import javafx.scene.control.TableView; 10 | 11 | 12 | /** 13 | * T represent the type of the items in 14 | * the table 15 | */ 16 | 17 | @AComponent 18 | public class TableComponent extends FXMLComponent> { 19 | 20 | public TableComponent(String name, List mapping_column_property) { 21 | super( 22 | name, 23 | "/atomes/table/table.fxml", 24 | new TableAtomView( new TableViewModel(mapping_column_property) ) 25 | ); 26 | } 27 | 28 | public TableView getTableview() { 29 | return ((TableAtomView) getView()).getTableview(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /components/atom/table/src/main/fxcomponents/atom/table/TableViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.table; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javafx.beans.property.ObjectProperty; 7 | import javafx.beans.property.SimpleObjectProperty; 8 | import javafx.collections.FXCollections; 9 | import javafx.collections.ObservableList; 10 | import relia.arsf.component.base.MVVMViewModel; 11 | import relia.arsf.component.base.ViewModel; 12 | 13 | 14 | @MVVMViewModel 15 | public class TableViewModel extends ViewModel { 16 | private final List mapping_column_property; 17 | private final ObservableList items = FXCollections.observableArrayList(); 18 | private final ObjectProperty selected_item = new SimpleObjectProperty<>(); 19 | 20 | 21 | public TableViewModel(List mapping_column_property) { 22 | if (mapping_column_property == null) 23 | this.mapping_column_property = new ArrayList<>(); 24 | else this.mapping_column_property = mapping_column_property; 25 | } 26 | 27 | 28 | public void set_columns( List mapping_column_property ) { 29 | this.mapping_column_property.clear(); 30 | this.mapping_column_property.addAll( mapping_column_property ); 31 | } 32 | 33 | 34 | public void set_items(List items) { 35 | this.items.setAll(items); 36 | } 37 | 38 | 39 | // getters 40 | 41 | public List getMapping_column_property() { 42 | return mapping_column_property; 43 | } 44 | 45 | public ObservableList getItems() { 46 | return items; 47 | } 48 | 49 | public ObjectProperty selected_item() { 50 | return selected_item; 51 | } 52 | 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /components/atom/table/src/main/resources/table.css: -------------------------------------------------------------------------------- 1 | .table-view { 2 | -fx-background-color: #f5f5f5; 3 | -fx-background-insets: none; 4 | -fx-background-radius: 4px; 5 | -fx-border-width: 0; 6 | -fx-padding: 20px 0 0 0; 7 | -fx-effect: dropshadow(gaussian, #cecece, 20,0,0,0); 8 | } 9 | 10 | .table-view .label { 11 | -fx-text-fill: black; 12 | } 13 | 14 | .table-view .column-header-background { 15 | -fx-background-color: #ededed; 16 | -fx-border-color: #e3e3e3; 17 | -fx-border-width: 1px 0 1px 0; 18 | -fx-padding: 10px; 19 | } 20 | 21 | .table-view .filler, 22 | .table-view .nested-column-header, 23 | .table-view .column-header { 24 | -fx-background-color: transparent; 25 | } 26 | 27 | 28 | .table-view *.column-header .label { 29 | -fx-font-weight: normal; 30 | -fx-text-fill: #6D6D6D; 31 | } 32 | 33 | .table-view .column-resize-line { 34 | -fx-background-color: red; 35 | } 36 | 37 | .table-view .place-holder { 38 | -fx-background-color: transparent; 39 | } 40 | 41 | /* rows */ 42 | 43 | .table-view .table-row-cell { 44 | -fx-background-color: #fafbff; 45 | } 46 | -------------------------------------------------------------------------------- /components/atom/table/src/main/resources/table.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /components/atom/text/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/atom/text/src/main/fxcomponents/atom/text/TextComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.text; 2 | 3 | import relia.arsf.component.base.AComponent; 4 | import relia.arsf.component.base.Component; 5 | 6 | 7 | @AComponent 8 | public class TextComponent extends Component { 9 | 10 | public TextComponent(String component_name) { 11 | super( component_name, new TextView(new TextViewModel())); 12 | } 13 | 14 | public TextComponent(String component_name, String text, TextType type) { 15 | super(component_name, new TextView(new TextViewModel(text, type))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /components/atom/text/src/main/fxcomponents/atom/text/TextType.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.text; 2 | 3 | 4 | public enum TextType { 5 | SIMPLE, 6 | EMPHASE, 7 | TITLE, 8 | BIG_TITLE 9 | } 10 | -------------------------------------------------------------------------------- /components/atom/text/src/main/fxcomponents/atom/text/TextView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.text; 2 | 3 | import javafx.scene.control.Label; 4 | import relia.arsf.component.base.MVVMView; 5 | import relia.arsf.component.base.View; 6 | 7 | 8 | @MVVMView 9 | public class TextView extends View { 10 | 11 | private final Label text = new Label();; 12 | 13 | public TextView(TextViewModel viewModel) { 14 | super(viewModel); 15 | super.root_node = text; 16 | } 17 | 18 | @Override 19 | public void sync_with_view_model() { 20 | sync_text(); 21 | sync_type(); 22 | sync_alignement(); 23 | } 24 | 25 | private void sync_alignement() { 26 | this.text.alignmentProperty().bind( 27 | this.viewModel.alignment() ); 28 | } 29 | 30 | 31 | private void sync_text() { 32 | this.text.setText( this.viewModel.getText() ); 33 | this.viewModel.text().addListener((obs, old, new_text) -> { 34 | this.text.setText( new_text ); 35 | }); 36 | } 37 | 38 | 39 | private void sync_type() { 40 | update_type( this.viewModel.type().get() ); 41 | 42 | this.viewModel.type().addListener( (obs, old, type) -> { 43 | update_type(type); 44 | }); 45 | } 46 | 47 | 48 | private void update_type(TextType type) { 49 | if (type.equals(TextType.EMPHASE)) to_emphase(); 50 | else if (type.equals(TextType.TITLE)) to_title(); 51 | else if (type.equals(TextType.BIG_TITLE)) to_big_title(); 52 | } 53 | 54 | private void to_emphase() { 55 | this.text.setStyle("-fx-font-weight : bold; -fx-text-fill: #161616;"); 56 | } 57 | 58 | private void to_title() { 59 | this.text.setStyle("-fx-font-weight: bold; -fx-text-fill: #161616; -fx-padding: 18px"); 60 | 61 | // to uppercase 62 | this.text.setText( this.text.getText().toUpperCase() ); 63 | this.text.textProperty().addListener((obs, old, new_text) -> { 64 | this.text.setText(new_text.toUpperCase()); 65 | }); 66 | } 67 | 68 | private void to_big_title() { 69 | this.text.setStyle("-fx-font-size: 36px; -fx-font-weight: medium; -fx-text-fill: #161616; "); 70 | 71 | // to uppercase 72 | this.text.setText( this.text.getText() ); 73 | this.text.textProperty().addListener((obs, old, new_text) -> { 74 | this.text.setText(new_text.toUpperCase()); 75 | }); 76 | } 77 | 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /components/atom/text/src/main/fxcomponents/atom/text/TextViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.text; 2 | 3 | import javafx.beans.property.ObjectProperty; 4 | import javafx.beans.property.SimpleObjectProperty; 5 | import javafx.beans.property.SimpleStringProperty; 6 | import javafx.beans.property.StringProperty; 7 | import javafx.geometry.Pos; 8 | import relia.arsf.component.base.MVVMViewModel; 9 | import relia.arsf.component.base.ViewModel; 10 | 11 | 12 | 13 | @MVVMViewModel 14 | public class TextViewModel extends ViewModel { 15 | 16 | private final StringProperty text = new SimpleStringProperty(); 17 | private final ObjectProperty type = new SimpleObjectProperty<>(TextType.SIMPLE); 18 | private final ObjectProperty alignment = new SimpleObjectProperty<>(Pos.BOTTOM_LEFT); 19 | 20 | 21 | public TextViewModel() { } 22 | 23 | public TextViewModel(String text, TextType type) { 24 | this.text.set( text ); 25 | this.type.set( type ); 26 | } 27 | 28 | 29 | public void setAlignement(Pos alignment) { 30 | this.alignment.set( alignment ); 31 | } 32 | 33 | 34 | // getters and setters 35 | 36 | public String getText() { 37 | return this.text().get(); 38 | } 39 | 40 | public TextType getType() { 41 | return type.get(); 42 | } 43 | 44 | public void setType(TextType type) { 45 | this.type.set(type); 46 | } 47 | 48 | public ObjectProperty type() { 49 | return type; 50 | } 51 | 52 | public void setText(String text) { 53 | this.text.set( text ); 54 | } 55 | 56 | public StringProperty text() { 57 | return this.text; 58 | } 59 | 60 | public ObjectProperty alignment() { 61 | return alignment; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /components/atom/text/src/main/resources/text.css: -------------------------------------------------------------------------------- 1 | .label { 2 | -fx-text-fill: #161616; 3 | } 4 | 5 | .emphase { 6 | -fx-font-weight: bold; 7 | } 8 | 9 | .title { 10 | -fx-font-size: 1.3em; 11 | -fx-font-weight: bold; 12 | -fx-text-fill: #161616; 13 | } 14 | 15 | .title-with-background { 16 | -fx-background-color: rgba(0,0,0,0.2); 17 | -fx-background-radius: 5px; 18 | -fx-padding: 2px 6px; 19 | -fx-font-weight: bold; 20 | } 21 | -------------------------------------------------------------------------------- /components/atom/textfield/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/atom/textfield/src/main/fxcomponents/atom/textfield/TextFieldComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.textfield; 2 | 3 | import java.util.List; 4 | 5 | import relia.arsf.component.base.AComponent; 6 | import relia.arsf.component.base.FXMLComponent; 7 | import relia.arsf.component.base.checker.Checker; 8 | 9 | 10 | @AComponent 11 | public class TextFieldComponent extends FXMLComponent { 12 | 13 | public TextFieldComponent(String name, String label) { 14 | super( 15 | name, 16 | "/atomes/textfield/text_field.fxml", 17 | new TextFieldView( new TextFieldViewModel(label) ) 18 | ); 19 | } 20 | 21 | public TextFieldComponent(String name, String label, List checkers) { 22 | super( 23 | name, 24 | "/atomes/textfield/text_field.fxml", 25 | new TextFieldView( new TextFieldViewModel(label, checkers) ) 26 | ); 27 | } 28 | 29 | public boolean check() { 30 | return getViewModel().check(); 31 | } 32 | 33 | 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /components/atom/textfield/src/main/fxcomponents/atom/textfield/TextFieldView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.textfield; 2 | 3 | import javafx.collections.ListChangeListener; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.TextField; 7 | import relia.arsf.component.base.MVVMView; 8 | import relia.arsf.component.base.View; 9 | 10 | 11 | @MVVMView 12 | public class TextFieldView extends View { 13 | @FXML private TextField text_field; 14 | @FXML private Label label_error, label_textfield; 15 | 16 | 17 | public TextFieldView(TextFieldViewModel viewModel) { 18 | super(viewModel); 19 | } 20 | 21 | 22 | @Override 23 | public void sync_with_view_model() { 24 | update_field_label(); 25 | sync_error(); 26 | sync_textfield(); 27 | } 28 | 29 | 30 | private void sync_textfield() { 31 | // text biderectionnal binding if we can change both side value 32 | // bidirectional binding of textfield text property 33 | 34 | this.text_field.textProperty().addListener((obs,old,text) -> { 35 | this.viewModel.setValue( text ); 36 | }); 37 | 38 | // text binding here 39 | this.viewModel.value().addListener((obs, old, value) -> { 40 | this.text_field.setText(value); 41 | }); 42 | } 43 | 44 | 45 | /** 46 | * Show first error 47 | * */ 48 | public void show_errors() { 49 | this.label_error.setStyle("-fx-text-fill: red"); 50 | 51 | if ((this.viewModel).getErrors().isEmpty()) { 52 | this.label_error.setText(""); 53 | 54 | } else { 55 | this.viewModel.getErrors().forEach(System.out::println); 56 | this.label_error.setText( this.viewModel.getErrors().get(0)); 57 | } 58 | } 59 | 60 | 61 | public void sync_error() { 62 | this.viewModel.getErrors().addListener( 63 | (ListChangeListener) change -> { 64 | show_errors(); 65 | }); 66 | } 67 | 68 | 69 | public void update_field_label() { 70 | this.label_textfield.setText(this.viewModel.getLabel()); 71 | 72 | this.viewModel.label().addListener((obs,old,value)-> { 73 | this.label_textfield.setText(value); 74 | }); 75 | } 76 | 77 | 78 | 79 | } 80 | 81 | 82 | -------------------------------------------------------------------------------- /components/atom/textfield/src/main/fxcomponents/atom/textfield/TextFieldViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.atom.textfield; 2 | 3 | import java.util.List; 4 | 5 | import javafx.beans.property.SimpleStringProperty; 6 | import javafx.beans.property.StringProperty; 7 | import relia.arsf.component.base.FieldViewModel; 8 | import relia.arsf.component.base.checker.Checker; 9 | 10 | 11 | public class TextFieldViewModel extends FieldViewModel { 12 | 13 | public TextFieldViewModel(String label) { 14 | super(label); 15 | } 16 | 17 | public TextFieldViewModel(String label, List checkers) { 18 | super(label, checkers); 19 | } 20 | 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /components/atom/textfield/src/main/resources/text_field.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: lato; 3 | src: url('../fonts/lato/Lato-Bold.ttf'); 4 | } 5 | 6 | .root { 7 | -fx-spacing: 6px; 8 | } 9 | 10 | .textfield-box { 11 | -fx-spacing: 6px; /* tiny */ 12 | } 13 | 14 | .textfield-box .label { 15 | -fx-font-family: 'lato'; 16 | -fx-font-weight: bold; 17 | } 18 | 19 | .textfield-box .text-field { 20 | -fx-background-insets: transparent; 21 | -fx-background-color: transparent; 22 | -fx-border-color: #D6D6D6; 23 | -fx-border-width: 1px; 24 | -fx-border-radius: 5px; 25 | 26 | -fx-padding: 0 12px 0 12px; 27 | -fx-pref-height: 36px; 28 | } 29 | -------------------------------------------------------------------------------- /components/atom/textfield/src/main/resources/text_field.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /components/base/AComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | 7 | /** 8 | * A component is a piece of a reusable view. 9 | * Used to access easly to the View and the ViewModel. 10 | * It's like a factory that create the View instance and 11 | * the ViewModel associate with this. 12 | */ 13 | 14 | @Target(ElementType.TYPE) 15 | public @interface AComponent { 16 | } 17 | -------------------------------------------------------------------------------- /components/base/Component.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | /** 4 | * Super type for all kind of component 5 | */ 6 | 7 | @AComponent 8 | public abstract class Component { 9 | 10 | protected String name; 11 | protected final View view; 12 | protected Object user_data; 13 | 14 | public Component(String name, View view) { 15 | this.name = name; 16 | this.view = view; 17 | this.view.setComponent(this); 18 | } 19 | 20 | /** 21 | * Synchronize the view associate with the 22 | * view model of this component. 23 | * Here we don't do direct action like 24 | * mounting or configuring components children, ... 25 | * */ 26 | public void initialize_component() { 27 | this.view.sync_with_view_model(); 28 | change_component_state_to_ready(); 29 | } 30 | 31 | public void change_component_state_to_ready() { 32 | ((ViewModel) this.view.viewModel).state.set(ComponentState.READY); 33 | if (this.name.equals("Splash screen")) 34 | System.out.println("[i] INFO : state " +this.name+ ": " + ((ViewModel) this.view.viewModel).state.get()); 35 | } 36 | 37 | 38 | public void debug() { 39 | getView().getRoot_node().setStyle("-fx-border-color: red"); 40 | } 41 | 42 | 43 | // getters 44 | 45 | public View getView() { 46 | return this.view; 47 | } 48 | 49 | public ViewModelType getViewModel() { 50 | return this.view.getViewModel(); 51 | } 52 | 53 | public void setUserData(Object object) { 54 | this.user_data = object; 55 | } 56 | 57 | public Object getUserData() { 58 | return user_data; 59 | } 60 | 61 | /** 62 | * Retrun the name of the component 63 | */ 64 | public String getName() { 65 | return this.name; 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return getName(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /components/base/ComponentMountException.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | public class ComponentMountException extends Throwable { 4 | 5 | public ComponentMountException(String message) { 6 | super(message); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /components/base/ComponentState.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | public enum ComponentState { 4 | 5 | /** 6 | * Indicate that the component is not ready 7 | * to receive events and to react to 8 | * it 9 | */ 10 | NOT_YET_READY, 11 | 12 | /** 13 | * Indicate that the component is ready 14 | * to receive events and to react to 15 | * it 16 | */ 17 | READY 18 | 19 | } 20 | -------------------------------------------------------------------------------- /components/base/ConfigurableComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | public interface ConfigurableComponent { 5 | 6 | public void configure_component(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /components/base/DirectChildrens.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | /** 5 | * Used by a component that have 6 | * one or many childrens that need to mount 7 | * directly by default 8 | */ 9 | 10 | public interface DirectChildrens { 11 | 12 | void initialize_childrens(); 13 | 14 | void mount_childrens() throws ComponentMountException; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /components/base/EasyBinding.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import javafx.beans.binding.Bindings; 4 | import javafx.beans.property.BooleanProperty; 5 | import javafx.beans.property.IntegerProperty; 6 | import javafx.beans.property.ObjectProperty; 7 | import javafx.beans.property.StringProperty; 8 | import javafx.scene.control.*; 9 | import javafx.util.converter.NumberStringConverter; 10 | 11 | import java.time.LocalDate; 12 | 13 | 14 | /** 15 | * A easy way to use binding 16 | */ 17 | public abstract class EasyBinding { 18 | /** 19 | * Bind a label text property with another StringProperty 20 | * @param label 21 | * @param bindWith 22 | */ 23 | public static void bindLab(Label label, StringProperty bindWith) { 24 | label.textProperty().bind( bindWith ); 25 | } 26 | 27 | /** 28 | * Bind a label text property with a IntegerProperty 29 | * @param label 30 | * @param bindWith 31 | */ 32 | public static void bindLab(Label label, IntegerProperty bindWith) { 33 | label.textProperty().bind( Bindings.concat(bindWith) ); 34 | } 35 | 36 | /** 37 | * Bind bidirectional a TextField text property with and IntegerProperty 38 | * @param textfield 39 | * @param bindWith 40 | */ 41 | public static void bindBidirecText(TextField textfield, IntegerProperty bindWith) { 42 | Bindings.bindBidirectional( 43 | textfield.textProperty(), 44 | bindWith, 45 | new NumberStringConverter() 46 | ); 47 | } 48 | 49 | /** 50 | * Bind bidirectional a TextField text property with and StringProperty 51 | * @param textfield 52 | * @param bindWith 53 | */ 54 | public static void bindBidirecText(TextField textfield, StringProperty bindWith) { 55 | Bindings.bindBidirectional( 56 | textfield.textProperty(), 57 | bindWith 58 | ); 59 | } 60 | 61 | /** 62 | * Bind bidirectional a DatePicker text property with and ObjectProperty 63 | * @param datePicker 64 | * @param bindWith 65 | */ 66 | public static void bindBidirecTf(DatePicker datePicker, ObjectProperty bindWith) { 67 | Bindings.bindBidirectional( 68 | datePicker.valueProperty(), 69 | bindWith 70 | ); 71 | } 72 | 73 | /** 74 | * Bind bidirectional a PasswordField text property with and StringProperty 75 | * @param passwordField 76 | * @param bindWith 77 | */ 78 | public static void bindBidirecPf(PasswordField passwordField, StringProperty bindWith) { 79 | Bindings.bindBidirectional( 80 | passwordField.textProperty(), 81 | bindWith 82 | ); 83 | } 84 | 85 | /** 86 | * Bind a label text property with a IntegerProperty 87 | * @param button 88 | * @param bindWith 89 | */ 90 | public static void bindDisable(Button button, BooleanProperty bindWith) { 91 | button.disableProperty().bind( bindWith ); 92 | } 93 | 94 | /** 95 | * Bind a label text property with a IntegerProperty 96 | * @param toggle 97 | * @param bindWith 98 | */ 99 | public static void bindDisable(ToggleButton toggle, BooleanProperty bindWith) { 100 | toggle.disableProperty().bind( bindWith ); 101 | } 102 | 103 | /** 104 | * Bind pressed state of the button with given BooleanProperty 105 | * @param button 106 | * @param bindWith 107 | */ 108 | public static void bindPressed(Button button, BooleanProperty bindWith) { 109 | bindWith.bind(button.pressedProperty()); 110 | } 111 | 112 | /** 113 | * Bind pressed state of the toggle button with given BooleanProperty 114 | * @param button 115 | * @param bindWith 116 | */ 117 | public static void bindPressed(ToggleButton button, BooleanProperty bindWith) { 118 | bindWith.bind(button.pressedProperty()); 119 | } 120 | 121 | /** 122 | * Bind visibility of the textfield with the specified BooleanProperty 123 | * @param textfield 124 | * @param bindWith 125 | */ 126 | public static void bindVisibility(TextField textfield, BooleanProperty bindWith) { 127 | textfield.visibleProperty().bind(bindWith); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /components/base/EmptyChecker.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/base/EmptyChecker.java -------------------------------------------------------------------------------- /components/base/FXMLComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.io.IOException; 4 | 5 | import javafx.fxml.FXMLLoader; 6 | 7 | 8 | /** 9 | * FXML component. M represent a ViewModel. 10 | * A component regroupe a View, Path of the view and 11 | * the instance of the node. 12 | * 13 | * Will be obsolte because the method and the synchronsation 14 | * is done by the FXMLView who extend View 15 | */ 16 | 17 | @AComponent 18 | public class FXMLComponent extends Component { 19 | 20 | protected final String view_path; 21 | 22 | public FXMLComponent(String component_name, String view_path, View view) { 23 | super(component_name, view); 24 | this.view_path = view_path; 25 | } 26 | 27 | 28 | @Override 29 | public void initialize_component() { 30 | load_fxml(); 31 | super.initialize_component(); 32 | } 33 | 34 | 35 | /** 36 | * Load the fxml and 37 | * synchronise View (the controller in this case) 38 | * with the ViewModel. 39 | */ 40 | public void load_fxml() { 41 | 42 | FXMLLoader fxml_loader = new FXMLLoader(getClass().getResource(this.view_path)); 43 | fxml_loader.setController(this.view); 44 | 45 | try { 46 | super.view.root_node = fxml_loader.load(); 47 | 48 | } catch (IllegalStateException e) { 49 | System.err.printf("[ERROR] Location '%s' is not set%n", this.view_path); 50 | 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | } 54 | 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /components/base/FXMLParentComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | /** 5 | * A ParentComponent is a Component that 6 | * have on or more Component childrens 7 | */ 8 | 9 | @AComponent 10 | public abstract class FXMLParentComponent extends FXMLComponent { 11 | 12 | public FXMLParentComponent(String name, String view_path, View view) { 13 | super(name, view_path, view); 14 | } 15 | 16 | 17 | @Override 18 | public void initialize_component() { 19 | initialize_childrens(); 20 | mount_childrens(); 21 | } 22 | 23 | public abstract void initialize_childrens(); 24 | 25 | public abstract void mount_childrens(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /components/base/FXMLSimpleComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | @AComponent 5 | public class FXMLSimpleComponent extends FXMLComponent { 6 | 7 | public FXMLSimpleComponent(String name, String view_path, View view) { 8 | super(name, view_path, view); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /components/base/FieldErrorException.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | public class FieldErrorException extends Throwable { 4 | 5 | public FieldErrorException(String message) { 6 | super(message); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /components/base/FieldValidator.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | public enum FieldValidator { 5 | 6 | NOT_EMPTY, 7 | NUMBER_ONLY 8 | 9 | } 10 | -------------------------------------------------------------------------------- /components/base/FieldView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import javafx.collections.ListChangeListener; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.Label; 6 | 7 | 8 | /** 9 | * M represent a FieldViewModel, a super type of ViewModel for 10 | * Field type component 11 | **/ 12 | 13 | public abstract class FieldView extends View { 14 | 15 | 16 | public FieldView(M viewModel) { 17 | super(viewModel); 18 | } 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /components/base/FieldViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javafx.beans.property.SimpleStringProperty; 7 | import javafx.beans.property.StringProperty; 8 | import javafx.collections.FXCollections; 9 | import javafx.collections.ObservableList; 10 | import relia.arsf.component.base.checker.Checker; 11 | 12 | 13 | @MVVMViewModel 14 | public abstract class FieldViewModel extends ViewModel { 15 | 16 | protected final StringProperty label = new SimpleStringProperty("");; 17 | private final StringProperty value = new SimpleStringProperty(""); 18 | protected final StringProperty error_message = new SimpleStringProperty("");; 19 | protected final List checkers = new ArrayList<>(); 20 | protected final ObservableList errors = FXCollections.observableArrayList(); 21 | 22 | 23 | public FieldViewModel(String label) { 24 | this(label, new ArrayList<>()); 25 | } 26 | 27 | public FieldViewModel(String label, List checkers) { 28 | this.label.set(label); 29 | this.checkers.addAll(checkers); 30 | 31 | remove_errors_on_modification(); 32 | } 33 | 34 | 35 | private void remove_errors_on_modification() { 36 | this.value.addListener( val -> { 37 | this.errors.clear(); 38 | }); 39 | } 40 | 41 | /** 42 | * Verify the field value 43 | * and populate error_message with 44 | * the Checker message. 45 | * 46 | * @return true if all ok otherwise false; 47 | * */ 48 | public boolean check() { 49 | this.errors.clear(); 50 | 51 | this.checkers.forEach( checker -> { 52 | checker.check( getValue() ); 53 | 54 | if (!checker.isPassed()) 55 | this.errors.add( checker.getError_message() ); 56 | }); 57 | 58 | return this.errors.isEmpty(); 59 | } 60 | 61 | 62 | 63 | // getters and setters 64 | 65 | public StringProperty label() { 66 | return this.label; 67 | } 68 | 69 | public String getLabel() { 70 | return label.get(); 71 | } 72 | 73 | public void setLabel(String label) { 74 | this.label.set( label ); 75 | } 76 | 77 | 78 | public StringProperty error_messageProperty() { 79 | return error_message; 80 | } 81 | 82 | public String getError_message() { 83 | return error_message.get(); 84 | } 85 | 86 | public void setError_message(String error_message) { 87 | this.error_message.set(error_message); 88 | } 89 | 90 | 91 | public ObservableList getErrors() { 92 | return this.errors; 93 | } 94 | 95 | public String getValue() { 96 | return this.value.get(); 97 | } 98 | 99 | public StringProperty value() { 100 | return value; 101 | } 102 | 103 | public void setValue(String value) { 104 | this.value.set(value); 105 | } 106 | 107 | public List getCheckers() { 108 | return this.checkers; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /components/base/Item.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import javafx.beans.property.ObjectProperty; 4 | import javafx.beans.property.SimpleObjectProperty; 5 | import javafx.beans.property.SimpleStringProperty; 6 | import javafx.beans.property.StringProperty; 7 | 8 | 9 | /** 10 | * Used as item of any list of items. 11 | */ 12 | 13 | public class Item { 14 | 15 | private final StringProperty text = new SimpleStringProperty(); 16 | private final ObjectProperty user_data = new SimpleObjectProperty<>(); 17 | 18 | 19 | public Item() { 20 | this( null, null ); 21 | } 22 | 23 | public Item(String text) { 24 | this( text, null ); 25 | } 26 | 27 | public Item(String text, Object user_data) { 28 | setText( text ); 29 | setUser_data( user_data ); 30 | } 31 | 32 | // getters and setters 33 | 34 | public StringProperty text() { 35 | return text; 36 | } 37 | 38 | public ObjectProperty user_data() { 39 | return user_data; 40 | } 41 | 42 | public String getText() { 43 | return this.text.get(); 44 | } 45 | 46 | public Object getUser_data() { 47 | return this.user_data().get(); 48 | } 49 | 50 | public void setUser_data(Object user_data) { 51 | this.user_data.set( user_data ); 52 | } 53 | 54 | public void setText(String text) { 55 | this.text.set( text ); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return this.text.get(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /components/base/JavaSimpleComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | @AComponent 5 | public class JavaSimpleComponent extends Component { 6 | 7 | public JavaSimpleComponent(String name, View view) { 8 | super(name, view); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /components/base/MVVMView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | 7 | /** 8 | * View of the architecture MVVM. 9 | */ 10 | 11 | @Target(ElementType.TYPE) 12 | public @interface MVVMView { 13 | } 14 | -------------------------------------------------------------------------------- /components/base/MVVMViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | 7 | /** 8 | * MVVMViewModel of pattern MVVM. 9 | * Un view model gere la logique de son vue. 10 | */ 11 | @Target(ElementType.TYPE) 12 | public @interface MVVMViewModel { 13 | } 14 | -------------------------------------------------------------------------------- /components/base/Obsolete.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | 7 | /** 8 | * Indicate that a code is obsolte and 9 | * it will be removed 10 | */ 11 | @Target(ElementType.TYPE) 12 | public @interface Obsolete { 13 | String reason(); 14 | } 15 | -------------------------------------------------------------------------------- /components/base/ParentComponent.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | /** 5 | * A component that can content one or many other components. 6 | * ViewModelType represent the type of the ViewModel. 7 | */ 8 | 9 | @AComponent 10 | public abstract class ParentComponent extends Component { 11 | 12 | public ParentComponent(String name, View view) { 13 | super(name, view); 14 | } 15 | 16 | @Override 17 | public void initialize_component() { 18 | super.initialize_component(); 19 | 20 | initialize_childrens(); 21 | mount_childrens(); 22 | } 23 | 24 | 25 | public abstract void initialize_childrens(); 26 | 27 | public abstract void mount_childrens(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /components/base/ParentView.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import javafx.scene.Parent; 4 | 5 | /** 6 | * ViewModelType represent the type of the ViewModel. 7 | * Parent type represent the type of the main container 8 | * of this parent view. 9 | */ 10 | 11 | public abstract class ParentView extends View { 12 | protected ParentType root_container; 13 | 14 | public ParentView(ViewModelType viewModel, ParentType container) { 15 | super(viewModel); 16 | this.root_container = container; 17 | this.root_node = (Parent) this.root_container; 18 | 19 | configure_container(); 20 | } 21 | 22 | public abstract void configure_container(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /components/base/Synchronizable.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | 4 | /** 5 | * Synchronize and set default state 6 | * of a component 7 | */ 8 | public interface Synchronizable { 9 | 10 | /** 11 | * Initialize synchronisation of all properties. 12 | * For exemple : a property is changed according to the 13 | * state of an another property. 14 | * 15 | * This function must be called before running default 16 | * action. 17 | */ 18 | void synchronize_states(); 19 | 20 | void initialize_default_states(); 21 | } 22 | -------------------------------------------------------------------------------- /components/base/View.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import javafx.scene.Node; 4 | 5 | 6 | /** 7 | * Super class for all view 8 | * @param : M represent a ViewModel Class 9 | */ 10 | 11 | @MVVMView 12 | public abstract class View { 13 | protected M viewModel; 14 | protected Node root_node; 15 | private Component component; 16 | 17 | public View(M viewModel) { 18 | this.viewModel = viewModel; 19 | } 20 | 21 | 22 | /** 23 | * Used to synchronize view Nodes property 24 | * with the view model 25 | */ 26 | public abstract void sync_with_view_model(); 27 | 28 | 29 | // getters 30 | 31 | public M getViewModel() { 32 | return viewModel; 33 | } 34 | 35 | public Node getRoot_node() { 36 | if ( ((ViewModel) this.viewModel).getState().equals(ComponentState.NOT_YET_READY) ) { 37 | System.err.println(String.format("[ERROR] '%s' is not ready, you must initialize it", 38 | getComponent().getName())); 39 | System.exit(1); 40 | } 41 | return this.root_node; 42 | } 43 | 44 | public Component getComponent() { 45 | return component; 46 | } 47 | 48 | public void setComponent(Component component) { 49 | this.component = component; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /components/base/ViewModel.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import javafx.beans.property.ObjectProperty; 4 | import javafx.beans.property.SimpleObjectProperty; 5 | 6 | import static relia.arsf.component.base.ComponentState.*; 7 | 8 | 9 | @MVVMViewModel 10 | public abstract class ViewModel { 11 | 12 | protected final ObjectProperty state = new SimpleObjectProperty<>(); 13 | protected final ObjectProperty user_data = new SimpleObjectProperty<>(); 14 | 15 | 16 | public ViewModel() { 17 | this.state.set(ComponentState.NOT_YET_READY); 18 | } 19 | 20 | // getters 21 | 22 | public ComponentState getState() { 23 | return this.state.get(); 24 | } 25 | 26 | public ObjectProperty state() { 27 | return state; 28 | } 29 | 30 | public ObjectProperty user_data() { 31 | return user_data; 32 | } 33 | 34 | public void setState(ComponentState state) { 35 | this.state.set(state); 36 | } 37 | 38 | public void setUser_data(Object user_data) { 39 | this.user_data.set(user_data); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /components/base/ViewModelSynchronisation.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | /** 7 | * Synchronisation avec le model du vue 8 | */ 9 | @Target(ElementType.METHOD) 10 | public @interface ViewModelSynchronisation { 11 | } 12 | -------------------------------------------------------------------------------- /components/base/checker/CINFormatCheck.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base.checker; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | 7 | public class CINFormatCheck extends Checker { 8 | 9 | public CINFormatCheck() { 10 | super("Format du CIN incorrect"); 11 | } 12 | 13 | @Override 14 | public boolean correct(String message) { 15 | String regex = "[0-9]{12}"; 16 | Pattern pattern = Pattern.compile( regex, Pattern.CASE_INSENSITIVE ); 17 | Matcher matcher = pattern.matcher( message.trim() ); 18 | return matcher.find(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /components/base/checker/Checker.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base.checker; 2 | 3 | import javafx.beans.property.BooleanProperty; 4 | import javafx.beans.property.SimpleBooleanProperty; 5 | 6 | 7 | /** 8 | * Check errors 9 | * */ 10 | public abstract class Checker { 11 | 12 | protected final BooleanProperty passed = new SimpleBooleanProperty(); 13 | protected final String error_message; 14 | 15 | 16 | public Checker(String error_message) { 17 | this.error_message = error_message; 18 | } 19 | 20 | 21 | public void check(String message) { 22 | if (correct(message)) this.passed.set(true); 23 | else this.passed.set(false); 24 | } 25 | 26 | 27 | public abstract boolean correct(String message); 28 | 29 | 30 | // getters 31 | 32 | 33 | public boolean isPassed() { 34 | return this.passed.get(); 35 | } 36 | 37 | public BooleanProperty passedProperty() { 38 | return passed; 39 | } 40 | 41 | public String getError_message() { 42 | return error_message; 43 | } 44 | 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /components/base/checker/NotEmptyCheck.java: -------------------------------------------------------------------------------- 1 | package relia.arsf.component.base.checker; 2 | 3 | 4 | /** 5 | * Check if field is not empty 6 | */ 7 | public class NotEmptyCheck extends Checker { 8 | 9 | 10 | public NotEmptyCheck() { 11 | super("Ce champ est obligatoire"); 12 | } 13 | 14 | 15 | @Override 16 | public boolean correct(String message) { 17 | return !message.isEmpty(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /components/baseold/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.openjfx.javafxplugin' version '0.0.10' 3 | } 4 | 5 | javafx { 6 | version = "16-ea+1" 7 | modules = [ 'javafx.controls', 'javafx.fxml' ] 8 | } 9 | 10 | repositories { 11 | mavenLocal() 12 | mavenCentral() 13 | } 14 | -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/AComponent.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/AComponent.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/Component.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/Component.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/ComponentRoute.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/ComponentRoute.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/EasyBinding.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/EasyBinding.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/MVVMView.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/MVVMView.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/MVVMViewModel.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/MVVMViewModel.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/Synchronizable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/Synchronizable.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/View.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/View.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/ViewModel.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/ViewModel.class -------------------------------------------------------------------------------- /components/baseold/build/classes/java/main/mg/fxComponent/base/ViewModelSynchronisation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/classes/java/main/mg/fxComponent/base/ViewModelSynchronisation.class -------------------------------------------------------------------------------- /components/baseold/build/libs/base-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/libs/base-0.1.jar -------------------------------------------------------------------------------- /components/baseold/build/tmp/compileJava/previous-compilation-data.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/baseold/build/tmp/compileJava/previous-compilation-data.bin -------------------------------------------------------------------------------- /components/baseold/build/tmp/jar/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/AComponent.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | 7 | /** 8 | * A component is a piece of a reusable view 9 | */ 10 | 11 | @Target(ElementType.TYPE) 12 | public @interface AComponent { 13 | } 14 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/Component.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import javafx.fxml.FXMLLoader; 4 | import javafx.scene.Node; 5 | 6 | import java.io.IOException; 7 | 8 | 9 | /** 10 | * FXML component. T represent a ViewModel. 11 | * A component regroupe a View, Path of the view and 12 | * the instance of the node. 13 | */ 14 | public class Component { 15 | 16 | protected final View view; 17 | protected final String viewPath; 18 | private Node node; 19 | private Object user_data; 20 | 21 | public Component(String viewPath, View view) { 22 | this.viewPath = viewPath; 23 | this.view = view; 24 | } 25 | 26 | 27 | /** 28 | * Load the fxml and 29 | * synchronise View (the controller in this case) 30 | * with the ViewModel 31 | */ 32 | public void load() { 33 | 34 | FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(this.viewPath)); 35 | fxmlLoader.setController(this.view); 36 | 37 | try { 38 | this.node = fxmlLoader.load(); 39 | this.view.sync_with_view_model(); 40 | 41 | } catch (IllegalStateException e) { 42 | System.err.printf("[ERROR] Location '%s' is not set%n", this.viewPath); 43 | e.printStackTrace(); 44 | 45 | } catch (IOException e) { 46 | e.printStackTrace(); 47 | } 48 | 49 | } 50 | 51 | 52 | // getters 53 | 54 | public View getView() { 55 | return this.view; 56 | } 57 | 58 | public Node getNode() { 59 | return this.node; 60 | } 61 | 62 | public T getViewModel() { 63 | return this.view.getViewModel(); 64 | } 65 | 66 | public void setUserData(Object object) { 67 | this.user_data = object; 68 | } 69 | 70 | public Object getUserData() { 71 | return user_data; 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/ComponentRoute.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import java.util.HashMap; 4 | 5 | public class ComponentRoute extends HashMap { 6 | 7 | public void add(Object componentName, Component component) { 8 | put(componentName, component); 9 | } 10 | 11 | /** 12 | * Load components, synchronize states and initialize_route default states 13 | */ 14 | public void load_components() { 15 | values().forEach(component -> { 16 | component.load(); 17 | component.getView().sync_with_view_model(); 18 | }); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/EasyBinding.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import javafx.beans.binding.Bindings; 4 | import javafx.beans.property.BooleanProperty; 5 | import javafx.beans.property.IntegerProperty; 6 | import javafx.beans.property.ObjectProperty; 7 | import javafx.beans.property.StringProperty; 8 | import javafx.scene.control.*; 9 | import javafx.util.converter.NumberStringConverter; 10 | 11 | import java.time.LocalDate; 12 | 13 | 14 | /** 15 | * A easy way to use binding 16 | */ 17 | public abstract class EasyBinding { 18 | /** 19 | * Bind a label text property with another StringProperty 20 | * @param label 21 | * @param bindWith 22 | */ 23 | public static void bindLab(Label label, StringProperty bindWith) { 24 | label.textProperty().bind( bindWith ); 25 | } 26 | 27 | /** 28 | * Bind a label text property with a IntegerProperty 29 | * @param label 30 | * @param bindWith 31 | */ 32 | public static void bindLab(Label label, IntegerProperty bindWith) { 33 | label.textProperty().bind( Bindings.concat(bindWith) ); 34 | } 35 | 36 | /** 37 | * Bind bidirectional a TextField text property with and IntegerProperty 38 | * @param textfield 39 | * @param bindWith 40 | */ 41 | public static void bindBidirecText(TextField textfield, IntegerProperty bindWith) { 42 | Bindings.bindBidirectional( 43 | textfield.textProperty(), 44 | bindWith, 45 | new NumberStringConverter() 46 | ); 47 | } 48 | 49 | /** 50 | * Bind bidirectional a TextField text property with and StringProperty 51 | * @param textfield 52 | * @param bindWith 53 | */ 54 | public static void bindBidirecText(TextField textfield, StringProperty bindWith) { 55 | Bindings.bindBidirectional( 56 | textfield.textProperty(), 57 | bindWith 58 | ); 59 | } 60 | 61 | /** 62 | * Bind bidirectional a DatePicker text property with and ObjectProperty 63 | * @param datePicker 64 | * @param bindWith 65 | */ 66 | public static void bindBidirecTf(DatePicker datePicker, ObjectProperty bindWith) { 67 | Bindings.bindBidirectional( 68 | datePicker.valueProperty(), 69 | bindWith 70 | ); 71 | } 72 | 73 | /** 74 | * Bind bidirectional a PasswordField text property with and StringProperty 75 | * @param passwordField 76 | * @param bindWith 77 | */ 78 | public static void bindBidirecPf(PasswordField passwordField, StringProperty bindWith) { 79 | Bindings.bindBidirectional( 80 | passwordField.textProperty(), 81 | bindWith 82 | ); 83 | } 84 | 85 | /** 86 | * Bind a label text property with a IntegerProperty 87 | * @param button 88 | * @param bindWith 89 | */ 90 | public static void bindDisable(Button button, BooleanProperty bindWith) { 91 | button.disableProperty().bind( bindWith ); 92 | } 93 | 94 | /** 95 | * Bind a label text property with a IntegerProperty 96 | * @param toggle 97 | * @param bindWith 98 | */ 99 | public static void bindDisable(ToggleButton toggle, BooleanProperty bindWith) { 100 | toggle.disableProperty().bind( bindWith ); 101 | } 102 | 103 | /** 104 | * Bind pressed state of the button with given BooleanProperty 105 | * @param button 106 | * @param bindWith 107 | */ 108 | public static void bindPressed(Button button, BooleanProperty bindWith) { 109 | bindWith.bind(button.pressedProperty()); 110 | } 111 | 112 | /** 113 | * Bind pressed state of the toggle button with given BooleanProperty 114 | * @param button 115 | * @param bindWith 116 | */ 117 | public static void bindPressed(ToggleButton button, BooleanProperty bindWith) { 118 | bindWith.bind(button.pressedProperty()); 119 | } 120 | 121 | /** 122 | * Bind visibility of the textfield with the specified BooleanProperty 123 | * @param textfield 124 | * @param bindWith 125 | */ 126 | public static void bindVisibility(TextField textfield, BooleanProperty bindWith) { 127 | textfield.visibleProperty().bind(bindWith); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/MVVMView.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | 7 | /** 8 | * View of the architecture MVVM 9 | */ 10 | 11 | @Target(ElementType.TYPE) 12 | public @interface MVVMView { 13 | } 14 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/MVVMViewModel.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | /** 7 | * MVVMViewModel of pattern MVVM. 8 | * Un view model gere la logique de son vue. 9 | * Transmet les actions de gestion de fenetre au ViewOrchestrator. 10 | * 11 | */ 12 | @Target(ElementType.TYPE) 13 | public @interface MVVMViewModel { 14 | } 15 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/Synchronizable.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | 4 | /** 5 | * Synchronize and set default state 6 | * of a component 7 | */ 8 | public interface Synchronizable { 9 | 10 | /** 11 | * Initialize synchronisation of all properties. 12 | * For exemple : a property is changed according to the 13 | * state of an another property. 14 | * 15 | * This function must be called before running default 16 | * action. 17 | */ 18 | void synchronize_states(); 19 | 20 | void initialize_default_states(); 21 | } 22 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/View.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | 4 | 5 | /** 6 | * Super class for all controller 7 | * @param : T represent a ViewModel Class 8 | */ 9 | 10 | @MVVMView 11 | public abstract class View { 12 | protected T viewModel; 13 | 14 | public View(T viewModel) { 15 | this.viewModel = viewModel; 16 | } 17 | 18 | 19 | @ViewModelSynchronisation 20 | public abstract void sync_with_view_model(); 21 | 22 | 23 | // getters 24 | 25 | public T getViewModel() { 26 | return viewModel; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/ViewModel.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | 4 | @MVVMViewModel 5 | public abstract class ViewModel { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /components/baseold/src/main/java/mg/fxComponent/base/ViewModelSynchronisation.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | /** 7 | * Synchronisation avec le model du vue 8 | */ 9 | @Target(ElementType.METHOD) 10 | public @interface ViewModelSynchronisation { 11 | } 12 | -------------------------------------------------------------------------------- /components/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':components:base') 3 | } 4 | -------------------------------------------------------------------------------- /components/product_item/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.openjfx.javafxplugin' version '0.0.10' 3 | } 4 | 5 | javafx { 6 | version = "16-ea+1" 7 | modules = [ 'javafx.controls', 'javafx.fxml' ] 8 | } 9 | 10 | repositories { 11 | mavenLocal() 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation project(':components:baseold') 17 | } 18 | -------------------------------------------------------------------------------- /components/product_item/src/main/java/mg/fxComponent/productItem/ProductItemComponent.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.productItem; 2 | 3 | 4 | import mg.fxComponent.base.Component; 5 | 6 | public class ProductItemComponent extends Component { 7 | 8 | public ProductItemComponent( 9 | String name, 10 | String price, 11 | String quantity_available, 12 | int quantity_selected) { 13 | 14 | super( "/fxml/product_item.fxml", 15 | new ProductItemView( 16 | new ProductItemVM( 17 | name, 18 | price, 19 | quantity_available, 20 | quantity_selected 21 | ) 22 | ) 23 | ); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /components/product_item/src/main/java/mg/fxComponent/productItem/ProductItemVM.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.productItem; 2 | 3 | import javafx.beans.property.*; 4 | import mg.fxComponent.base.MVVMView; 5 | import mg.fxComponent.base.ViewModel; 6 | 7 | 8 | @MVVMView 9 | public class ProductItemVM extends ViewModel { 10 | private final StringProperty name; 11 | private final StringProperty price; 12 | private final StringProperty quantity_available; 13 | private final IntegerProperty quantity_selected; 14 | private BooleanProperty quantity_selected_visible; 15 | private final BooleanProperty root_container_pressed = new SimpleBooleanProperty(); 16 | 17 | 18 | public ProductItemVM( 19 | String name, String price, String quantity_available) { 20 | 21 | this(name, price, quantity_available, 0, false); 22 | } 23 | 24 | public ProductItemVM( 25 | String name, String price, String quantity_available, int quantity_selected) { 26 | 27 | this(name, price, quantity_available, quantity_selected, false); 28 | } 29 | 30 | public ProductItemVM( 31 | String name, String price, String quantity_available, int quantity_selected, boolean quantity_visible) { 32 | 33 | this.name = new SimpleStringProperty(name); 34 | this.price = new SimpleStringProperty(price); 35 | this.quantity_available = new SimpleStringProperty(quantity_available); 36 | this.quantity_selected = new SimpleIntegerProperty(quantity_selected); 37 | this.quantity_selected_visible = new SimpleBooleanProperty(quantity_visible); 38 | } 39 | 40 | 41 | // getters 42 | 43 | public StringProperty nameProperty() { 44 | return name; 45 | } 46 | 47 | public StringProperty priceProperty() { 48 | return price; 49 | } 50 | 51 | public StringProperty quantity_availableProperty() { 52 | return quantity_available; 53 | } 54 | 55 | public IntegerProperty quantity_selectedProperty() { 56 | return quantity_selected; 57 | } 58 | 59 | public BooleanProperty onRootContainerPressed() { 60 | return root_container_pressed; 61 | } 62 | 63 | public BooleanProperty quantity_selected_visibleProperty() { 64 | return quantity_selected_visible; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /components/product_item/src/main/java/mg/fxComponent/productItem/ProductItemView.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.productItem; 2 | 3 | import javafx.fxml.FXML; 4 | import javafx.scene.control.Label; 5 | import javafx.scene.image.ImageView; 6 | import javafx.scene.layout.AnchorPane; 7 | import javafx.scene.layout.StackPane; 8 | import mg.fxComponent.base.EasyBinding; 9 | import mg.fxComponent.base.View; 10 | 11 | 12 | public class ProductItemView extends View { 13 | @FXML private ImageView img_product; 14 | @FXML private Label lab_name; 15 | @FXML private Label lab_rest; 16 | @FXML private Label lab_price; 17 | @FXML private Label lab_count; 18 | @FXML private StackPane counter_container; 19 | @FXML private AnchorPane root_container; 20 | 21 | public ProductItemView(ProductItemVM viewModel) { 22 | super(viewModel); 23 | } 24 | 25 | @Override 26 | public void sync_with_view_model() { 27 | sync_name(); 28 | sync_rest(); 29 | sync_price(); 30 | sync_count(); 31 | sync_counter_container_visibilty(); 32 | sync_root_container_clicked(); 33 | } 34 | 35 | private void sync_counter_container_visibilty() { 36 | this.counter_container.visibleProperty().bind( 37 | this.viewModel.quantity_selected_visibleProperty()); 38 | } 39 | 40 | private void sync_root_container_clicked() { 41 | this.root_container.pressedProperty().addListener((obs, old, pressed) -> { 42 | this.viewModel.onRootContainerPressed().set(pressed); 43 | }); 44 | } 45 | 46 | private void sync_name() { 47 | EasyBinding.bindLab(this.lab_name, this.viewModel.nameProperty()); 48 | } 49 | 50 | private void sync_rest() { 51 | EasyBinding.bindLab(this.lab_rest, this.viewModel.quantity_availableProperty()); 52 | } 53 | 54 | private void sync_price() { 55 | EasyBinding.bindLab(this.lab_price, this.viewModel.priceProperty()); 56 | } 57 | 58 | private void sync_count() { 59 | EasyBinding.bindLab(this.lab_count, this.viewModel.quantity_selectedProperty()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /components/product_item/src/main/resources/fxml/images/money.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/product_item/src/main/resources/fxml/images/money.png -------------------------------------------------------------------------------- /components/product_item/src/main/resources/fxml/images/noodle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/product_item/src/main/resources/fxml/images/noodle.png -------------------------------------------------------------------------------- /components/product_item/src/main/resources/fxml/images/stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryharim/FxComponents/25fc221b428124a88f84d40ecef399caffc20774/components/product_item/src/main/resources/fxml/images/stack.png -------------------------------------------------------------------------------- /components/product_item/src/main/resources/fxml/product_item.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /components/window/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.openjfx.javafxplugin' version '0.0.10' 3 | } 4 | 5 | javafx { 6 | version = "16-ea+1" 7 | modules = [ 'javafx.controls', 'javafx.fxml' ] 8 | } 9 | 10 | repositories { 11 | mavenLocal() 12 | } 13 | 14 | dependencies { 15 | implementation project(':components:baseold') 16 | } 17 | -------------------------------------------------------------------------------- /components/window/src/main/java/mg/fxComponent/windowComponent/WindowComponent.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.windowComponent; 2 | 3 | 4 | import mg.fxComponent.base.Component; 5 | 6 | public class WindowComponent extends Component { 7 | 8 | public WindowComponent() { 9 | super("/fxml/window.fxml", 10 | new WindowComponentView(new WindowComponentVM()) 11 | ); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /components/window/src/main/java/mg/fxComponent/windowComponent/WindowComponentVM.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.windowComponent; 2 | 3 | import javafx.beans.property.*; 4 | import javafx.scene.Node; 5 | import mg.fxComponent.base.MVVMViewModel; 6 | import mg.fxComponent.base.ViewModel; 7 | 8 | 9 | @MVVMViewModel 10 | public class WindowComponentVM extends ViewModel { 11 | private final BooleanProperty pressed_close_button = new SimpleBooleanProperty(); 12 | private final ObjectProperty content = new SimpleObjectProperty<>(); 13 | private final ObjectProperty current_popup = new SimpleObjectProperty<>(); 14 | private final StringProperty username = new SimpleStringProperty(); 15 | 16 | 17 | public void show_popup(Node node) { 18 | this.current_popup.set(node); 19 | } 20 | 21 | public void close_popup() { 22 | this.current_popup.set(null); 23 | } 24 | 25 | 26 | // getters 27 | 28 | public BooleanProperty pressed_close_button() { 29 | return pressed_close_button; 30 | } 31 | 32 | public ObjectProperty current_popup() { 33 | return current_popup; 34 | } 35 | 36 | public ObjectProperty content() { 37 | return content; 38 | } 39 | 40 | public StringProperty usernameProperty() { 41 | return username; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /components/window/src/main/java/mg/fxComponent/windowComponent/WindowComponentView.java: -------------------------------------------------------------------------------- 1 | package mg.fxComponent.windowComponent; 2 | 3 | import javafx.fxml.FXML; 4 | import javafx.scene.Node; 5 | import javafx.scene.control.Button; 6 | import javafx.scene.control.Label; 7 | import javafx.scene.layout.*; 8 | import mg.fxComponent.base.MVVMView; 9 | import mg.fxComponent.base.View; 10 | 11 | 12 | @MVVMView 13 | public class WindowComponentView extends View { 14 | @FXML private Button close_window_button, 15 | button_add, 16 | minimize_window_button, 17 | maximize_window_button; 18 | 19 | @FXML private Label lab_username, lab_deconnexion; 20 | 21 | @FXML private StackPane root; 22 | @FXML private Pane content; 23 | 24 | 25 | public WindowComponentView(WindowComponentVM viewModel) { 26 | super(viewModel); 27 | } 28 | 29 | @Override 30 | public void sync_with_view_model() { 31 | sync_username(); 32 | 33 | sync_close_window_pressed_state(); 34 | 35 | sync_content(); 36 | sync_current_popup(); 37 | } 38 | 39 | private void sync_username() { 40 | this.viewModel.usernameProperty().addListener((obs, old, actual_username) -> { 41 | this.lab_username.setText(actual_username); 42 | }); 43 | } 44 | 45 | 46 | private void sync_close_window_pressed_state() { 47 | this.viewModel.pressed_close_button().bind( 48 | this.close_window_button.pressedProperty()); 49 | } 50 | 51 | 52 | // root content 53 | 54 | private void sync_content() { 55 | this.viewModel.content().addListener((obs, old, content_node) -> { 56 | if (content_node != null) show_content(content_node); 57 | }); 58 | } 59 | 60 | private void show_content(Node node) { 61 | HBox.setHgrow(node, Priority.ALWAYS); 62 | this.content.getChildren().setAll(node); 63 | } 64 | 65 | 66 | // popup 67 | 68 | private void sync_current_popup() { 69 | this.viewModel.current_popup().addListener((obs, old, current_popup) -> { 70 | if (current_popup != null) showPopup(current_popup); 71 | else close_popup(); 72 | }); 73 | } 74 | 75 | 76 | private void showPopup(Node current_popup) { 77 | this.root.getChildren().add(1, current_popup); 78 | } 79 | 80 | private void close_popup() { 81 | this.root.getChildren().remove(1); 82 | } 83 | 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /components/window/src/main/resources/fxml/window.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | 42 | 43 | 44 |