feature/github-copilot-consolidation #1

Merged
konrad merged 10 commits from feature/github-copilot-consolidation into main 2025-12-14 13:29:43 +01:00
4 changed files with 254 additions and 0 deletions
Showing only changes of commit 2b60038774 - Show all commits

15
fx/ideas.md Normal file
View File

@ -0,0 +1,15 @@
# Ideen
# Bindings
Bindngs kommen über ein spezielles Binding Control, das dann notwendige Bindings beinhaltet.
Da kann dann auch eine eigene Logik zur Erkennung des Bindings erfolgen oder zusätziche Informationen bezüglich notwendiger Elemente in dem ViewModel
# FXMLComponent
Dient dem Laden einer Komponente und bekommt dazu das fxml, die Daten und ggf. auch eine ModelView.
# ModelView generieren
Damit eine ModelView nicht ständig manuell generiert werden muss, ist hier ggf. etwas zu generieren?
Ggf. eine eigenes Beschreibungssprache?

View File

@ -0,0 +1,67 @@
package de.neitzel.fx.component.controls;
import de.neitzel.fx.component.model.BindingData;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.layout.Region;
/**
* The BindingControl class represents a UI control that manages a list
* of {@link BindingData} objects. It extends the {@link Region} class and
* provides functionality to bind and monitor connections between source
* and target properties.
*
* The primary purpose of this control is to maintain an observable list
* of bindings, allowing developers to track or adjust the linked properties
* dynamically.
*
* The internal list of bindings is implemented as an {@link ObservableList},
* allowing property change notifications to be easily monitored for UI
* updates or other reactive behaviors.
*
* This class serves as an organizational component and does not provide
* any user interaction by default.
*/
public class Binding extends Region {
/**
* Represents an observable list of {@link BindingData} objects contained within the
* {@link Binding} instance. This list is utilized to manage and monitor
* the bindings between source and target properties dynamically.
*
* The list is implemented as an {@link ObservableList}, allowing changes in the
* collection to be observed and reacted to, such as triggering UI updates or
* responding to binding modifications.
*
* This field is initialized as an empty list using {@link FXCollections#observableArrayList()}.
* It is declared as final to ensure its reference cannot be changed, while the
* contents of the list remain mutable.
*/
private final ObservableList<BindingData> bindings = FXCollections.observableArrayList();
/**
* Retrieves the observable list of {@code Binding} objects associated with this control.
* The returned list allows monitoring and management of the bindings maintained
* by the {@code BindingControl}.
*
* @return an {@code ObservableList<Binding>} containing the bindings managed by this control
*/
public ObservableList<BindingData> getBindings() {
return bindings;
}
/**
* Constructs a new instance of the BindingControl class.
*
* This default constructor initializes the BindingControl without
* any pre-configured bindings. The instance will contain an empty
* {@link ObservableList} of {@link BindingData} objects, which can later
* be populated as needed.
*
* The constructor does not perform additional setup or initialization,
* allowing the class to be extended or customized as necessary.
*/
public Binding() {
// Absichtlich leer wird später "ausgewertet"
}
}

View File

@ -0,0 +1,90 @@
package de.neitzel.fx.component.controls;
import de.neitzel.fx.component.ComponentLoader;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.layout.StackPane;
import java.io.IOException;
import java.util.Arrays;
public class FxmlComponent extends StackPane {
private final StringProperty fxml = new SimpleStringProperty();
private final StringProperty direction = new SimpleStringProperty("unidirectional");
private final ObjectProperty<Object> data = new SimpleObjectProperty<>();
public StringProperty fxmlProperty() { return fxml; }
public String getFxml() { return fxml.get(); }
public void setFxml(String fxml) { this.fxml.set(fxml); }
public StringProperty directionProperty() { return direction; }
public String getDirection() { return direction.get(); }
public void setDirection(String direction) { this.direction.set(direction); }
public ObjectProperty<Object> dataProperty() { return data; }
public Object getData() { return data.get(); }
public void setData(Object data) { this.data.set(data); }
public FxmlComponent() {
fxml.addListener((obs, oldVal, newVal) -> load());
data.addListener((obs, oldVal, newVal) -> injectData());
}
private void load() {
if (getFxml() == null || getFxml().isBlank()) return;
try {
ComponentLoader loader = new ComponentLoader();
// Option: ControllerFactory verwenden, wenn nötig
Parent content = loader.load(getClass().getResource(getFxml()));
getChildren().setAll(content);
Object controller = loader.getController();
if (controller != null && getData() != null) {
injectDataToController(controller, getData());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void injectData() {
if (!getChildren().isEmpty() && getData() != null) {
Object controller = getControllerFromChild(getChildren().get(0));
if (controller != null) {
injectDataToController(controller, getData());
}
}
}
private void injectDataToController(Object controller, Object dataObject) {
// Daten-Objekt per Reflection zuweisen
// Beispiel: Controller hat `setData(User data)`
Arrays.stream(controller.getClass().getMethods())
.filter(m -> m.getName().equals("setData") && m.getParameterCount() == 1)
.findFirst()
.ifPresent(method -> {
try {
method.invoke(controller, dataObject);
} catch (Exception e) {
e.printStackTrace();
}
});
// Optional: automatisch Binding ausführen (s. u.)
}
private Object getControllerFromChild(Node node) {
if (node.getProperties().containsKey("fx:controller")) {
return node.getProperties().get("fx:controller");
}
return null;
}
}

View File

@ -0,0 +1,82 @@
package de.neitzel.fx.component.model;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* The Binding class represents a connection between a source and a target,
* with an associated direction. It is typically used to define a binding
* relationship that determines how data flows between these two entities.
*
* The class provides three properties:
* - direction: Represents the type of the binding. Defaults to "unidirectional".
* - source: Represents the source of the binding.
* - target: Represents the target of the binding.
*
* It uses JavaFX property types, allowing these properties to be observed
* for changes.
*/
public class BindingData {
/**
* Represents the direction of the binding in the {@code Binding} class.
* It determines whether the binding is unidirectional or bidirectional.
* The default value is "unidirectional".
*
* This property is observed for changes, enabling dynamic updates
* within the JavaFX property system.
*/
private StringProperty direction = new SimpleStringProperty("unidirectional");
/**
* Represents the source of the binding. This property holds a string value
* that specifies the originating object or identifier in the binding connection.
* It can be observed for changes, allowing updates to the binding relationship
* when the source value is modified.
*/
private StringProperty source = new SimpleStringProperty();
/**
* Represents the target of the binding in the Binding class.
* This property holds the target value, which can be observed for changes.
*/
private StringProperty target = new SimpleStringProperty();
/**
* Gets the current direction of the binding.
* The direction determines how data flows between
* the source and the target, and typically defaults to "unidirectional".
*
* @return the current direction of the binding
*/
public String getDirection() { return direction.get(); }
/**
* Sets the direction of the binding.
*
* @param dir the new direction to set for the binding
*/
public void setDirection(String dir) { direction.set(dir); }
/**
* Gets the current source value of the binding.
*
* @return the source value as a String.
*/
public String getSource() { return source.get(); }
/**
* Sets the value of the source property for this binding.
*
* @param source the new source value to be set
*/
public void setSource(String source) { this.source.set(source); }
/**
* Retrieves the current value of the target property.
*
* @return the value of the target property as a String.
*/
public String getTarget() { return target.get(); }
/**
* Sets the target property of the binding.
*
* @param target the new value to set for the target property
*/
public void setTarget(String target) { this.target.set(target); }
}