mabe02 / lanterna

Java library for creating text-based GUIs
GNU Lesser General Public License v3.0
2.3k stars 243 forks source link

documentation about window management #573

Closed damnms closed 8 months ago

damnms commented 1 year ago

i really like ncurses, therefore i like lanterna, but: the documentation is a bit... uncomplete. or i am blind. i am looking for a way to change screens. for example, i have 3 message dialogs that can appear:

unfortunately, i cant get it working.

    private final Map<String, Long> downloadProgress = new HashMap<>();
    private final Terminal terminal = new DefaultTerminalFactory().createTerminal();
    private final Screen screen = new TerminalScreen(terminal);
    final WindowBasedTextGUI textGUI = new MultiWindowTextGUI(screen);

    final FileDialog fileDialogWindow = new FileDialogBuilder()
            .setTitle("xyz")
            .setDescription("Choose a file")
            .setActionLabel("Open")
            .build();

    final MessageDialog fileDoesNotExistWindow = new MessageDialogBuilder()
                        .setTitle("Error!")
                        .setText("The file does not exist or is not readable or is no xml!")
                        .addButton(MessageDialogButton.Close)
                        .build();

    public CursesWindow() throws IOException {
        textGUI.addWindow(fileDialogWindow);
        textGUI.addWindow(fileDoesNotExistWindow);
    }

public void show() throws IOException {
        screen.startScreen();
        textGUI.setActiveWindow(fileDialogWindow);
        textGUI.addWindowAndWait(fileDialogWindow);
        File file;
        while (true) {

            file = fileDialogWindow.showDialog(textGUI);

            if (!file.canRead()) {
                screen.clear();
                textGUI.waitForWindowToClose(fileDoesNotExistWindow);
                continue;
            }
...
}

Not sure if this is some kind of bug, or wrong usage by me. The filedialogwindow is somehow set to the foreground again and in the background is my error message

Bildschirmfoto_2023-06-28_09-06-57

damnms commented 1 year ago

was because of that textGUI.setActiveWindow(fileDialogWindow); textGUI.addWindowAndWait(fileDialogWindow);

would be nice to have a bit more documentation about changing window's and best practices

damnms commented 1 year ago

have to re-open that, the initial problem is solved but the main problem still exists. when i try to change the window back to the filedialog choser, it only shows "xyz" like
Bildschirmfoto_2023-06-28_09-32-08

damnms commented 1 year ago

when i set fileDialogWindow to full_screen, it looks like as if the window exists but the filedialog choser is "lost" :D

damnms commented 1 year ago

guess i found the "problem" all the code is in the constructor of FileDialog, so in order to use this again, one must probably create a new instance. i will see if that fixes it.

damnms commented 1 year ago

yeah... thats the thing. maybe it would make sense to get rid of that from the constructor and have some sort of "show()" method that shows it. as workaround i now use the builders and call each time .build()

avl42 commented 1 year ago

I'm glad you were able to solve it.

I think, throw-away objects are quite common in Java, and are even faster than handling of objects "kept in reserve". The reason lies in how the garbage collector works. Throw-away-objects are really cheap, as they usually don't survive the next sweep of the GC. Objects kept for re-use, on the other hand, are moved to next "generation" and, unless they are really needed to persist, it's more of a waste than throwing them away "asap".

Is anything left? (otherwise please close this one, too)

damnms commented 1 year ago

the problem occurs when this is used in loops, then it will produce massive overhead. like i use it in one of my applications where listeners get informed every few ms. i close this now as it feels like you are not going to implement it, so it makes no sense to continue. imo this is wrong, but its just my opinion.

edit: just checked jfilechooser from swing, they separate the show() logic and constructor stuff completely. so jfilechooser can be re-used, the filechooser from laterna unfortunately not.

avl42 commented 1 year ago

Just one last note: I'm just yet another contributor to this project, nothing more.

I'm not the one who decides what gets in and what not.

If you disagree with me, that's fine. You still have a chance that the project owner (Martin Berglund) might agree with you, and will actually change something.

In other words: don't give up just because of my differing opinion.

damnms commented 1 year ago

ah, i thought you are the "boss" of this project and thats your decision ;) in that case i'll reopen and wait what the boss says. i mean its fine for me now as it works, i use now the builders. its just ugly imo.

mabe02 commented 1 year ago

@damnms sorry, I don't follow... You want to keep the file dialog alive after it's closed so you can show it again?

damnms commented 1 year ago

yes, like (pseudocode):

filedialog = new FileDialog("My Title", "Some random Text", JButton.Close);
File file = filedialog.show();
#show it again
File file2 = filedialog.show();

and another really nice feature would be to be able to filter, e.g. to show only .xml files

mabe02 commented 1 year ago

Ok, is this because you want to keep state in the dialog? Or you just don't like calling the constructor twice?

damnms commented 1 year ago

i want to have state, yes. but not only state, the object is not usable anymore when it was called once with show. so even if i dont want state, it would be impossible to use the object again and i have to generate it new. which makes maybe sense if the dialog is only shown once but when its in a loop... i really like it how jfx and swing solve that problem.

mabe02 commented 1 year ago

Ok, well, by design the dialogs are use-and-throw-away, Swing usually has the same approach to their modals. I checked the code for exactly what the behavior is when you try to re-open a modal and it results in an empty window because the close() method removes the main component from the window. I agree this is a bit weird. I've checked for any particular reason why I did it this way (code is nearly 10 years old) but I can't find anything so I'll experimentally remove that part and let's see if anything breaks. Any existing code that only displays the modal once should be ok as the whole object is GC:ed anyway.

damnms commented 1 year ago

not sure about the other models, but jfilechooser does not have any close() method at all, https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/swing/JFileChooser.html

mabe02 commented 1 year ago

No, I think the Swing/AWT convention is setVisible(false) when you do it programmatically.

ginkoblongata commented 8 months ago

Does this commit address the issue? https://github.com/mabe02/lanterna/commit/b02492a211f27deb3682e775abf4581dafd35003

Is this completed and this issue can be closed?

mabe02 commented 8 months ago

I think so. Let me close it and please re-open if you disagree