class ListSelectDialog<T> extends DialogWindow {
    private T result;

    ListSelectDialog(
            String title,
            String description,
            TerminalSize listBoxPreferredSize,
            boolean canCancel,
            List<T> content) {

        super(title);
        this.result = null;
        if(content.isEmpty()) {
            throw new IllegalStateException("ListSelectDialog needs at least one item");
        }

        ActionListBox listBox = new ActionListBox(listBoxPreferredSize);
        for(final T item: content) {
            listBox.addItem(item.toString(), () -> onSelect(item));
        }

        Panel mainPanel = new Panel();
        mainPanel.setLayoutManager(
                new GridLayout(1)
                        .setLeftMarginSize(1)
                        .setRightMarginSize(1));
        if(description != null) {
            mainPanel.addComponent(new Label(description));
            mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
        }
        listBox.setLayoutData(
                GridLayout.createLayoutData(
                        GridLayout.Alignment.FILL,
                        GridLayout.Alignment.CENTER,
                        true,
                        false))
                .addTo(mainPanel);
        mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));

        if(canCancel) {
            Panel buttonPanel = new Panel();
            buttonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1));
            buttonPanel.addComponent(new Button(LocalizedString.Cancel.toString(), this::onCancel).setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false)));
            buttonPanel.setLayoutData(
                    GridLayout.createLayoutData(
                            GridLayout.Alignment.END,
                            GridLayout.Alignment.CENTER,
                            false,
                            false))
                    .addTo(mainPanel);
        }
        setComponent(mainPanel);
    }

    private void onSelect(T item) {
        result = item;
        close();
    }

    private void onCancel() {
        close();
    }

    /**
     * {@inheritDoc}
     *
     * @param textGUI Text GUI to add the dialog to
     * @return The item in the list that was selected or {@code null} if the dialog was cancelled
     */
    @Override
    public T showDialog(WindowBasedTextGUI textGUI) {
        result = null;
        super.showDialog(textGUI);
        return result;
    }

    /**
     * Shortcut for quickly creating a new dialog
     * @param textGUI Text GUI to add the dialog to
     * @param title Title of the dialog
     * @param description Description of the dialog
     * @param items Items in the dialog
     * @param <T> Type of items in the dialog
     * @return The selected item or {@code null} if cancelled
     */
    @SafeVarargs
    public static <T> T showDialog(WindowBasedTextGUI textGUI, String title, String description, T... items) {
        return showDialog(textGUI, title, description, null, items);
    }

    /**
     * Shortcut for quickly creating a new dialog
     * @param textGUI Text GUI to add the dialog to
     * @param title Title of the dialog
     * @param description Description of the dialog
     * @param listBoxHeight Maximum height of the list box, scrollbars will be used if there are more items
     * @param items Items in the dialog
     * @param <T> Type of items in the dialog
     * @return The selected item or {@code null} if cancelled
     */
    @SafeVarargs
    public static <T> T showDialog(WindowBasedTextGUI textGUI, String title, String description, int listBoxHeight, T... items) {<FILL_FUNCTION_BODY>}

    /**
     * Shortcut for quickly creating a new dialog
     * @param textGUI Text GUI to add the dialog to
     * @param title Title of the dialog
     * @param description Description of the dialog
     * @param listBoxSize Maximum size of the list box, scrollbars will be used if the items cannot fit
     * @param items Items in the dialog
     * @param <T> Type of items in the dialog
     * @return The selected item or {@code null} if cancelled
     */
    @SafeVarargs
    public static <T> T showDialog(WindowBasedTextGUI textGUI, String title, String description, TerminalSize listBoxSize, T... items) {
        ListSelectDialog<T> listSelectDialog = new ListSelectDialogBuilder<T>()
                .setTitle(title)
                .setDescription(description)
                .setListBoxSize(listBoxSize)
                .addListItems(items)
                .build();
        return listSelectDialog.showDialog(textGUI);
    }
}

        int width = 0;
        for(T item: items) {
            width = Math.max(width, TerminalTextUtils.getColumnWidth(item.toString()));
        }
        width += 2;
        return showDialog(textGUI, title, description, new TerminalSize(width, listBoxHeight), items);
    
<methods>public java.lang.Object showDialog(com.googlecode.lanterna.gui2.WindowBasedTextGUI) <variables>private static final Set<com.googlecode.lanterna.gui2.Window.Hint> GLOBAL_DIALOG_HINTS