Javafx自定义单元工厂节点不工作但在Cell工厂中继承了setText()方法

时间:2017-02-21 17:40:01

标签: java javafx tableviewcell

我已经建立了一个定制的细胞工厂。大多数值显示正确,但有些值不正确。当我扩展和折叠细胞时,问题变得更糟。奇怪的是继承的setText()方法按预期工作。我只使用setText()方法来帮助我理解为什么这不起作用。您会注意到我的自定义内容左侧的setText()方法的内容。

查看第一个单元格,您会注意到我的自定义单元格内容都没有显示(最值得注意的是,TextFlow节点未显示)。但是setText()内容确实如此,所以我知道if语句逻辑按预期工作。任何想法到底发生了什么?

下面是代码:

import java.util.Collections;
import java.util.List;

import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;

public class CellValueMaker extends TreeTableCell<ProviderAttribute, ProviderAttribute>{

    ImageView up;
    ImageView down;
    GridPane grid;
    Text cellName;
    Text cellDesc;
    Label serialNumber;
    VBox innerVB;
    GridPane innerLowerGrid;
    ImageButton upButton;
    ImageButton downButton;
    TextFlow flow;

    public CellValueMaker(){
        up = new ImageView(new Image(getClass().getResourceAsStream(
                "/resources/up.png")));
        up.setFitHeight(15);
        up.setFitWidth(15);
        upButton = new ImageButton(up);

        down = new ImageView(new Image(getClass().getResourceAsStream(
                "/resources/down.png")));
        down.setFitHeight(15);
        down.setFitWidth(15);
        downButton = new ImageButton(down);

        grid = new GridPane();
        innerVB = new VBox();
        innerVB.setPadding(new Insets(0, 0, 0, 3));
        innerLowerGrid = new GridPane();

        serialNumber = new Label("");
        serialNumber.setFont(Font.font ("System", 10));
        innerLowerGrid.add(serialNumber, 1, 0);
        cellName = new Text("");
        cellDesc = new Text("");
        cellDesc.setStyle("-fx-font-weight: bold");
        flow = new TextFlow();
        flow.getChildren().addAll(cellDesc, cellName);



        innerVB.getChildren().addAll(flow, serialNumber);

        upButton.setOnMouseClicked(new OnMoveUp());
        downButton.setOnMouseClicked(new OnMoveDown());

        // set lower nested grid
        grid.add(upButton, 0, 0);
        grid.add(downButton, 1, 0);
        grid.add(innerVB, 2, 0);
        setGraphic(grid);
    }

    @Override
    public void updateItem(ProviderAttribute item, boolean empty){
        super.updateItem(item, empty);

        if(item == null || empty){
            setGraphic(null);       
            setText("");
            setStyle("-fx-background-color: white;");
            cellName.setText("");
            cellDesc.setText("");
        }else{
            if(item instanceof DigitalIdentityType){
                DigitalIdentityType certBean = item.getEncapsulatedBean();
                setGraphic(grid);
                cellName.setText(item.getStringName());
                cellDesc.setText("Cert: ");
                setText(item.getStringName());
                setStyle("-fx-background-color: darkkhaki;");
                if(certBean.getParentCert() != null){
                    serialNumber.setText("SN: " + certBean.getParentCert().getSerialNumber().toString());
                }   
            }else if(item instanceof TSPServiceType){
                setGraphic(grid);
                cellName.setText(item.getStringName());
                serialNumber.setText("");
                cellDesc.setText("Service: ");
                setStyle("-fx-background-color: lightblue;");
                setText("Service: " + item.getStringName());
            }else if(item instanceof TSPType){
                setGraphic(grid);
                cellName.setText(item.getStringName());
                serialNumber.setText("");
                cellDesc.setText("TSP: ");
                setText("TSP: " + item.getStringName());
                setStyle("-fx-background-color: bisque;");
            }else{
                GridPane pane = new GridPane();
                pane.add(innerVB, 0, 0);
                setGraphic(pane);
                setText(item.getStringName());
                serialNumber.setText("");
                setStyle("-fx-background-color: white;");
//              cellName.setText(item.getStringName());
            }
        }

    }

