Page 1 of 1

JavaFX MDI Windows

PostPosted: Mon Dec 12, 2016 1:20 pm
by Artificial
Hello, everyone!
I use FXInternalWindow in my JavaFX project. It's greate, but I have some questions about it.
How to handle event when I switching to certain window, I mean, how to get active window, focused window?
I have a label and I want to bind this label textproperty with titleproperty of my FXInternalWindow, so when I switching between windows label textproperty also changing. Thank you.

Re: JavaFX MDI Windows

PostPosted: Mon Dec 12, 2016 3:50 pm
by rzenz
Hello.

Artificial wrote:I use FXInternalWindow in my JavaFX project. It's greate, but I have some questions about it.


Awesome, both of it. :)

Artificial wrote:How to handle event when I switching to certain window, I mean, how to get active window, focused window? I have a label and I want to bind this label textproperty with titleproperty of my FXInternalWindow, so when I switching between windows label textproperty also changing.


There is no event or property, unfortunately. There is only the function getActiveWindow() in FXDesktopPane which returns the currently active window and the active property of the FXInternalWindow itself. I agree that not having an event or property for this is properly an oversight. However, I see two possibilities on how to achieve this functionality:

  • Use the active property of the FXInternalWindow to achieve this.
  • Extend the FXDesktopWindowManager and add the property yourself, attach listeners to all added windows active properties or hook into updateActiveWindow().

The ideal solution would be, of course, to add this to IWindowManager and FXDesktopPane (with the window manager controlling it and the desktop pane "just forwarding" the property (or its value)).

Artificial wrote:I have a label and I want to bind this label textproperty with titleproperty of my FXInternalWindow, so when I switching between windows label textproperty also changing.


I'm not sure if it can be bound directly even if we would add such a property. How exactly are you trying or would you like bind these properties?

Re: JavaFX MDI Windows

PostPosted: Mon Dec 12, 2016 4:37 pm
by Artificial
Thanks for answer!
Could you please show me a code snippet, where I can call method "getActiveWindow" of my FXDesktopPane, because I always got null, when I try to call it?

Re: JavaFX MDI Windows

PostPosted: Mon Dec 12, 2016 5:25 pm
by rzenz
You're most likely always receiving null because there is no active window, which is the same as no focused window. The FXInternalWindow is only active when it also has the focus.

So if you have a test setup with a FXDesktopPane and a button updating a label, you will never be able to get the active window when pressing the button, because in that moment the button has the focus and there will be no active window. So you either must update the label without removing focus from the desktop pane and its windows, or you go the hard way and fetch the uppermost window (which might or might not work depending on the window manager in use) from the pane of the window manager:

Code: Select all
ObservableList<Node> windowNodes = desktopPane.getWindowManager().getPane().getChildren();

if (!windowNodes.isEmpty())
{
   Node lastNode = windowNodes.get(windowNodes.size() - 1);
   FXInternalWindow topWindow = (FXInternalWindow)lastNode;
   activeWindowTitleLabel.setText(topWindow.getTitle());
}
else
{
   activeWindowTitleLabel.setText("<none>");
}


Note that this will only work for the FXDesktopWindowManager, not for the FXTabWindowManager. Also note that the window list which you receive from FXDesktopPane is always in the order in which the windows have been added, not in the order as they appear on screen (that is deliberate).

We definitely need a better mechanism to expose the active window, and to be honest I'm not sure if the active/focus coupling is actually intended to be this way because there is code in place to make it optional, but unfortunately that part was never publicly exposed.

A simple workaround would be to "remember" the last window which changed its active property to true.

Re: JavaFX MDI Windows

PostPosted: Tue Dec 13, 2016 10:38 am
by Artificial
I understand your code sample, but I can't get where I should insert it in my controller class? I mean this code should performs in cycle, always determine my "active" window.

Re: JavaFX MDI Windows

PostPosted: Tue Dec 13, 2016 11:47 am
by rzenz
Well, that depends on when you want to update the title, really. As there currently is no event to fire upon, short of attaching listeners to all windows, that is.

But it seems like that I will find the time to do the necessary fixes for this within a day or two, so if you can wait for that and be able to compile the project from the sources (which is really just starting Ant, really) you can have a property for the active window without having to resort to these workarounds.

Re: JavaFX MDI Windows

PostPosted: Tue Dec 13, 2016 2:00 pm
by Artificial
I would be very greateful :)

Re: JavaFX MDI Windows

PostPosted: Wed Dec 14, 2016 10:31 am
by rzenz
I have committed the necessary changes for this.

First, I have to say that I thought it through and the active window is also always the focused one, if it is not focused it can not be active. That is because the active state is used for determining whether the window should receive a "focus" border, among other things. It is currently tightly coupled with the focus sitting inside the window and I don't see a way to represent it differently. I thought about setting the focus property of the window itself, but that might have side effects which I can't foresee right now and it would require a lot of testing.

That means that the new activeWindowProperty of FXDesktopPane will "just" fetch you the currently active/focused window.

Code: Select all
FXInternalWindow activeWindow = desktopPane.getActiveWindow();

if (activeWindow != null)
{
    // Do something here.
}
else
{
    // No focused window.
}


Since that isn't that useful for your use case, I've also implemented that the window managers are exposing a list of windows in their display order:

Code: Select all
List<FXInternalWindow> windows = pane.getWindowManager().getWindows();

if (!windows.isEmpty())
{
    FXInternalWindow topMostWindow = windows.get(windows.size() - 1);
    currentWindowLabel.setText(topMostWindow.getTitle());
}
else
{
    currentWindowLabel.setText("<none>");
}


So if you want to know which window is currently the top one, which equals the active one even if does not have the focus, you just have to listen to the list of the window manager for changes and then get the last one from it.

Code: Select all
pane.getWindowManager().windowsProperty().addListener((ListChangeListener<FXInternalWindow>)pChange ->
{
    List<? extends FXInternalWindow> windows = pChange.getList();
   
    if (!windows.isEmpty())
    {
        FXInternalWindow topMostWindow = windows.get(windows.size() - 1);
        currentWindowLabel.setText(topMostWindow.getTitle());
    }
    else
    {
        currentWindowLabel.setText("<none>");
    }
});


That works with the FXDesktopWindowManager and the FXTabWindowManager. Obviously, if you change the window manager of the FXDesktopPane, you'll have to rewire your listener. You can see some of this in action in the MDITestMain application.

Now forth to the explanation on how to compile the project, that is easy:

  • Checkout/Get the project from the SourceForge repository.
  • Change into the "java" directory of "trunk".
  • Run Ant (default goal is to build everything, so no parameters needed).

That's it, the jar you're looking for will be located in the "build/install" directory.

Re: JavaFX MDI Windows

PostPosted: Mon Dec 19, 2016 9:01 am
by Artificial
Thank you for clear and comprehensible reply! But I don't have method
Code: Select all
windowsProperty()
in my
Code: Select all
windowManager()
?

Re: JavaFX MDI Windows

PostPosted: Mon Dec 19, 2016 10:10 am
by rzenz
Odd. It is there in the IFXWindowManager interface and is implemented correctly. Are you sure you're using the updated (read: build from source) jar?

Re: JavaFX MDI Windows

PostPosted: Mon Dec 19, 2016 10:41 am
by Artificial
Unfortunately, I don't have this method in my IFXWindowManager. I use latest library from maven repo:
Code: Select all
<dependency>
            <groupId>com.sibvisions.jvx</groupId>
            <artifactId>jfxtensions</artifactId>
            <version>1.0</version>
</dependency>

Re: JavaFX MDI Windows

PostPosted: Mon Dec 19, 2016 11:22 am
by rzenz
No, you must compile from source as stated in my post. There is currently no schedule for releasing a new JVx/JavaFX version or update of the Maven version.

Re: JavaFX MDI Windows

PostPosted: Mon Dec 19, 2016 12:45 pm
by Support@SIB
It's also possible to use maven snapshots (updated every friday).

Read more...

Re: JavaFX MDI Windows

PostPosted: Mon Dec 19, 2016 2:20 pm
by Artificial
Got it. Thank you for dialog, it was very helpful.

Re: JavaFX MDI Windows

PostPosted: Tue Dec 20, 2016 1:55 pm
by Artificial
By the way, do you guys have plans to develop your fx-library in future?

Re: JavaFX MDI Windows

PostPosted: Tue Dec 20, 2016 2:56 pm
by Support@SIB
What do you mean?

Our lib is ready to use as JavaFX UI for JVx applications and all components will work without JVx. We'll fix bugs an implement new Features on Request or if needed. The lib is OpenSource and the Ticketing system is available for everyone. Feel free to submit your requests.

Re: JavaFX MDI Windows

PostPosted: Tue Dec 20, 2016 2:57 pm
by Support@SIB