Example usage for javafx.scene.control SelectionMode MULTIPLE

List of usage examples for javafx.scene.control SelectionMode MULTIPLE

Introduction

In this page you can find the example usage for javafx.scene.control SelectionMode MULTIPLE.

Prototype

SelectionMode MULTIPLE

To view the source code for javafx.scene.control SelectionMode MULTIPLE.

Click Source Link

Document

Allows for one or more contiguous range of indices to be selected at a time.

Usage

From source file:qupath.lib.gui.tma.TMASummaryViewer.java

private void initialize() {

    model = new TMATableModel();

    groupByIDProperty.addListener((v, o, n) -> refreshTableData());

    MenuBar menuBar = new MenuBar();
    Menu menuFile = new Menu("File");
    MenuItem miOpen = new MenuItem("Open...");
    miOpen.setAccelerator(new KeyCodeCombination(KeyCode.O, KeyCombination.SHORTCUT_DOWN));
    miOpen.setOnAction(e -> {//from   w w  w  . j  av  a 2s. c o m
        File file = QuPathGUI.getDialogHelper(stage).promptForFile(null, null, "TMA data files",
                new String[] { "qptma" });
        if (file == null)
            return;
        setInputFile(file);
    });

    MenuItem miSave = new MenuItem("Save As...");
    miSave.setAccelerator(
            new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN, KeyCombination.SHIFT_DOWN));
    miSave.setOnAction(
            e -> SummaryMeasurementTableCommand.saveTableModel(model, null, Collections.emptyList()));

    MenuItem miImportFromImage = new MenuItem("Import from current image...");
    miImportFromImage.setAccelerator(
            new KeyCodeCombination(KeyCode.I, KeyCombination.SHORTCUT_DOWN, KeyCombination.SHIFT_DOWN));
    miImportFromImage.setOnAction(e -> setTMAEntriesFromOpenImage());

    MenuItem miImportFromProject = new MenuItem("Import from current project... (experimental)");
    miImportFromProject.setAccelerator(
            new KeyCodeCombination(KeyCode.P, KeyCombination.SHORTCUT_DOWN, KeyCombination.SHIFT_DOWN));
    miImportFromProject.setOnAction(e -> setTMAEntriesFromOpenProject());

    MenuItem miImportClipboard = new MenuItem("Import from clipboard...");
    miImportClipboard.setOnAction(e -> {
        String text = Clipboard.getSystemClipboard().getString();
        if (text == null) {
            DisplayHelpers.showErrorMessage("Import scores", "Clipboard is empty!");
            return;
        }
        int n = importScores(text);
        if (n > 0) {
            setTMAEntries(new ArrayList<>(entriesBase));
        }
        DisplayHelpers.showMessageDialog("Import scores", "Number of scores imported: " + n);
    });

    Menu menuEdit = new Menu("Edit");
    MenuItem miCopy = new MenuItem("Copy table to clipboard");
    miCopy.setOnAction(e -> {
        SummaryMeasurementTableCommand.copyTableContentsToClipboard(model, Collections.emptyList());
    });

    combinedPredicate.addListener((v, o, n) -> {
        // We want any other changes triggered by this to have happened, 
        // so that the data has already been updated
        Platform.runLater(() -> handleTableContentChange());
    });

    // Reset the scores for missing cores - this ensures they will be NaN and not influence subsequent results
    MenuItem miResetMissingScores = new MenuItem("Reset scores for missing cores");
    miResetMissingScores.setOnAction(e -> {
        int changes = 0;
        for (TMAEntry entry : entriesBase) {
            if (!entry.isMissing())
                continue;
            boolean changed = false;
            for (String m : entry.getMeasurementNames().toArray(new String[0])) {
                if (!TMASummaryEntry.isSurvivalColumn(m) && !Double.isNaN(entry.getMeasurementAsDouble(m))) {
                    entry.putMeasurement(m, null);
                    changed = true;
                }
            }
            if (changed)
                changes++;
        }
        if (changes == 0) {
            logger.info("No changes made when resetting scores for missing cores!");
            return;
        }
        logger.info("{} change(s) made when resetting scores for missing cores!", changes);
        table.refresh();
        updateSurvivalCurves();
        if (scatterPane != null)
            scatterPane.updateChart();
        if (histogramDisplay != null)
            histogramDisplay.refreshHistogram();
    });
    menuEdit.getItems().add(miResetMissingScores);

    QuPathGUI.addMenuItems(menuFile, miOpen, miSave, null, miImportClipboard, null, miImportFromImage,
            miImportFromProject);
    menuBar.getMenus().add(menuFile);
    menuEdit.getItems().add(miCopy);
    menuBar.getMenus().add(menuEdit);

    menuFile.setOnShowing(e -> {
        boolean imageDataAvailable = QuPathGUI.getInstance() != null
                && QuPathGUI.getInstance().getImageData() != null
                && QuPathGUI.getInstance().getImageData().getHierarchy().getTMAGrid() != null;
        miImportFromImage.setDisable(!imageDataAvailable);
        boolean projectAvailable = QuPathGUI.getInstance() != null
                && QuPathGUI.getInstance().getProject() != null
                && !QuPathGUI.getInstance().getProject().getImageList().isEmpty();
        miImportFromProject.setDisable(!projectAvailable);
    });

    // Double-clicking previously used for comments... but conflicts with tree table expansion
    //      table.setOnMouseClicked(e -> {
    //         if (!e.isPopupTrigger() && e.getClickCount() > 1)
    //            promptForComment();
    //      });

    table.setPlaceholder(new Text("Drag TMA data folder onto window, or choose File -> Open"));
    table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

    BorderPane pane = new BorderPane();
    pane.setTop(menuBar);
    menuBar.setUseSystemMenuBar(true);

    // Create options
    ToolBar toolbar = new ToolBar();
    Label labelMeasurementMethod = new Label("Combination method");
    labelMeasurementMethod.setLabelFor(comboMeasurementMethod);
    labelMeasurementMethod
            .setTooltip(new Tooltip("Method whereby measurements for multiple cores with the same "
                    + TMACoreObject.KEY_UNIQUE_ID + " will be combined"));

    CheckBox cbHidePane = new CheckBox("Hide pane");
    cbHidePane.setSelected(hidePaneProperty.get());
    cbHidePane.selectedProperty().bindBidirectional(hidePaneProperty);

    CheckBox cbGroupByID = new CheckBox("Group by ID");
    entriesBase.addListener((Change<? extends TMAEntry> event) -> {
        if (!event.getList().stream().anyMatch(e -> e.getMetadataValue(TMACoreObject.KEY_UNIQUE_ID) != null)) {
            cbGroupByID.setSelected(false);
            cbGroupByID.setDisable(true);
        } else {
            cbGroupByID.setDisable(false);
        }
    });
    cbGroupByID.setSelected(groupByIDProperty.get());
    cbGroupByID.selectedProperty().bindBidirectional(groupByIDProperty);

    CheckBox cbUseSelected = new CheckBox("Use selection only");
    cbUseSelected.selectedProperty().bindBidirectional(useSelectedProperty);

    CheckBox cbSkipMissing = new CheckBox("Hide missing cores");
    cbSkipMissing.selectedProperty().bindBidirectional(skipMissingCoresProperty);
    skipMissingCoresProperty.addListener((v, o, n) -> {
        table.refresh();
        updateSurvivalCurves();
        if (histogramDisplay != null)
            histogramDisplay.refreshHistogram();
        updateSurvivalCurves();
        if (scatterPane != null)
            scatterPane.updateChart();
    });

    toolbar.getItems().addAll(labelMeasurementMethod, comboMeasurementMethod,
            new Separator(Orientation.VERTICAL), cbHidePane, new Separator(Orientation.VERTICAL), cbGroupByID,
            new Separator(Orientation.VERTICAL), cbUseSelected, new Separator(Orientation.VERTICAL),
            cbSkipMissing);
    comboMeasurementMethod.getItems().addAll(MeasurementCombinationMethod.values());
    comboMeasurementMethod.getSelectionModel().select(MeasurementCombinationMethod.MEDIAN);
    selectedMeasurementCombinationProperty.addListener((v, o, n) -> table.refresh());

    ContextMenu popup = new ContextMenu();
    MenuItem miSetMissing = new MenuItem("Set missing");
    miSetMissing.setOnAction(e -> setSelectedMissingStatus(true));

    MenuItem miSetAvailable = new MenuItem("Set available");
    miSetAvailable.setOnAction(e -> setSelectedMissingStatus(false));

    MenuItem miExpand = new MenuItem("Expand all");
    miExpand.setOnAction(e -> {
        if (table.getRoot() == null)
            return;
        for (TreeItem<?> item : table.getRoot().getChildren()) {
            item.setExpanded(true);
        }
    });
    MenuItem miCollapse = new MenuItem("Collapse all");
    miCollapse.setOnAction(e -> {
        if (table.getRoot() == null)
            return;
        for (TreeItem<?> item : table.getRoot().getChildren()) {
            item.setExpanded(false);
        }
    });
    popup.getItems().addAll(miSetMissing, miSetAvailable, new SeparatorMenuItem(), miExpand, miCollapse);
    table.setContextMenu(popup);

    table.setRowFactory(e -> {
        TreeTableRow<TMAEntry> row = new TreeTableRow<>();

        //         // Make rows invisible if they don't pass the predicate
        //         row.visibleProperty().bind(Bindings.createBooleanBinding(() -> {
        //               TMAEntry entry = row.getItem();
        //               if (entry == null || (entry.isMissing() && skipMissingCoresProperty.get()))
        //                     return false;
        //               return entries.getPredicate() == null || entries.getPredicate().test(entry);
        //               },
        //               skipMissingCoresProperty,
        //               entries.predicateProperty()));

        // Style rows according to what they contain
        row.styleProperty().bind(Bindings.createStringBinding(() -> {
            if (row.isSelected())
                return "";
            TMAEntry entry = row.getItem();
            if (entry == null || entry instanceof TMASummaryEntry)
                return "";
            else if (entry.isMissing())
                return "-fx-background-color:rgb(225,225,232)";
            else
                return "-fx-background-color:rgb(240,240,245)";
        }, row.itemProperty(), row.selectedProperty()));
        //         row.itemProperty().addListener((v, o, n) -> {
        //            if (n == null || n instanceof TMASummaryEntry || row.isSelected())
        //               row.setStyle("");
        //            else if (n.isMissing())
        //               row.setStyle("-fx-background-color:rgb(225,225,232)");            
        //            else
        //               row.setStyle("-fx-background-color:rgb(240,240,245)");            
        //         });
        return row;
    });

    BorderPane paneTable = new BorderPane();
    paneTable.setTop(toolbar);
    paneTable.setCenter(table);

    MasterDetailPane mdTablePane = new MasterDetailPane(Side.RIGHT, paneTable, createSidePane(), true);

    mdTablePane.showDetailNodeProperty().bind(Bindings.createBooleanBinding(
            () -> !hidePaneProperty.get() && !entriesBase.isEmpty(), hidePaneProperty, entriesBase));
    mdTablePane.setDividerPosition(2.0 / 3.0);

    pane.setCenter(mdTablePane);

    model.getEntries().addListener(new ListChangeListener<TMAEntry>() {
        @Override
        public void onChanged(ListChangeListener.Change<? extends TMAEntry> c) {
            if (histogramDisplay != null)
                histogramDisplay.refreshHistogram();
            updateSurvivalCurves();
            if (scatterPane != null)
                scatterPane.updateChart();
        }
    });

    Label labelPredicate = new Label();
    labelPredicate.setPadding(new Insets(5, 5, 5, 5));
    labelPredicate.setAlignment(Pos.CENTER);
    //      labelPredicate.setStyle("-fx-background-color: rgba(20, 120, 20, 0.15);");
    labelPredicate.setStyle("-fx-background-color: rgba(120, 20, 20, 0.15);");

    labelPredicate.textProperty().addListener((v, o, n) -> {
        if (n.trim().length() > 0)
            pane.setBottom(labelPredicate);
        else
            pane.setBottom(null);
    });
    labelPredicate.setMaxWidth(Double.MAX_VALUE);
    labelPredicate.setMaxHeight(labelPredicate.getPrefHeight());
    labelPredicate.setTextAlignment(TextAlignment.CENTER);
    predicateMeasurements.addListener((v, o, n) -> {
        if (n == null)
            labelPredicate.setText("");
        else if (n instanceof TablePredicate) {
            TablePredicate tp = (TablePredicate) n;
            if (tp.getOriginalCommand().trim().isEmpty())
                labelPredicate.setText("");
            else
                labelPredicate.setText("Predicate: " + tp.getOriginalCommand());
        } else
            labelPredicate.setText("Predicate: " + n.toString());
    });
    //      predicate.set(new TablePredicate("\"Tumor\" > 100"));

    scene = new Scene(pane);

    scene.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
        KeyCode code = e.getCode();
        if ((code == KeyCode.SPACE || code == KeyCode.ENTER) && entrySelected != null) {
            promptForComment();
            return;
        }
    });

}

From source file:qupath.lib.gui.tma.TMASummaryViewer.java

private Pane getCustomizeTablePane() {
    TableView<TreeTableColumn<TMAEntry, ?>> tableColumns = new TableView<>();
    tableColumns.setPlaceholder(new Text("No columns available"));
    tableColumns.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    tableColumns.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

    SortedList<TreeTableColumn<TMAEntry, ?>> sortedColumns = new SortedList<>(
            table.getColumns().filtered(p -> !p.getText().trim().isEmpty()));
    sortedColumns.setComparator((c1, c2) -> c1.getText().compareTo(c2.getText()));
    tableColumns.setItems(sortedColumns);
    sortedColumns.comparatorProperty().bind(tableColumns.comparatorProperty());
    //      sortedColumns.comparatorProperty().bind(tableColumns.comparatorProperty());

    TableColumn<TreeTableColumn<TMAEntry, ?>, String> columnName = new TableColumn<>("Column");
    columnName.setCellValueFactory(v -> v.getValue().textProperty());
    TableColumn<TreeTableColumn<TMAEntry, ?>, Boolean> columnVisible = new TableColumn<>("Visible");
    columnVisible.setCellValueFactory(v -> v.getValue().visibleProperty());
    //      columnVisible.setCellValueFactory(col -> {
    //         SimpleBooleanProperty prop = new SimpleBooleanProperty(col.getValue().isVisible());
    //         prop.addListener((v, o, n) -> col.getValue().setVisible(n));
    //         return prop;
    //      });// www .jav  a  2  s  .  c o m
    tableColumns.setEditable(true);
    columnVisible.setCellFactory(v -> new CheckBoxTableCell<>());
    tableColumns.getColumns().add(columnName);
    tableColumns.getColumns().add(columnVisible);
    ContextMenu contextMenu = new ContextMenu();

    Action actionShowSelected = new Action("Show selected", e -> {
        for (TreeTableColumn<?, ?> col : tableColumns.getSelectionModel().getSelectedItems()) {
            if (col != null)
                col.setVisible(true);
            else {
                // Not sure why this happens...?
                logger.trace("Selected column is null!");
            }
        }
    });

    Action actionHideSelected = new Action("Hide selected", e -> {
        for (TreeTableColumn<?, ?> col : tableColumns.getSelectionModel().getSelectedItems()) {
            if (col != null)
                col.setVisible(false);
            else {
                // Not sure why this happens...?
                logger.trace("Selected column is null!");
            }
        }
    });

    contextMenu.getItems().addAll(ActionUtils.createMenuItem(actionShowSelected),
            ActionUtils.createMenuItem(actionHideSelected));
    tableColumns.setContextMenu(contextMenu);
    tableColumns.setTooltip(
            new Tooltip("Show or hide table columns - right-click to change multiple columns at once"));

    BorderPane paneColumns = new BorderPane(tableColumns);
    paneColumns.setBottom(PanelToolsFX.createColumnGridControls(ActionUtils.createButton(actionShowSelected),
            ActionUtils.createButton(actionHideSelected)));

    VBox paneRows = new VBox();

    // Create a box to filter on some metadata text
    ComboBox<String> comboMetadata = new ComboBox<>();
    comboMetadata.setItems(metadataNames);
    comboMetadata.getSelectionModel().getSelectedItem();
    comboMetadata.setPromptText("Select column");
    TextField tfFilter = new TextField();
    CheckBox cbExact = new CheckBox("Exact");
    // Set listeners
    cbExact.selectedProperty().addListener(
            (v, o, n) -> setMetadataTextPredicate(comboMetadata.getSelectionModel().getSelectedItem(),
                    tfFilter.getText(), cbExact.isSelected(), !cbExact.isSelected()));
    tfFilter.textProperty().addListener(
            (v, o, n) -> setMetadataTextPredicate(comboMetadata.getSelectionModel().getSelectedItem(),
                    tfFilter.getText(), cbExact.isSelected(), !cbExact.isSelected()));
    comboMetadata.getSelectionModel().selectedItemProperty().addListener(
            (v, o, n) -> setMetadataTextPredicate(comboMetadata.getSelectionModel().getSelectedItem(),
                    tfFilter.getText(), cbExact.isSelected(), !cbExact.isSelected()));

    GridPane paneMetadata = new GridPane();
    paneMetadata.add(comboMetadata, 0, 0);
    paneMetadata.add(tfFilter, 1, 0);
    paneMetadata.add(cbExact, 2, 0);
    paneMetadata.setPadding(new Insets(10, 10, 10, 10));
    paneMetadata.setVgap(2);
    paneMetadata.setHgap(5);
    comboMetadata.setMaxWidth(Double.MAX_VALUE);
    GridPane.setHgrow(tfFilter, Priority.ALWAYS);
    GridPane.setFillWidth(comboMetadata, Boolean.TRUE);
    GridPane.setFillWidth(tfFilter, Boolean.TRUE);

    TitledPane tpMetadata = new TitledPane("Metadata filter", paneMetadata);
    tpMetadata.setExpanded(false);
    //      tpMetadata.setCollapsible(false);
    Tooltip tooltipMetadata = new Tooltip(
            "Enter text to filter entries according to a selected metadata column");
    Tooltip.install(paneMetadata, tooltipMetadata);
    tpMetadata.setTooltip(tooltipMetadata);
    paneRows.getChildren().add(tpMetadata);

    // Add measurement predicate
    TextField tfCommand = new TextField();
    tfCommand.setTooltip(new Tooltip("Predicate used to filter entries for inclusion"));

    TextFields.bindAutoCompletion(tfCommand, e -> {
        int ind = tfCommand.getText().lastIndexOf("\"");
        if (ind < 0)
            return Collections.emptyList();
        String part = tfCommand.getText().substring(ind + 1);
        return measurementNames.stream().filter(n -> n.startsWith(part)).map(n -> "\"" + n + "\" ")
                .collect(Collectors.toList());
    });

    String instructions = "Enter a predicate to filter entries.\n"
            + "Only entries passing the test will be included in any results.\n"
            + "Examples of predicates include:\n" + "    \"Num Tumor\" > 200\n"
            + "    \"Num Tumor\" > 100 && \"Num Stroma\" < 1000";
    //      labelInstructions.setTooltip(new Tooltip("Note: measurement names must be in \"inverted commands\" and\n" + 
    //            "&& indicates 'and', while || indicates 'or'."));

    BorderPane paneMeasurementFilter = new BorderPane(tfCommand);
    Label label = new Label("Predicate: ");
    label.setAlignment(Pos.CENTER);
    label.setMaxHeight(Double.MAX_VALUE);
    paneMeasurementFilter.setLeft(label);

    Button btnApply = new Button("Apply");
    btnApply.setOnAction(e -> {
        TablePredicate predicateNew = new TablePredicate(tfCommand.getText());
        if (predicateNew.isValid()) {
            predicateMeasurements.set(predicateNew);
        } else {
            DisplayHelpers.showErrorMessage("Invalid predicate",
                    "Current predicate '" + tfCommand.getText() + "' is invalid!");
        }
        e.consume();
    });
    TitledPane tpMeasurementFilter = new TitledPane("Measurement filter", paneMeasurementFilter);
    tpMeasurementFilter.setExpanded(false);
    Tooltip tooltipInstructions = new Tooltip(instructions);
    tpMeasurementFilter.setTooltip(tooltipInstructions);
    Tooltip.install(paneMeasurementFilter, tooltipInstructions);
    paneMeasurementFilter.setRight(btnApply);

    paneRows.getChildren().add(tpMeasurementFilter);

    logger.info("Predicate set to: {}", predicateMeasurements.get());

    VBox pane = new VBox();
    //      TitledPane tpColumns = new TitledPane("Select column", paneColumns);
    //      tpColumns.setMaxHeight(Double.MAX_VALUE);
    //      tpColumns.setCollapsible(false);
    pane.getChildren().addAll(paneColumns, new Separator(), paneRows);
    VBox.setVgrow(paneColumns, Priority.ALWAYS);

    return pane;
}

From source file:spdxedit.PackageEditor.java

@FXML
private void initialize() {
    assert tabFiles != null : "fx:id=\"tabFiles\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert tabPackageProperties != null : "fx:id=\"tabPackageProperties\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert tabExternalRefs != null : "fx:id=\"tabExternalRefs\" was not injected: check your FXML file 'PackageEditor.fxml'.";

    assert filesTable != null : "fx:id=\"filesTable\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert tblColumnFile != null : "fx:id=\"tblColumnFile\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkListFileTypes != null : "fx:id=\"chkListFileTypes\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert tabRelationships != null : "fx:id=\"tabRelationships\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnOk != null : "fx:id=\"btnOk\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnDeleteFileFromPackage != null : "fx:id=\"btnDeleteFileFromPackage\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnAddFile != null : "fx:id=\"btnAddFile\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnCopyright != null : "fx:id=\"btnCopyright\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnFileLicense != null : "fx:id=\"btnFileLicense\" was not injected: check your FXML file 'PackageEditor.fxml'.";

    //File relationship checkboxes
    assert chkDataFile != null : "fx:id=\"chkDataFile\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkTestCase != null : "fx:id=\"chkTestCase\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkDocumentation != null : "fx:id=\"chkDocumentation\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkOptionalComponent != null : "fx:id=\"chkOptionalComponent\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkMetafile != null : "fx:id=\"chkMetafile\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkBuildTool != null : "fx:id=\"chkBuildTool\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chkExcludeFile != null : "fx:id=\"chkExcludeFile\" was not injected: check your FXML file 'PackageEditor.fxml'.";

    //Initialise file relationship checkbox handling
    //TODO: Could make this easier by extending the CheckBox control?
    chkDataFile.selectedProperty().addListener((observable, oldValue,
            newValue) -> addOrRemoveFileRelationshipToPackage(RelationshipType.DATA_FILE_OF, newValue));
    chkTestCase.selectedProperty().addListener((observable, oldValue,
            newValue) -> addOrRemoveFileRelationshipToPackage(RelationshipType.TEST_CASE_OF, newValue));
    chkDocumentation.selectedProperty().addListener((observable, oldValue,
            newValue) -> addOrRemoveFileRelationshipToPackage(RelationshipType.DOCUMENTATION_OF, newValue));
    chkOptionalComponent.selectedProperty()
            .addListener((observable, oldValue, newValue) -> addOrRemoveFileRelationshipToPackage(
                    RelationshipType.OPTIONAL_COMPONENT_OF, newValue));
    chkMetafile.selectedProperty().addListener((observable, oldValue,
            newValue) -> addOrRemoveFileRelationshipToPackage(RelationshipType.METAFILE_OF, newValue));
    chkBuildTool.selectedProperty().addListener((observable, oldValue,
            newValue) -> addOrRemoveFileRelationshipToPackage(RelationshipType.BUILD_TOOL_OF, newValue));
    chkExcludeFile.selectedProperty()// www  .  j  a va 2s  . c  o  m
            .addListener((observable, oldValue, newValue) -> handleChkExcludeFileChange(newValue));

    //Package relationship controls
    assert lstTargetPackages != null : "fx:id=\"lstTargetPackages\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert chcNewRelationshipType != null : "fx:id=\"chcNewRelationshipType\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnAddRelationship != null : "fx:id=\"btnAddRelationship\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert btnRemoveRelationship != null : "fx:id=\"btnRemoveRelationship\" was not injected: check your FXML file 'PackageEditor.fxml'.";

    //Initialize package relationship controls
    lstTargetPackages.getSelectionModel().selectedItemProperty()
            .addListener((observable1, oldValue1, newValue1) -> handleTargetPackageSelected(newValue1));
    lstTargetPackages.setCellFactory(listView -> new MainSceneController.SpdxPackageListCell());
    lstPackageRelationships.getSelectionModel().selectedItemProperty().addListener(
            (observable1, oldValue1, newValue1) -> btnRemoveRelationship.setDisable(newValue1 == null));
    //Package relationship types
    chcNewRelationshipType.setConverter(RELATIONSHIP_TYPE_STRING_CONVERTER);
    chcNewRelationshipType.getItems()
            .setAll(Stream.of(RelationshipType.AMENDS, RelationshipType.DESCENDANT_OF,
                    RelationshipType.DYNAMIC_LINK, RelationshipType.GENERATED_FROM, RelationshipType.GENERATES,
                    RelationshipType.HAS_PREREQUISITE, RelationshipType.PREREQUISITE_FOR,
                    RelationshipType.STATIC_LINK, RelationshipType.OTHER).collect(Collectors.toList()));
    chcNewRelationshipType.getSelectionModel().selectFirst();
    assert (otherPackages != null); //Constructor finished executing
    lstTargetPackages.getItems().setAll(otherPackages);

    //Package license editor
    assert tabPkgLicenses != null : "fx:id=\"tabPkgLicenses\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert tabPkgDeclaredLicense != null : "fx:id=\"tabPkgDeclaredLicense\" was not injected: check your FXML file 'PackageEditor.fxml'.";
    assert tabPkgConcludedLicense != null : "fx:id=\"tabPkgConcludedLicense\" was not injected: check your FXML file 'PackageEditor.fxml'.";

    pkgConcludedLicenseEdit = new LicenseEditControl(documentContainer);
    pkgConcludedLicenseEdit.setInitialValue(pkg.getLicenseConcluded());
    pkgConcludedLicenseEdit
            .setOnLicenseChange(license -> SpdxWithoutExeption.setLicenseConcluded(pkg, license));
    tabPkgConcludedLicense.setContent(pkgConcludedLicenseEdit.getUi());
    pkgDeclaredLicenseEdit = new LicenseEditControl(documentContainer);
    pkgDeclaredLicenseEdit.setInitialValue(SpdxWithoutExeption.getLicenseDeclared(pkg));
    pkgDeclaredLicenseEdit.setOnLicenseChange(license -> SpdxWithoutExeption.setLicenseDeclared(pkg, license));
    tabPkgDeclaredLicense.setContent(pkgDeclaredLicenseEdit.getUi());

    //Initialize other elements
    tblColumnFile.setCellValueFactory(
            (TreeTableColumn.CellDataFeatures<SpdxFile, String> param) -> new ReadOnlyStringWrapper(
                    param.getValue().getValue().getName()));
    //Load all file types into the file type list in order.
    chkListFileTypes.getItems().setAll(Stream.of(FileType.values()).sorted(Ordering.usingToString()) //Sort
            .map(fileType -> StringableWrapper.wrap(fileType, SpdxLogic::toString)) //Wrap so that the nice toString function gets used by the checkbox
            .collect(Collectors.toList()));
    chkListFileTypes.getCheckModel().getCheckedItems().addListener(this::handleFileTypeCheckedOrUnchecked);
    filesTable.getSelectionModel().selectedItemProperty()
            .addListener((observable, oldValue, newValue) -> handleFileSelected(newValue));
    filesTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    filesTable.setShowRoot(false);

    AnchorPane externalRefControl = new ExternalRefListControl(pkg).getUi();
    externalRefControl.setPadding(new Insets(12, 10, 5, 10));
    tabExternalRefs.setContent(externalRefControl);
    externalRefControl.setManaged(true);

    new PackagePropertyEditor(pkg).initialize(tabPackageProperties);

}