    public class OnMoveUp implements EventHandler<MouseEvent>{
         private final String STYLE_PRESSED = "-fx-background-color: transparent; -fx-padding: 3 1 1 3;";

        @SuppressWarnings("unchecked")
        @Override
        public void handle(MouseEvent event) {
            Button button = (Button)event.getSource();
            button.setStyle(STYLE_PRESSED);

            // get the table
            TreeTableView<ProviderAttribute> table = (TreeTableView<ProviderAttribute>)
                    button.getParent().getParent().getParent()
                    .getParent().getParent().getParent().getParent();

            // get the item
            TreeTableRow<ProviderAttribute> row = (TreeTableRow<ProviderAttribute>)
                    button.getParent().getParent().getParent();
            ProviderAttribute itemValue  = row.getItem();
            TreeItem<ProviderAttribute> item = row.getTreeItem();

            ObservableList<TreeItem<ProviderAttribute>> list = item.getParent().getChildren();

            if(item == null || list == null || list.size() <= 1) return;

            // swap the current item with the one above it
            int index = getIndexOf(list, itemValue);
            if(index > 0){
                Collections.swap(list, index, index-1);
                table.getSelectionModel().clearSelection();
            }
        }

    }

    public class OnMoveDown implements EventHandler<MouseEvent>{
         private final String STYLE_PRESSED = "-fx-background-color: transparent; -fx-padding: 3 1 1 3;";

        @SuppressWarnings("unchecked")
        @Override
        public void handle(MouseEvent event) {
            Button button = (Button)event.getSource();
            button.getGraphic().setOpacity(50);
            button.setStyle(STYLE_PRESSED);

            // get the table
            TreeTableView<ProviderAttribute> table = (TreeTableView<ProviderAttribute>)
                    button.getParent().getParent().getParent()
                    .getParent().getParent().getParent().getParent();

            // get the item
            TreeTableRow<ProviderAttribute> row = (TreeTableRow<ProviderAttribute>)
                    button.getParent().getParent().getParent();
            ProviderAttribute itemValue  = row.getItem();
            TreeItem<ProviderAttribute> item = row.getTreeItem();

            ObservableList<TreeItem<ProviderAttribute>> list = item.getParent().getChildren();
            if(item == null || list == null || list.size() <= 1) return;

            int index = getIndexOf(list, itemValue);
            if(index < list.size() - 1){
                Collections.swap(list, index, index+1);
                table.getSelectionModel().clearSelection();
            }
        }

    }

    public int getIndexOf(List<TreeItem<ProviderAttribute>> items, ProviderAttribute bean){
        int index = -1;
        for(int i = 0; i < items.size(); i++){
            if(items.get(i).getValue().equals(bean))
                return i;
        }

        return index;
    }

    public class ImageButton extends Button {
    private final String STYLE_NORMAL = "-fx-background-color: transparent; -fx-padding: 2, 2, 2, 2;";

    public ImageButton(ImageView image) {
        setGraphic(image);
        setStyle(STYLE_NORMAL);


        setOnMouseReleased(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
               setStyle(STYLE_NORMAL);
//               setOpacity(0);
            }            
        });
    }

}

//  public class EventHandler
}

TableTreeView (notice the contents of the first cell is not bold)

1 个答案:

答案 0 :(得分:1)

在重复使用单元格时,有时会使innerVB成为最后一个else子句中创建的新GridPane的子项;但innerVB已经是另一个父节点(grid的子节点,也可能是先前在同一个子句的先前调用中创建的网格窗格)。这违反了场景图的规则(一个节点只能是一个父节点的子节点),并且可能会使布局混淆得足以让您获得不可预测的显示。

你应该做

grid.getChildren().clear();

每次调用updateItem(),然后

grid.addRow(0, upButton, downButton, innerVB);

grid.addRow(0, innerVB);

根据需要。