0

I am building up a playlist manager.

Which works well but has deep flaws in the design, and thus, is difficult to UPGRADE / MAINTAIN.

In that context I now have a javafx TreeTableView having a column as Checkbox. To get a visual idea, here is what it looks like :

image of TreeTableView illustrating checkboxes

In order to manage the check/uncheck children and parents of checkboxes, I implemented a listener, applied in mass AFTER the tree is built :

private void addMarkListenerToAllChildren(TreeItem<PlaylistTtRow> parentTreeItem) {
    parentTreeItem.getChildren().forEach(playlist -> {
        playlist.getValue().isMarked.addListener((ChangeListener<Boolean>) (obs, isPrevStatus, isNowStatus) -> {
            if (!isStopListen) {
                chbxOnChangeMarkTreeItem(playlist, isNowStatus);
                logDLI.append(LogCategory.DEVELOPMENT, LogSeverity.INFO, LogGroup.A, "Value of " + playlist.getValue().playlistIconAndName.getValue().getPlaylistName() + " changed to " + playlist.getValue().isMarked.getValue());
            }
        });
        logDLI.append(LogCategory.DEVELOPMENT, LogSeverity.INFO, LogGroup.A, "Listener added to " + playlist.getValue().playlistIconAndName.getValue().getPlaylistName());
        if (!playlist.getChildren().isEmpty()) {
            addMarkListenerToAllChildren(playlist);
        }
    });
}

This is in my controller at the moment !!! It's obviously in the wrong place as design... where should it go ?

And here is the process of a 'change' in checkbox value... Which is at moment in my Controller as well... again wrongly placed :

// TODO : The complete processing linked to Makred row, should be placed in the corresponding Object ! Or better, in a parent Object to be extended to TtvPlaylist / TtvTrack / ...
void chbxOnChangeMarkTreeItem(TreeItem<PlaylistTtRow> tiPlaylist, boolean isSetTo) {
    if (!isUserClicked) {
        isUserClicked           = true;
        tiPlaylistUserClicked   = tiPlaylist;
    }
    
    logDLI.append(LogCategory.DEVELOPMENT, LogSeverity.INFO, LogGroup.A, "Value of '" + tiPlaylist.getValue().playlistIconAndName.getValue().getPlaylistName() + "' changed to : " + tiPlaylist.getValue().getIsMarked());
    if (tbtnAutoMarkChildren.isSelected()) {
        tiPlaylist.getChildren().forEach(child -> {
            if (!isStopListen) {
                child.getValue().setIsMarked(isSetTo);
            } else {
                logDLI.append(LogCategory.DEVELOPMENT, LogSeverity.INFO, LogGroup.A, "Value of '" + tiPlaylist.getValue().playlistIconAndName.getValue().getPlaylistName() + "' not changed because it has 'StopListen' set to true.");
            }
        });
    }
    
    // If playlist has leafs, and 'OnlyLeafs' are to be checked, force playlist as unchecked.
    if (!tiPlaylist.getChildren().isEmpty() && configs.isMarkOnlyLeafs) {
        isStopListen = true;
        tiPlaylist.getValue().isMarked.set(false);
        isStopListen = false;
    }
    // If There are parents, and 'OnlyLeafs' is NOT set, set parents to be checked (without auto-selecting children, of course).
    TreeItem<PlaylistTtRow> tiTested = tiPlaylist;
    while ((tiTested.getParent() != null) && (isSetTo)) {
        isStopListen = true;
        tiTested.getParent().getValue().isMarked.set(true);
        isStopListen    = false;
        tiTested        = tiTested.getParent();
    }
    
    // TODO : If the last of children is 'unmarked', unmark the parent.
    
    if (tiPlaylist.equals(tiPlaylistUserClicked)) {
        getInfosOnCheckedPlaylistsFromNode(tiPlaylist);
        isUserClicked = false;
    }
}

My aim is :

  • Have heritage of my PLAYLIST tree, for my TRACKS tree, which will also need marked row etc...
  • Add some more listeners to other columns
  • Be able to implement SPECIFIC methods on certain events

Any help would be appreciated. Thanks in advance...

Daric
  • 83
  • 9
  • My idea was to extend 'TreeItem'... Bad/Good idea ? – Daric Feb 17 '21 at 15:13
  • Is the `CheckBox` code in the `setCellValueFactory` method? If not, that might be the reason you are having issues. – SedJ601 Feb 17 '21 at 16:13
  • 1
    have a look at CheckBoxTreeTableCell - when stuck using it, come back with a [mcve] demonstrating what's not working as expected. And stick to java naming conventions when publicly showing code. – kleopatra Feb 17 '21 at 16:14
  • @Sedrick : Everything is working fine... I'm puzzled about making the design architecture of the objects more reusable/maintainable. To answer to your question, I do have `setCellValueFactory` implemented fo my checkbox : `ttvcPlaylistIsMarked.setCellValueFactory(param -> param.getValue().getValue().isMarked);` – Daric Feb 18 '21 at 10:33
  • @kleopatra 1 : Thank you for suggestions. I'll separate the answers in 2 : `CheckBoxTreeTableCell`, of what i understood in other posts, would make my tree have, in fact 2 parallel trees inside : a. The one built with parent/children relation of playlists... b. The one, identical, with the checkboxes... this does not seem right does it ? – Daric Feb 18 '21 at 10:39
  • @kleopatra 2 : I'll look more inside of best practice for Java naming conventions _(have any suggested website giving these?)_, sorry if this makes it harder to read the code :-(. As about a minimal reproducible example... it's exactly the problem I'm facing : the code is so badly articulated... – Daric Feb 18 '21 at 11:12

0 Answers0