Skip to content
Snippets Groups Projects
Commit f8ecfcfa authored by Tiziano Munaro's avatar Tiziano Munaro
Browse files

[UI] Introduce new composite JavaFX layout mechanism

'ICompositeFXController' is introduced as a generic interface JavaFX
controllers which can be hierarchically composed. This interface is
implemented by the 'CompositeFXControllerBase' as well as by the
'AF3FXViewPart'. Parent classes then have to specify how to include the
children within their container by implementing the 'addContainments'
method defined by the interface.

Issue-Ref: 3437
Issue-Url: https://af3-developer.fortiss.org/issues/3437



Signed-off-by: default avatarTiziano Munaro <munaro@fortiss.org>
parent 666c88a3
No related branches found
No related tags found
1 merge request!823437
AF3FXViewPart.java 03924bbf64aaaee3faee7bc913c6694d7038d01b YELLOW
AF3FXViewPart.java d849a51e96181629b6adab841410aa1b1a10dbe7 YELLOW
......@@ -24,7 +24,7 @@ import java.util.ResourceBundle;
import org.apache.commons.lang3.SystemUtils;
import org.eclipse.fx.ui.workbench3.FXViewPart;
import org.eclipse.ui.part.ViewPart;
import org.fortiss.tooling.common.ui.javafx.layout.ICompositeFXController;
import javafx.application.Platform;
import javafx.fxml.Initializable;
......@@ -39,78 +39,56 @@ import javafx.scene.layout.Pane;
*
* @author diewald
*/
public abstract class AF3FXViewPart extends FXViewPart implements Initializable {
public abstract class AF3FXViewPart extends FXViewPart implements ICompositeFXController, Initializable {
/** For later use, if we need to define different styles. */
private String cssLocation;
/** Flag that indicates if a custom style sheet has been applied. */
private boolean isCustomStyleSheetApplied;
/**
* Holds the relative location of the FXML JavaXML files. Roots are the source folders of the
* (plugin) project.
*/
private final String fXMLLocation;
/** References the stub that defines the FXML file defining the layout and controller. */
private Class<? extends AF3FXViewPart> viewerClass;
/** References the root {@link Pane} to which GUI elements must be added to be displayed. */
private Pane root;
/**
* Constructor that is intended for {@link ViewPart}s which host a single view/node/control.
*
* @param viewerClass
* Class implementing the {@link AF3FXViewPart} to load resources from its containing
* bundle.
* @param cssLocation
* style sheet file path for the appearance settings relative to the source
* (resource) folders. Pass {@code null} if the OS-native look shall be used.
* @throws Exception
* if the given FXML file path is not given or if it cannot be found in any of the
* source (resource) folders.
*/
public AF3FXViewPart(Class<? extends AF3FXViewPart> viewerClass, String cssLocation)
throws Exception {
// Initializing the base constructor with "null" for the FXML file indicates a
// single-view/node/control usecase.
this(viewerClass, null, cssLocation);
}
/** {@link ICompositeFXController}s to be added to a container node within the view part. */
private ICompositeFXController[] containments;
/**
* Constructor. Allows to pass the view's FXML definition file.
* Constructor.
*
* @param viewerClass
* Class implementing the {@link AF3FXViewPart} to load resources from its containing
* bundle.
* @param fXMLLocation
* location of the fXML file relative to the source (resource) folders.
* @param cssLocation
* style sheet file path for the appearance settings relative to the source
* (resource) folders. Pass {@code null} if the OS-native look shall be used.
* @param containments
* Optional {@link ICompositeFXController}s to be added to a container node within the view
* part.
* @throws Exception
* if the given FXML file path is not given or if it cannot be found in any of the
* source (resource) folders.
*/
public AF3FXViewPart(Class<? extends AF3FXViewPart> viewerClass, String fXMLLocation,
String cssLocation) throws Exception {
public AF3FXViewPart(Class<? extends AF3FXViewPart> viewerClass, String cssLocation,
ICompositeFXController... containments) throws Exception {
Platform.setImplicitExit(false);
this.viewerClass = viewerClass;
this.fXMLLocation = fXMLLocation;
this.cssLocation = cssLocation;
this.containments = containments;
}
/** {@inheritDoc} */
@Override
protected Scene createFxScene() {
if(fXMLLocation != null) {
URL fxmlResource = viewerClass.getResource(fXMLLocation);
if(getFXMLLocation() != null) {
URL fxmlResource = viewerClass.getResource(getFXMLLocation());
try {
root = load(fxmlResource, this);
} catch(IOException e) {
throw new RuntimeException("Cannot load the resource located at " + fXMLLocation,
e);
throw new RuntimeException(
"Cannot load the resource located at " + getFXMLLocation(), e);
}
} else {
root = new AnchorPane();
......@@ -135,6 +113,8 @@ public abstract class AF3FXViewPart extends FXViewPart implements Initializable
setNativeLook(root);
}
addContainments(containments);
Scene scene = new Scene(root);
return scene;
}
......@@ -155,7 +135,7 @@ public abstract class AF3FXViewPart extends FXViewPart implements Initializable
* {@link Node} to be added to the view.
*/
protected void setChildNodeFinal(Node fxNode) {
if(fXMLLocation != null) {
if(getFXMLLocation() != null) {
throw new RuntimeException("This method is intended for single-control views. It may" +
" not be used for FXML-based views.");
}
......@@ -218,4 +198,10 @@ public abstract class AF3FXViewPart extends FXViewPart implements Initializable
}
return false;
}
/** {@inheritDoc} */
@Override
public Node getLayout() {
return root;
}
}
FXContainerView.java 4337fdd21f6258c7fed0c3e411fa04d45bc06c90 YELLOW
FXView.java dc5ff1c7c7c60c8203acb5e3e370da31822e0f97 YELLOW
CompositeFXControllerBase.java 5983c46c93c3cdc303c47784861be314810239dc YELLOW
ICompositeFXController.java d2c239d857aa1b125097fe0feb8ebb7dfe7f7072 YELLOW
......@@ -24,12 +24,12 @@ import javafx.fxml.FXML;
import javafx.scene.Node;
/**
* JavaFX node to be included within a container (e.g. a {@link FXContainerView}) and associated
* with a controller of type {@code T}.
* JavaFX node which can be hierarchically composed. It can be included within another
* {@link CompositeFXControllerBase} and might contain other {@link CompositeFXControllerBase}s.
*
* @author munaro
*/
public abstract class FXView<T> {
public abstract class CompositeFXControllerBase implements ICompositeFXController {
/**
* JavaFX {@link Node} with the layout specified in the {@link FXML} resource and
......@@ -38,21 +38,26 @@ public abstract class FXView<T> {
private Node layout;
/** Constructor. */
@SuppressWarnings("unchecked")
public FXView() throws IOException {
T controller = (T)this;
URL fxmlResource = controller.getClass().getResource(getFXMLLocation());
layout = load(fxmlResource, controller);
public CompositeFXControllerBase(CompositeFXControllerBase... containments) throws IOException {
URL fxmlResource = getClass().getResource(getFXMLLocation());
layout = load(fxmlResource, this);
addContainments(containments);
}
/**
* Returns a JavaFX {@link Node} with the layout specified in the {@link FXML} resource and
* associated with a controller of type {@code T}.
*/
@Override
public Node getLayout() {
return layout;
}
/** Returns the location of the {@link FXML} resource with the view's layout. */
protected abstract String getFXMLLocation();
@Override
public abstract String getFXMLLocation();
/** {@inheritDoc} */
@Override
public abstract void addContainments(ICompositeFXController[] containments);
}
......@@ -15,23 +15,25 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.common.ui.javafx.layout;
import java.io.IOException;
import javafx.scene.layout.Pane;
import javafx.fxml.FXML;
import javafx.scene.Node;
/**
* JavaFX node of type {@link FXView} including a {@link Pane} which serves as a container for
* another {@link FXView}.
* Generic interface for JavaFX controllers which can be hierarchically composed.
*
* @author munaro
*/
public abstract class FXContainerView<T> extends FXView<T> {
public interface ICompositeFXController {
/**
* Returns a JavaFX {@link Node} with the layout specified in the {@link FXML} resource and
* associated with a controller of type {@code T}.
*/
public Node getLayout();
/** Constructor. */
public FXContainerView(FXView<?> containment) throws IOException {
getContainer().getChildren().add(containment.getLayout());
}
/** Returns the location of the {@link FXML} resource with the view's layout. */
public String getFXMLLocation();
/** Returns the {@link Pane} which will act as a container for another {@link FXView}. */
protected abstract Pane getContainer();
/** Adds the {@link ICompositeFXController}s to the container. */
public void addContainments(ICompositeFXController[] containments);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment