panemu / tiwulfx-dock

MIT License
42 stars 12 forks source link

Features Request #4

Closed SKeeneCode closed 6 months ago

SKeeneCode commented 3 years ago

I'm trying to use this awesome library in my program, and I've come across some particular needs I would love to be included:

Maintain an ObservableSet of DetachableTabPanes In my program I need additional functionality when the user interacts with the DetachableTabPanes. As the library is moving/creating/deleting DetachableTabPanes it would be nice for a Set or List with which I can attach or detach listeners as new Panes are added/removed. I played around with this and achieved it by having a DetachableTabPane take in an appropriate collection, and use that same collection in the factory function.

Toggle the ability to completely detach a Tab into its own TabStage Being able to do this is a great feature, but for me personally it doesn't apply well for my own user interface. I'd like to request a boolean property that acts as a toggle for this feature.

Be able to request a Tree representation of the layout. I'll have to double check the code but it looks like how the library builds the layouts naturally lends itself towards a binary tree, where the parents are Splitpanes and the children are TabPanes. Being able to request a tree representation of the layout would make saving/loading much easier. At the very least it would be great to have some convenience functions that allow rebuilding the layout manually such as dockTop(Node node) dockRight(Node node) etc.

jingglang commented 3 years ago

Hi,

For the 2nd point: take a look at DetachableTab.setDetachable(boolean). For the other points, it would be great if you can create a PR.

SKeeneCode commented 3 years ago

So I've revisited the project which used tiwufx-dock and begun the process of storing the tabs in a tree like structure and then trying to rebuild it programmatically but I've hit a problem and I'll really appreciate some help if possible @jingglang :

image

To help me with this task I slightly modified the adjacent() method into a placeTab() one:

public void placeTab(Tab tab, Pos pos) {
        SplitPane targetSplitPane = findParentSplitPane(DetachableTabPane.this);
        final Tab selectedtab = tab;
               // rest cut out
}

This works just fine when I'm adding Tabs along the same orientation as the parent SplitPane. But when I try to add in another orientation the library then needs to create a split-pane in the opposite orientation. Basically it runs this code.

The problem is the TabPanes it moves around into new SplitPanes etc will have their getParent() and getScene() return null. And because we're rebuilding this programmatically traversing a tree, the algorithm may then try and use the moved TabPane in some way but it cannot because the parent and scene of the TabPane won't be set until (I presume) the next layout pulse from the javafx engine.

SKeeneCode commented 3 years ago

I've created a minimal example program to demonstrate the exact issue - please have a look.

https://github.com/SKeeneCode/dock-test

jingglang commented 3 years ago

I checked your code. Please try this:

addTabsQuicklyButton2.setOnAction(event -> {
            tabPane.placeTab(createTab(), Pos.CENTER_RIGHT);
            tabPane.placeTab(createTab(), Pos.CENTER_RIGHT);
            tabPane.placeTab(createTab(), Pos.TOP_CENTER);
            new Thread(() -> {
                  try {
                      Thread.sleep(1000);//give FX Thread a chance to put the tabPane back to the scene
                  } catch (InterruptedException ex) {
                      Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
                  }
                  Platform.runLater(() -> tabPane.placeTab(createTab(), Pos.CENTER_RIGHT));
              }).start();
        });

That code with thread.sleep is a bad code though.

SKeeneCode commented 2 years ago

Didn't realise I never replied to this. I solved the problem by created a custom class that inherits SplitPane and adds a listener to its children list so that any new DetachableTabPanes have their parents stored in a new class variable. This let's me programatically dock left right up down with no problems.