Controls in Controls / Nested fxml

kagel

Neues Mitglied
Momentan implementiere einen Prototypen mit javafx
der als Basis für die GUI von einer komplexen Enterpriselösung verwendet werden soll.

Folgende Bedingungen sollen erfüllt sein:
Zunächst sollen einige wiederverwendbare Komponenten/UserControls
fxml + deren controller implementiert werden

diese sollen je nach Anwendung
beliebig miteinander kombiniert / verschachtelt werden können

die Komponenten sollen unabhängig voneinander funktionsfähig sein
d.h. dependecy injection/lose Kopplung keine direkten abhängigkeiten

die Kommunikation/Event Datenaustausch
zwischen den Modulen soll beliebig konfigurierbar sein

Nun stehe ich vor dem ersten Problem in einem einfachen Beispiel

die main.fxml (hauptkomponente) enthält die fkt.fxml (subkomponente)
jeder ist ein separaten Controller maincontroller.java bzw.
fktcontroller.java über den FXMLLoader verknüpft.
In jedem Controller gibt es einen Eventhandler der auf Actionen
z.B. buttonclick von Controls reagiert.
Das funktioniert im Beispiel aber nicht sobald ein Komponente über <fx:include eingebunden ist:

Nun möchte ich einen button click in einer subkomponente
hier fkt.fxml bis zum hauptprogramm "durchreichen" um dort dann
mit der business logik zu verkuppeln.
um direkte Abhängigkeiten zwischen den Controllern zu vermeiden
wollte ich per Observer die Kommunikation zwischen diesen
realisieren.

Im moment regiert aber der handler von subkomponenten über haupt nicht
Ich bin Euch dankbar für Ideen/Alternativen wie man die Thematik am elegantesten löst.


Entrypoint: program.java

Java:
    public void start(Stage stage) throws Exception 
    {	   		 	
    	FktController cFkt = new FktController(); //subkomponenente über fx:include verknüpft
    	MainController cMain = new MainController(); //hauptkomponente
    	cMain.SetLabelText("dieser text wurde überschrieben"); //funktioniert
    	
        Scene scene = new Scene(cMain);
        stage.setScene(scene);
        stage.show();
    }

maincontroller.java

Java:
public class MainController extends VBox 
{
	@FXML private VBox paneMain;
	@FXML private Label lblTest;
	
    public MainController()
    {	
    	FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Main.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
   
        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }
    
    
    public void SetLabelText(String txt) 
    {
        lblTest.setText(txt);
    }
}

fktcontroller.java

Java:
public class FktController extends VBox 
{
	@FXML private VBox panefkt;
	@FXML private Button btnTest;
	  
    public FktController()
    {	
    	FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Fkt.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
   
        try {
            fxmlLoader.load();
        } 
        catch (IOException exception) {
            throw new RuntimeException(exception);
        }
        
	//wird nur aufgerufen wenn 
	//hauptkomponente in program.java 
    	//FktController cFkt = new FktController(); 
        //Scene scene = new ScenecFkt 

      	btnTest.setOnAction(new EventHandler<ActionEvent>() {

	//wird nur aufgerufen wenn 
	//hauptkomponente in program.java 
    	//FktController cFkt = new FktController(); 
        //Scene scene = new Scene(cFkt); 

            public void handle(ActionEvent event) {
			  	System.out.println("FktController button clicked!"); 
            }		
        }); 
    }


main.fxml

Java:
<fx:root type="javafx.scene.layout.VBox" fx:id="paneMain" xmlns:fx="http://javafx.com/fxml"
	minWidth="300" minHeight="200" spacing="10">
	
	<padding>
        	<Insets right="20.0" bottom="20.0" left="20.0" top="20.0" />
	</padding>
   	<Label fx:id="lblTest" styleClass="app2" text="dieser label ist ein test..."/>
   	
   	<fx:include fx:id="vboxList" source="Fkt.fxml"/>  
   	
    <stylesheets>
    	<URL value="@HMVCDemo.css" />
  	</stylesheets>  
</fx:root>

fkt.fxml

Java:
<fx:root type="javafx.scene.layout.VBox" fx:id="paneFkt" xmlns:fx="http://javafx.com/fxml">
   <Button fx:id="btnTest"  text="fkt clicked!" />
</fx:root>
 

dzim

Top Contributor
Ich hab mir jetzt deine Codeschnipsel nicht im Detail durchgelesen, möchte dir aber einen Ratschlag geben: Mach das mit OSGi und deren Services...
Ich habe hier auf Arbeit mal eine kleine Plattform geschrieben, die selbst relativ doof ist und nur den Rumpf bietet, aber per OSGi-Services (quasi "Plugins") erweitert werden kann. Mit ein wenig e4 im Unterbau habe ich für DI den Eclipse-Context (in dem ich auch beliebige andere Klassen übergeben kann, die er dann bei Bedarf in z.B. meine Controller injiziert). von e4 nutze ich auch den EventBus (auch wenn ich da etwas deprecated-Zeug verwende) und ich muss sagen: Es klappt wunderbar!
Wichtig ist: Die Grundplatform muss nichts von den fxmls wissen, ich habe hier ein paar Interfaces, die ich auf Plugin-Seite implementiere und die alles regeln.
Ich kann dir aber keinen vollständigen Code, nur Ideen... Frag, wenn du interessiert bis, am besten mal per PN an - und es kann sein, dass ich erst wieder Dienstag reagiere, wenn hier unsere Feiertage vorbei sind.

Grüsse,
Daniel

PS: Das Setup ist etwas komplexer in meinem Fall, aber wenn es erst mal steht, ist der Rest quasi "a piece of cake"...
 

Ähnliche Java Themen

Neue Themen


Oben