Kevin Kabatra
Kevin Kabatra

Reputation: 122

JavaFX TreeView not refreshing upon shrinking parent, showing "children artifacts"

I have a TreeView that upon shrinking the parent directory, I still see the original children. There are only present as an "artifact", not really there and not clickable. This is the part of my code that is causing the issue. I know because when I comment it out the TreeView works fine.

    selectionTreeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
    @Override
    public TreeCell<String> call(TreeView<String> paramP) {
        return new TreeCell<String>(){
            @Override
            protected void updateItem(String paramT, boolean paramBoolean) {
                super.updateItem(paramT, paramBoolean);
                if(!isEmpty()){
                    setGraphic(new Label(paramT));
                    final TreeCell<String> this$ = this;
                    this.setOnMouseClicked(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        if(event.getClickCount()==2){
                            // Getting the node value.
                            String nodeValue = this$.getItem();
                        }
                    }
                    });
                }
            }
        };
    }
    });

This allows me to return the value of the child when it is double clicked. Not sure how to correct the issue. Any suggestions, any help would be appreciated? Including entire source code below in case it will help. And finally using JDK 8u5.

package javafxapplication1;

import java.net.URL;
import java.sql.*;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;

/**
*
* @author kevin_000
*/
public class FXMLDocumentController implements Initializable {

@FXML
private Label label;
@FXML TreeView selectionTreeView;

@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");
    label.setText("Hello World!");
}
//should delete item selected, does not work currently
@FXML
private void testRemoveTreeItem(ActionEvent event) {
        TreeItem<String> c = (TreeItem)selectionTreeView.getSelectionModel().getSelectedItem();
        boolean remove = c.getParent().getChildren().remove(c);
        System.out.println("Remove");
    }

