I have 2 views: a main, and a subpane; and 2 respective controllers, each defined by an FXML file. A button pressed in main should result in an action in the subpane. Currently, I'm simply importing the subpane's fxml into the main one like so:
...
<BorderPane parameters=values>
<center>
<AnchorPane parameters=values>
<fx:include fx:id="subPane" source="../../bin/view/SubPane.fxml" />
</AnchorPane>
</center>
</BorderPane>
...
which gives me access to the parameter "subPaneController" for free. However, I recently read this question where a new approach is presented. I would create a SubPaneController on the fly when needed using
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/SubPane.fxml"));
loader.load();
SubPaneController sc = loader.<SubPaneController>getController();
I am interested in using this approach as it seems more widely applicable (e.g. any controller could chat with any other). I have tried setting this up with my system, and it appears that this second method creates a new subPaneController, which renders this approach currently useless for me since I would need to manually tie it to the main view, which is what I thought the FXML files were for.
So, I have 2 very related questions. Can I get the already-instantiated controller? (Maybe I need to use a Singleton pattern or something?) And why is this technique better than importing FXMLs? (I have heard dependency injection can solve issues like this, but I'm not really sure how that works with FXML stuff. I'm not explicitly asking about that, though I would certainly be open to comments about it.)
Related
I want to be able to setup specific instances of window and document for use by render(). I can specify the container by creating a specific instance of jsdom thus:
this.dom = new JSDOM('<body></body>')
const container = this.document().createElement('div')
render(
<Provider store={store}>
<MyComponent />
</Provider>,
{ container: this.dom.window.document.body.appendChild(container) }
)
If I remove global-jsdom/register from the setup, the render() call fails due to window not being defined. It seems it wants a global object called window, yet the jsdom instance has one (dom.window).
The reason for avoiding use of global window and document is that I want to be able to create separate instances to make sure that there is no shared data between instances (i.e. equivilent of two users making separate browser requests). I can't test for this if its using a global instance it seems.
I'm not using Jest for tests. It's still possible to use the getBy... queries if you avoid using the versions bound to screen, as the naked versions take the container element as the first argument, and this seems to work, but I'm concerned that the global and shared window element is going to make the tests brittle or just not work.
Looking at the source for RTL it seems that its just assuming window is a global and doesn't provide an alterantive, so wondering if anyone knows of a workaround or alternative.
In my app, I have a presenter (Presenter1) which I use to kick off an Editor (EditorView1) which edits a Foo object. This MVP setup is akin to what is described in this answer, https://stackoverflow.com/a/10699346/565863
Now, let's say that I need to create another view (EditorView2 which is kicked off by Presenter2) which also edits a Foo object, but needs to make use of EditorView1.
EditorView1 would be supplied to EditorView2 by Presenter1.
This approach seems sloppy and error prone. Is there another way to do this?
As I was writing this question, I realized a much more clean approach.
The problem with what is described above is that I was intent on re-using the first Presenter, Presenter1.
It would be much cleaner to abstract out the Editor portion of the EditorView1 code into a re-usable Editor widget (Editor1) which could be used by both EditorView1 and EditorView2. Now, I have one presenter, one view, and one EditorDriver. There is no need to juggle nested presenters or multiple EditorDrivers.
I'm interested in approaches that avoids code in the code behind.
In my opinion, there are some cases where code must be placed in the code behind.
For example: I have a grid with an undefined count of columns. Columns can't be binded. So the easiest way would be to generate the columns in the code behind.
For this case, I can create a new class which inherits from the grid. This new class has a new binding property and code for the column binding. The code is separated in a custom class which can be used in the XAML. And then, I can easy bind the columns to my newly created property. And the view has no code behind.
Is it a good idea? How would you solve such (or similar) problems?
Are there other ways to extract the code from the code behind?
Thanks.
Having a code behind free xaml.cs and moving to code to a new class does not mean its pure MVVM. The idea is you will have all the logic in ViewModel hence a code behind free View, helping in Unit Testing. View specific logic like colors and animation cannot be unittested hence doesnt matter where it resides, in an custom control or a inherited control or directly in xaml.cs. As long as you are testing most of the user interactions and view logic via UnitTesting, you should be happy that you have done a good job.
I have created a couple of activities and stored them as XAML.
Opening them in the Workflowdesigner works great and I can Execute them.
Now I would like to create a new Activity and add the activities I created to it.
Basically loading it from the XAML and into the designer as part of another activity/flow.
I have tried adding my activities to the toolbox but the render as dynamicactivity and (understandably) does not work.
Any suggestions?
Is it even possible?
/Jimmy
DynamicActivity and the toolbox were basically not designed to work together that way. The toolbox expects to deal with types, not class instances.
One thing you can do instead is subclass IActivityTemplateFactory and in the Create() function return DynamicActivity. But you will probably have some really weird issues once you try to save a XAML file created which contains dynamic activities. Because in fact the designer doesn't do any special treatment for DynamicActivity, and it will not get serialized as any kind of 'logical reference' to the XAML file you created it from.
Tim
I would like to do absolute layout using said panel by only using ui.xml file however it isn't clear if this is possible since the documentation concentrates on the code and ignores the layout language altogether. I'm assuming, since the tutorial doesn't mention this, it is impossible but would like to know for sure.
I know this is old, but they updated the uibinder for AbsolutePanel
Use in UiBinder Templates
AbsolutePanel elements in UiBinder
templates lay out their children with
absolute position, using
elements. Each at element should have
left and top attributes in pixels.
They also can contain widget children
directly, with no position specified.
For example:
<g:AbsolutePanel>
<g:at left='10' top='20'>
<g:Label>Lorem ipsum...</g:Label>
</g:at>
<g:Label>...dolores est.</g:Label>
</g:AbsolutePanel>
You are right - there's no way to do this at the moment. This could be addressed in a future GWT release by introducing some custom syntax, like it was done for DockLayoutPanel. But I doubt it - you'd want to write code like this:
<g:AbsolutePanel ui:field="absolutePanel">
<g:Button x="50px" y="50px">Test</g:Button>
</g:AbsolutePanel>
However this conflicts with the "bean" (as in Java Beans; if you have a getSomethingCool method, you can write somethingCool="kewl" in the UiBinder code and it will autmagically call the appropriate get/set method) style - because Button doesn't have a setX/Y method. This could be bypassed by replacing the setX/Y calls with appropriate calls to existing methods (CSS positioning, etc) at compile time. But this introduces yet another custom behavior, dependent on the wrapping Widget/Panel - I think the GWT devs would like to avoid that.