0

EDIT: Forgot the code...

I have an app that let's the user select CSV files for viewing. I'm using JavaFX TableViews to display the data.

For one page, the user can type into a special text box. It's a custom class I made called AutoCompleteTextArea, which extends RichTextFX's StyleClassedTextArea. On other pages, this text box should be hidden. When I have just one TableView, things work fine.

vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable);

But I need other pages with different TableViews. If I add another TableView to the VBox, my AutoCompleteTextArea goes away!

vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable, tempTable);

The TableViews do not appear to be overlapping... Any idea why the AutoCompleteTextArea is disappearing? The other weird thing is that if I substitute a regular TextField for the AutoCompleteTextArea, things work fine!

Here's my code. You will need RichTextFX on your build path in order to run it. Use the View Menu to see the problem. The first menu item shows the AutoCompleteTextArea (in the working case). The second menu item shows a different TableView, but this is the broken case - the AutoCompleteTextArea is gone from the first page.

Line 132 is the line in question.

I hope someone is up for the challenge!

More background: I originally wanted to have just one TableView, and update it's contents based on the user's selection in the View Menu. But I couldn't find a good way to do that, and now here I am again... (see this post: How do I clone a JavaFX TableView?)

package FLOOR;

// --- Imports
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.fxmisc.richtext.StyleClassedTextArea;
import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;

// --- Main Class
public class Example extends Application {

    // --- All Pages
    final Page[] pages = new Page[] {
        new Page("Welcome!",
                "Welcome Page"),
        new Page("Page 1", "Shows Table_1"),
        new Page("Page 2", "Shows Table_2"), 
    };

    // --- All Tables
    TableView<ObservableList<StringProperty>> reqTable = new TableView<>();
    TableView<ObservableList<StringProperty>> tempTable = new TableView<>();
    //TextField reqBox = new TextField();
    AutoCompleteTextArea reqBox = new AutoCompleteTextArea();

    // --- Current Page
    final Label title = new Label();
    final Label subtitle = new Label();

    // --- Main
    public static void main(String[] args) { launch(args); }

    // --- Start
    @Override
    public void start(Stage stage) {

        // --- Menus
        // --- File Menu
        // --- Import Submenu
        Menu menuFile = new Menu("File");
        Menu importMenu = new Menu("Import");
        MenuItem reqOption = new MenuItem("Requirements");
        MenuItem tempOption = new MenuItem("Templates");
        importMenu.getItems().addAll(reqOption, tempOption);        
        //Import Requirements
        reqOption.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent e) {
                //TODO
            }
        });
        //Import Templates
        tempOption.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent e) {
                //TODO
            }
        });

        //Export
        MenuItem export = new MenuItem("Export");
        export.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent t) {
                //TODO
            }
        });

        //Exit
        MenuItem exit = new MenuItem("Exit");
        exit.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent t) {
                System.exit(0);
            }
        });
        menuFile.getItems().addAll(importMenu, export, new SeparatorMenuItem(), exit);

        // --- View Menu
        Menu menuView = new Menu("View");
        //Page1
        MenuItem viewRequirements = new MenuItem("Requirements");
        viewRequirements.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent t) {
                getPage1();
            }
        });
        //Page2
        MenuItem viewTemplates = new MenuItem("Templates");
        viewTemplates.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent t) {
                getPage2();
            }
        });
        menuView.getItems().addAll(viewRequirements, viewTemplates);

        // --- Menu Bar
        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(menuFile, menuView);

        // --- VBox
        final VBox vbox = new VBox();
        vbox.setAlignment(Pos.TOP_CENTER);
        vbox.setSpacing(10);
        reqTable.setMinHeight(300);
        tempTable.setMinHeight(300);
        reqTable.translateYProperty().set(30);
        tempTable.translateYProperty().set(-275);
        reqTable.setVisible(false);
        tempTable.setVisible(false);
        reqBox.setVisible(false);

        // --- Welcome Page
        title.setFont(new Font("Arial", 24));
        title.translateYProperty().set(10);
        title.setText(pages[0].title);
        subtitle.setText(pages[0].subtitle);
        subtitle.setMinHeight(30);
        subtitle.setTextAlignment(TextAlignment.CENTER);

        // --- Show FLOOR
        vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable);
        //vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable, tempTable);
        Scene scene = new Scene(vbox, 900, 500);
        stage.setScene(scene);
        stage.setTitle("FLOOR");
        stage.show();
    }

    // --- Methods
    // Page Getters
    private void getPage1() {
        title.setFont(new Font("Arial", 24));
        title.translateYProperty().set(10);
        title.setText(pages[1].title);
        subtitle.setText(pages[1].subtitle);
        subtitle.setMinHeight(20);
        reqBox.setVisible(true);
        reqTable.setVisible(true);
        tempTable.setVisible(false);
    }
    private void getPage2() {
        title.setFont(new Font("Arial", 24));
        title.translateYProperty().set(10);
        title.setText(pages[2].title);
        subtitle.setText(pages[2].subtitle);
        subtitle.setMinHeight(20);
        reqBox.setVisible(false);
        reqTable.setVisible(false);
        tempTable.setVisible(true);
    }

    // --- Classes
    // Page
    private class Page {
        public String title;
        public String subtitle;
        public Page(String title, String subtitle) {
            this.title = title;
            this.subtitle = subtitle;
        }
    }

    // AutoCompleteTextArea
    public class AutoCompleteTextArea extends StyleClassedTextArea {
        public final SortedSet<String> entries;
        public ContextMenu entriesPopup;

        public AutoCompleteTextArea() {
            super();
            entries = new TreeSet<>();
            entriesPopup = new ContextMenu();
        }

        public SortedSet<String> getEntries() { return entries; }

        public void populatePopup(List<String> searchResult) {
            List<CustomMenuItem> menuItems = new LinkedList<>();
            int maxEntries = 20;
            int count = Math.min(searchResult.size(), maxEntries);
            for (int i = 0; i < count; i++) {
                final String result = searchResult.get(i);
                Label entryLabel = new Label(result);
                CustomMenuItem item = new CustomMenuItem(entryLabel, true);
                menuItems.add(item);
            }
            entriesPopup.getItems().clear();
            entriesPopup.getItems().addAll(menuItems);
        }
    }

}
Community
  • 1
  • 1
Ted
  • 45
  • 4
  • Your code still doesn't follow some of the layout advice from a prior answer to your questions: http://stackoverflow.com/questions/43199086/why-is-an-invisible-tableview-covering-up-a-label. I advise following the advice there (such as not using translate for layout and using SceneBuilder rather than code to prototype layout building) and that may help you. – jewelsea Apr 07 '17 at 07:38
  • Hi @jewelsea. I appreciate your advice. You're suggesting that layering tables on top of each other and then manually setting their visibility is not a good idea. However, it seems like a basic use case of a GUI that you may need to change what is displayed, without scrolling down, etc. Do you have a specific solution for this? Is my code above easily modifiable towards a better way? That would be more helpful than downloading/learning sceneBuilder in the timeframe I have. Thanks again! – Ted Apr 07 '17 at 14:09
  • jewelsea was right - a workable method is mentioned here: http://stackoverflow.com/questions/28558165/javafx-setvisible-doesnt-hide-the-element basically combining setVisibility(false) and setManaged(false) fixes the problem I was having – Ted Apr 07 '17 at 14:36

0 Answers0