@Override
public void initialize(URL url, ResourceBundle rb) {
    createTree();
    //Get Name of TreeViewCell Double Clicked
    selectionTreeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
    @Override
    public TreeCell<String> call(TreeView<String> paramP) {
        return new TreeCell<String>(){
            @Override
            protected void updateItem(String paramT, boolean paramBoolean) {
                super.updateItem(paramT, paramBoolean);
                if(!isEmpty()){
                    setGraphic(new Label(paramT));
                    final TreeCell<String> this$ = this;
                    this.setOnMouseClicked(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        if(event.getClickCount()==2){
                            // Getting the node value.
                            String nodeValue = this$.getItem();
                        }
                    }
                    });
                }
            }
        };
    }
    });
}

  public void createTree(String... rootItems) {
    //create root
    TreeItem<String> root = new TreeItem<>("Sales Analysis & Goal Is King");
    //root.setExpanded(true);
    //january
    TreeItem<String> itemJanuary = new TreeItem<>("January");
    itemJanuary.setExpanded(false);
    TreeItem<String> itemSalesAnalysisJanuary = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisJanuary.setExpanded(false);
    TreeItem<String> itemGoalIsKingJanuary = new TreeItem<>("Goal Is King");
    itemGoalIsKingJanuary.setExpanded(false);        
    //february
    TreeItem<String> itemFebruary = new TreeItem<>("February");
    itemFebruary.setExpanded(false);
    TreeItem<String> itemSalesAnalysisFebruary = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisFebruary.setExpanded(false);
    TreeItem<String> itemGoalIsKingFebruary = new TreeItem<>("Goal Is King");
    itemGoalIsKingFebruary.setExpanded(false);
    //march
    TreeItem<String> itemMarch = new TreeItem<>("March");
    itemMarch.setExpanded(false);
    TreeItem<String> itemSalesAnalysisMarch = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisMarch.setExpanded(false);
    TreeItem<String> itemGoalIsKingMarch = new TreeItem<>("Goal Is King");
    itemGoalIsKingMarch.setExpanded(false);
    //april
    TreeItem<String> itemApril = new TreeItem<>("April");
    itemApril.setExpanded(false);
    TreeItem<String> itemSalesAnalysisApril = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisApril.setExpanded(false);
    TreeItem<String> itemGoalIsKingApril = new TreeItem<>("Goal Is King");
    itemGoalIsKingApril.setExpanded(false);
    //may
    TreeItem<String> itemMay = new TreeItem<>("May");
    itemMay.setExpanded(false);
    TreeItem<String> itemSalesAnalysisMay = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisMay.setExpanded(false);
    TreeItem<String> itemGoalIsKingMay = new TreeItem<>("Goal Is King");
    itemGoalIsKingMay.setExpanded(false);
    //june
    TreeItem<String> itemJune = new TreeItem<>("June");
    itemJune.setExpanded(false);
    TreeItem<String> itemSalesAnalysisJune = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisJune.setExpanded(false);
    TreeItem<String> itemGoalIsKingJune = new TreeItem<>("Goal Is King");
    itemGoalIsKingJune.setExpanded(false);
    //july
    TreeItem<String> itemJuly = new TreeItem<>("July");
    itemJuly.setExpanded(false);
    TreeItem<String> itemSalesAnalysisJuly = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisJuly.setExpanded(false);
    TreeItem<String> itemGoalIsKingJuly = new TreeItem<>("Goal Is King");
    itemGoalIsKingJuly.setExpanded(false);        
    //august
    TreeItem<String> itemAugust = new TreeItem<>("August");
    itemAugust.setExpanded(false);
    TreeItem<String> itemSalesAnalysisAugust = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisAugust.setExpanded(false);
    TreeItem<String> itemGoalIsKingAugust = new TreeItem<>("Goal Is King");
    itemGoalIsKingAugust.setExpanded(false);        
    //september
    TreeItem<String> itemSeptember = new TreeItem<>("September");
    itemSeptember.setExpanded(false);
    TreeItem<String> itemSalesAnalysisSeptember = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisSeptember.setExpanded(false);
    TreeItem<String> itemGoalIsKingSeptember = new TreeItem<>("Goal Is King");
    itemGoalIsKingSeptember.setExpanded(false);        
    //october
    TreeItem<String> itemOctober = new TreeItem<>("October");
    itemOctober.setExpanded(false);
    TreeItem<String> itemSalesAnalysisOctober = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisOctober.setExpanded(false);
    TreeItem<String> itemGoalIsKingOctober = new TreeItem<>("Goal Is King");
    itemGoalIsKingOctober.setExpanded(false);        
    //november
    TreeItem<String> itemNovember = new TreeItem<>("November");
    itemNovember.setExpanded(false);
    TreeItem<String> itemSalesAnalysisNovember = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisNovember.setExpanded(false);
    TreeItem<String> itemGoalIsKingNovember = new TreeItem<>("Goal Is King");
    itemGoalIsKingNovember.setExpanded(false);        
    //december
    TreeItem<String> itemDecember = new TreeItem<>("December");
    itemDecember.setExpanded(false);
    TreeItem<String> itemSalesAnalysisDecember = new TreeItem<>("Sales Analysis");
    itemSalesAnalysisDecember.setExpanded(false);
    TreeItem<String> itemGoalIsKingDecember = new TreeItem<>("Goal Is King");
    itemGoalIsKingDecember.setExpanded(false);        

    //create stores, stores are children of SalesAnalsysis & GoalIsKing Trees
    try (Connection connection = DriverManager.getConnection(
            "jdbc:derby://localhost:1527/FJH_Stores_&_Employees","kevinkabatra","ew4pkd8d");
        Statement statement = connection.createStatement();) {
        ResultSet rs = statement.executeQuery("select LOCATION from STORES");
        while (rs.next()){
            //january
            itemSalesAnalysisJanuary.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis January"));
            itemGoalIsKingJanuary.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King January"));
            //february
            itemSalesAnalysisFebruary.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis February"));
            itemGoalIsKingFebruary.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King February"));
            //march
            itemSalesAnalysisMarch.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis March"));
            itemGoalIsKingMarch.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King March"));
            //april
            itemSalesAnalysisApril.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis April"));
            itemGoalIsKingApril.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King April"));
            //may
            itemSalesAnalysisMay.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis May"));
            itemGoalIsKingMay.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King May"));
            //june
            itemSalesAnalysisJune.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis June"));
            itemGoalIsKingJune.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King June"));
            //july
            itemSalesAnalysisJuly.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis July"));
            itemGoalIsKingJuly.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King July"));
            //august
            itemSalesAnalysisAugust.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis August"));
            itemGoalIsKingAugust.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King August"));
            //september
            itemSalesAnalysisSeptember.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis September"));
            itemGoalIsKingSeptember.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King September"));
            //october
            itemSalesAnalysisOctober.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis October"));
            itemGoalIsKingOctober.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King October"));
            //november
            itemSalesAnalysisNovember.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis November"));
            itemGoalIsKingNovember.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King November"));
            //december
            itemSalesAnalysisDecember.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Sales Analsysis December"));
            itemGoalIsKingDecember.getChildren().add(new 
                TreeItem<>(rs.getString("LOCATION")+" Goal Is King December"));
        }
    } catch (SQLException ex) {
        System.err.print("Exception: ");
        System.err.println(ex.getMessage());
    }
    //SalesAnalysis and GoalIsKing are children of each month,
    //months are children of root
    itemJanuary.getChildren().addAll(itemSalesAnalysisJanuary,itemGoalIsKingJanuary);
    itemFebruary.getChildren().addAll(itemSalesAnalysisFebruary,itemGoalIsKingFebruary);
    itemMarch.getChildren().addAll(itemSalesAnalysisMarch,itemGoalIsKingMarch);
    itemApril.getChildren().addAll(itemSalesAnalysisApril,itemGoalIsKingApril);
    itemMay.getChildren().addAll(itemSalesAnalysisMay,itemGoalIsKingMay);
    itemJune.getChildren().addAll(itemSalesAnalysisJune,itemGoalIsKingJune);
    itemJuly.getChildren().addAll(itemSalesAnalysisJuly,itemGoalIsKingJuly);
    itemAugust.getChildren().addAll(itemSalesAnalysisAugust,itemGoalIsKingAugust);
    itemSeptember.getChildren().addAll(itemSalesAnalysisSeptember,itemGoalIsKingSeptember);
    itemOctober.getChildren().addAll(itemSalesAnalysisOctober,itemGoalIsKingOctober);
    itemNovember.getChildren().addAll(itemSalesAnalysisNovember,itemGoalIsKingNovember);
    itemDecember.getChildren().addAll(itemSalesAnalysisDecember,itemGoalIsKingDecember);
    root.getChildren().addAll(itemJanuary,itemFebruary,itemMarch,
            itemApril,itemMay,itemJune,itemJuly,itemAugust,itemSeptember,
            itemOctober,itemNovember,itemDecember);
    selectionTreeView.setRoot(root);
}
}

Upvotes: 1

Views: 2124

Answers (1)

Jonathan Giles
Jonathan Giles

Reputation: 666

The bug is in your updateItem method - you aren't calling setGraphic(null) when the empty parameter is true.

I should note that in this case using setGraphic is not correct - you're passing in a Label when you could just instead call setText with the paramT string.

Additionally, I would be remiss in not noting that your updateItem method is doing way more work than it should be, considering how frequently it is called. You should move everything that is not specifically related to updating the cell when the item and empty parameters change into the constructor of the TreeCell (by using an anonymous constructor). This includes the creation of the EventHandler - which only needs to be set in the constructor.

Upvotes: 5

Related Questions