Search in sources :

Example 1 with ColorMaps

use of qupath.lib.color.ColorMaps in project qupath by qupath.

the class ViewTrackerAnalysisCommand method run.

@Override
public void run() {
    if (dialog == null) {
        dialog = new Stage();
        dialog.sizeToScene();
        dialog.initOwner(qupath.getStage());
        dialog.setTitle("Recording analysis");
        currentFrame.set(tracker.getFrame(0));
        int nCols = nCols(tracker);
        for (int i = 0; i < nCols; i++) {
            final int col = i;
            final String columnName = getColumnName(tracker, col);
            TableColumn<ViewRecordingFrame, Object> column = new TableColumn<>(columnName);
            column.setCellValueFactory(new Callback<CellDataFeatures<ViewRecordingFrame, Object>, ObservableValue<Object>>() {

                @Override
                public ObservableValue<Object> call(CellDataFeatures<ViewRecordingFrame, Object> frame) {
                    return new SimpleObjectProperty<>(getColumnValue(frame.getValue(), columnName));
                }
            });
            table.getColumns().add(column);
        }
        table.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        table.getSelectionModel().selectedItemProperty().addListener((v, o, frame) -> {
            if (frame != null)
                currentFrame.set(frame);
        });
        refreshTracker();
        playback.getCurrentFrame().addListener((v, o, frame) -> currentFrame.set(frame));
        currentFrame.addListener((v, o, frame) -> {
            if (frame == null)
                return;
            // Set viewer for frame
            ViewTrackerPlayback.setViewerForFrame(viewer, frame);
            // Set slide overview for frame
            slideOverview.setVisibleShape(frame);
            zSlider.setValue(frame.getZ());
            tSlider.setValue(frame.getT());
            timeSlider.setValue(frame.getTimestamp());
            slideOverview.paintCanvas(o.getZ() != frame.getZ() || o.getT() != frame.getT(), false);
        });
        mainPane = new SplitPane();
        mainPane.setDividerPositions(1.0);
        BorderPane tablePane = new BorderPane();
        tablePane.setCenter(table);
        // ----------------------------------------------------------------------//
        // ----------------- SLIDE OVERVIEW (TOP LEFT)------------------//
        // ----------------------------------------------------------------------//
        int z = server.getMetadata().getSizeZ();
        int t = server.getMetadata().getSizeT();
        tSlider = new Slider(0, t - 1, 0);
        tSlider.setBlockIncrement(1);
        tSlider.setValue(viewer.getTPosition());
        tSlider.valueProperty().addListener((v, o, n) -> {
            tSlider.setValue(n.intValue());
            viewer.setTPosition(n.intValue());
            slideOverview.paintCanvas();
        });
        zSlider = new Slider(0, z - 1, 0);
        zSlider.setBlockIncrement(1);
        zSlider.setMinorTickCount(0);
        zSlider.setMajorTickUnit(1);
        zSlider.setShowTickMarks(true);
        zSlider.setValue(viewer.getZPosition());
        zSlider.valueProperty().addListener((v, o, n) -> {
            zSlider.setValue(n.intValue());
            viewer.setZPosition(n.intValue());
            slideOverview.paintCanvas();
        });
        zSlider.setOrientation(Orientation.VERTICAL);
        var timeSliderLength = tracker.getLastTime() - tracker.getStartTime();
        timeSlider = new Slider(0L, timeSliderLength, 0L);
        timeSlider.setMinWidth(250.0);
        if (timeSliderLength > 0) {
            timeSlider.setMajorTickUnit(timeSliderLength / 4);
            timeSlider.setMinorTickCount(0);
            timeSlider.setShowTickMarks(true);
        }
        timeSlider.valueProperty().addListener((v, o, n) -> {
            var frame = tracker.getFrameForTime(n.longValue());
            currentFrame.set(frame);
            if (table.getSelectionModel().getSelectedItem() != frame)
                table.getSelectionModel().select(frame);
        });
        timeSlider.setOnMouseClicked(e -> {
            playback.doStopPlayback();
        });
        long startTime = tracker.getStartTime();
        long endTime = tracker.getLastTime();
        Label timepointLabel = new Label();
        timepointLabel.textProperty().bind(Bindings.createStringBinding(() -> "t=" + GeneralTools.formatNumber(tSlider.getValue(), 2), tSlider.valueProperty()));
        Label zSliceLabel = new Label();
        zSliceLabel.textProperty().bind(Bindings.createStringBinding(() -> "z=" + GeneralTools.formatNumber(zSlider.getValue(), 2), zSlider.valueProperty()));
        Label timeLabelLeft = new Label();
        timeLabelLeft.textProperty().bind(Bindings.createStringBinding(() -> ViewTrackerTools.getPrettyTimestamp(startTime, (long) timeSlider.getValue() + startTime), timeSlider.valueProperty()));
        Label timeLabelRight = new Label();
        timeLabelRight.textProperty().bind(Bindings.createStringBinding(() -> "-" + ViewTrackerTools.getPrettyTimestamp((long) timeSlider.getValue() + startTime, endTime), timeSlider.valueProperty()));
        if (t == 1) {
            tSlider.setVisible(false);
            timepointLabel.setVisible(false);
        }
        if (z == 1) {
            zSlider.setVisible(false);
            zSliceLabel.setVisible(false);
        }
        Button btnPlay = new Button();
        btnPlay.setGraphic(iconPlay);
        btnPlay.setOnAction(e -> {
            if (!playback.isPlaying()) {
                // If it's not playing already, start playing
                playback.setFirstFrame(currentFrame.get());
                // Set the right slide overview image plane and visible shape for current frame
                slideOverview.paintCanvas();
                playback.doStartPlayback();
            } else {
                // If already playing, pause the playback where it currently is
                playback.doStopPlayback();
            }
        });
        Button btnStop = new Button();
        btnStop.setGraphic(iconStop);
        btnStop.setOnAction(e -> {
            playback.doStopPlayback();
            timeSlider.setValue(tracker.getFrame(0).getTimestamp());
        });
        // If we have a total of 0 or 1 frame in recording, disable playback
        btnPlay.disableProperty().bind(new SimpleBooleanProperty(tracker.nFrames() <= 1));
        btnStop.disableProperty().bind(new SimpleBooleanProperty(tracker.nFrames() <= 1));
        playback.playingProperty().addListener((v, o, n) -> {
            if (n) {
                btnPlay.setGraphic(iconPause);
                // btnPlay.setText("Pause");
                zSlider.setDisable(true);
                tSlider.setDisable(true);
            } else {
                btnPlay.setGraphic(iconPlay);
                // btnPlay.setText("Play");
                zSlider.setDisable(false);
                tSlider.setDisable(false);
            }
        });
        // --------------------------------------------------------------//
        // ----------- DATA VISUALIZATION PANE ---------------//
        // --------------------------------------------------------------//
        visualizationCheckBox = new CheckBox("Enable data overlay");
        // Label normalizedByLabel = new Label("Normalized by");
        // Bound below in the Binding section
        progressIndicator = new ProgressIndicator();
        progressIndicator.setPrefSize(15, 15);
        // ToggleGroup toggleGroup = new ToggleGroup();
        // timeNormalizedRadio = new RadioButton("Time");
        // timeNormalizedRadio.setSelected(true);
        // timeNormalizedRadio.setToggleGroup(toggleGroup);
        // 
        // downsampleNormalizedRadio = new RadioButton("Downsample");
        // downsampleNormalizedRadio.setToggleGroup(toggleGroup);
        // Create a color mapper ComboBox
        colorMaps = FXCollections.observableArrayList(ColorMaps.getColorMaps().values());
        ComboBox<ColorMap> colorMapCombo = new ComboBox<>(colorMaps);
        colorMapCombo.setMinWidth(350);
        colorMapCanvas = new ColorMapCanvas(10, colorMaps.get(0));
        colorMapCombo.getSelectionModel().selectedItemProperty().addListener((v, o, n) -> colorMapCanvas.setColorMap(n));
        if (colorMapCombo.getSelectionModel().isEmpty() && !colorMapCombo.getItems().isEmpty())
            colorMapCombo.getSelectionModel().selectFirst();
        colorMapCombo.setTooltip(new Tooltip("Select color map"));
        // ------------------ TIME DISPLAYED RANGESLIDER ------------------//
        Label timeDisplayedLeftLabel = new Label();
        Label timeDisplayedRightLabel = new Label();
        timeDisplayedSlider = new RangeSlider(0, timeSliderLength, 0, timeSliderLength);
        timeDisplayedSlider.setMinWidth(250.0);
        // Prompt input from user (min time)
        timeDisplayedLeftLabel.setOnMouseClicked(e -> {
            if (e.getButton().equals(MouseButton.PRIMARY) && e.getClickCount() == 2) {
                GridPane gp = new GridPane();
                TextField tf = new TextField();
                SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
                try {
                    tf.setTextFormatter(new TextFormatter<>(new DateTimeStringConverter(format), format.parse("00:00:00")));
                } catch (ParseException ex) {
                    logger.error("Error parsing the input time: ", ex.getLocalizedMessage());
                }
                gp.addRow(0, new Label("Enter time"), tf);
                var response = Dialogs.showConfirmDialog("Set min time", gp);
                if (response) {
                    long time = TimeUnit.HOURS.toMillis(Integer.parseInt(tf.getText(0, 2))) + TimeUnit.MINUTES.toMillis(Integer.parseInt(tf.getText(3, 5))) + TimeUnit.SECONDS.toMillis(Integer.parseInt(tf.getText(6, 8)));
                    timeDisplayedSlider.setLowValue(time);
                    updateOverlays();
                }
            }
        });
        // Prompt input from user (max time)
        timeDisplayedRightLabel.setOnMouseClicked(e -> {
            if (e.getButton().equals(MouseButton.PRIMARY) && e.getClickCount() == 2) {
                GridPane gp = new GridPane();
                TextField tf = new TextField();
                SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
                try {
                    tf.setTextFormatter(new TextFormatter<>(new DateTimeStringConverter(format), format.parse(ViewTrackerTools.getPrettyTimestamp((long) timeDisplayedSlider.getHighValue()))));
                } catch (ParseException ex) {
                    logger.error("Error parsing the input time: ", ex.getLocalizedMessage());
                }
                gp.addRow(0, new Label("Enter time"), tf);
                var response = Dialogs.showConfirmDialog("Set max time", gp);
                if (response) {
                    long time = ViewTrackerTools.getTimestampFromPrettyString(tf.getText());
                    timeDisplayedSlider.setHighValue(time);
                    updateOverlays();
                }
            }
        });
        timeDisplayedLeftLabel.textProperty().bind(Bindings.createStringBinding(() -> ViewTrackerTools.getPrettyTimestamp(startTime, (long) timeDisplayedSlider.getLowValue() + startTime), timeDisplayedSlider.lowValueProperty()));
        timeDisplayedRightLabel.textProperty().bind(Bindings.createStringBinding(() -> ViewTrackerTools.getPrettyTimestamp(startTime, (long) timeDisplayedSlider.getHighValue() + startTime), timeDisplayedSlider.highValueProperty()));
        // ------------------ DOWNSAMPLE RANGESLIDER ------------------//
        List<Double> allFramesDownsamples = tracker.getAllFrames().stream().map(e -> e.getDownsampleFactor()).collect(Collectors.toList());
        var minDownsample = allFramesDownsamples.stream().min(Comparator.naturalOrder()).get();
        var maxDownsample = allFramesDownsamples.stream().max(Comparator.naturalOrder()).get();
        downsampleSlider = new RangeSlider(minDownsample, maxDownsample, minDownsample, maxDownsample);
        Label downsampleLeftLabel = new Label();
        Label downsampleRightLabel = new Label();
        // Prompt input from user (min downsample)
        downsampleLeftLabel.setOnMouseClicked(e -> {
            if (e.getButton().equals(MouseButton.PRIMARY) && e.getClickCount() == 2) {
                ParameterList params = new ParameterList();
                params.addDoubleParameter("downsampleFilterLow", "Enter downsample", downsampleSlider.getLowValue());
                if (!Dialogs.showParameterDialog("Set min downsample", params))
                    return;
                double downFactor = params.getDoubleParameterValue("downsampleFilterLow");
                downsampleSlider.setLowValue(downFactor);
                updateOverlays();
            }
        });
        // Prompt input from user (max downsample)
        downsampleRightLabel.setOnMouseClicked(e -> {
            if (e.getButton().equals(MouseButton.PRIMARY) && e.getClickCount() == 2) {
                ParameterList params = new ParameterList();
                params.addDoubleParameter("downsampleFilterHigh", "Enter downsample", downsampleSlider.getHighValue());
                if (!Dialogs.showParameterDialog("Set max downsample", params))
                    return;
                double downFactor = params.getDoubleParameterValue("downsampleFilterHigh");
                downsampleSlider.setHighValue(downFactor);
                updateOverlays();
            }
        });
        downsampleLeftLabel.textProperty().bind(Bindings.createStringBinding(() -> GeneralTools.formatNumber(downsampleSlider.getLowValue(), 2), downsampleSlider.lowValueProperty()));
        downsampleRightLabel.textProperty().bind(Bindings.createStringBinding(() -> GeneralTools.formatNumber(downsampleSlider.getHighValue(), 2), downsampleSlider.highValueProperty()));
        // TODO: if using keys to change sliders, nothing will trigger the overlay update
        dataMaps = new ViewTrackerDataMaps(server, tracker);
        timeDisplayedSlider.setOnMouseReleased(v -> updateOverlays());
        downsampleSlider.setOnMouseReleased(v -> updateOverlays());
        colorMapCanvas.colorMapProperty().addListener((v, o, n) -> updateOverlays());
        progressIndicator.visibleProperty().bind(dataMaps.generatingOverlayProperty());
        visualizationCheckBox.selectedProperty().addListener((v, o, n) -> {
            if (n)
                updateOverlays();
            else {
                viewer.getCustomOverlayLayers().clear();
                slideOverview.setOverlay(null);
            }
        });
        // timeNormalizedRadio.selectedProperty().addListener((v, o, n) -> updateOverlays());
        // --------------------------------------------------------------//
        // ---------- PUTTING EVERYTHING TOGETHER ---------//
        // --------------------------------------------------------------//
        GridPane mainLeftPane = new GridPane();
        GridPane slideOverviewPane = new GridPane();
        GridPane dataVisualizationPane = new GridPane();
        mainLeftPane.setPadding(new Insets(5.0, 5.0, 5.0, 15.0));
        slideOverviewPane.setPadding(new Insets(5.0, 5.0, 5.0, 5.0));
        dataVisualizationPane.setPadding(new Insets(5.0, 5.0, 15.0, 5.0));
        mainLeftPane.addRow(0, slideOverviewPane);
        mainLeftPane.addRow(1, dataVisualizationPane);
        GridPane canvasPane = new GridPane();
        GridPane timelinePane = new GridPane();
        GridPane playbackPane = new GridPane();
        // GridPane normalizedByPane = new GridPane();
        GridPane rangeSlidersPane = new GridPane();
        GridPane downsamplePane = new GridPane();
        Separator sep = new Separator();
        slideOverviewPane.setHgap(10);
        slideOverviewPane.setVgap(10);
        dataVisualizationPane.setHgap(10);
        dataVisualizationPane.setVgap(10);
        playbackPane.setHgap(10.0);
        // normalizedByPane.setHgap(10.0);
        rangeSlidersPane.setHgap(10.0);
        rangeSlidersPane.setVgap(10.0);
        downsamplePane.setHgap(10.0);
        // Some 'invisible' elements might shift the canvas to the right, so make sure this doesn't happen
        if (zSlider.isVisible()) {
            canvasPane.addRow(0, new HBox(), timepointLabel, tSlider);
            canvasPane.addRow(1, zSliceLabel, zSlider, slideOverview.getCanvas());
            zSlider.setTooltip(new Tooltip("Slide to change the visible z-slice"));
        } else {
            canvasPane.addRow(0, timepointLabel, tSlider, new HBox());
            canvasPane.addRow(1, new HBox(), slideOverview.getCanvas());
        }
        if (tSlider.isVisible())
            tSlider.setTooltip(new Tooltip("Slide to change the visible timepoint"));
        // normalizedByPane.addRow(0, timeNormalizedRadio, downsampleNormalizedRadio, progressIndicator);
        // normalizedByPane.addRow(0, progressIndicator);
        timelinePane.addRow(0, timeLabelLeft, timeSlider, timeLabelRight);
        playbackPane.addRow(0, btnPlay, btnStop);
        timelinePane.setAlignment(Pos.CENTER);
        playbackPane.setAlignment(Pos.CENTER);
        canvasPane.setAlignment(Pos.CENTER);
        btnPlay.setTooltip(new Tooltip("Play the recording"));
        btnStop.setTooltip(new Tooltip("Rewind the recording"));
        int row = 0;
        PaneTools.addGridRow(slideOverviewPane, row++, 0, null, new HBox(), canvasPane);
        PaneTools.addGridRow(slideOverviewPane, row++, 0, null, timeLabelLeft, timeSlider, timeLabelRight);
        PaneTools.addGridRow(slideOverviewPane, row++, 0, "Playback options", new HBox(), playbackPane);
        PaneTools.addGridRow(slideOverviewPane, row++, 0, null, sep, sep, sep, sep);
        row = 0;
        PaneTools.addGridRow(dataVisualizationPane, row++, 0, "Show the amount of time spent in each region of the image", visualizationCheckBox, progressIndicator);
        PaneTools.addGridRow(dataVisualizationPane, row++, 0, "The data will only take into account the values recorded in-between this range", new Label("Time range"), timeDisplayedLeftLabel, timeDisplayedSlider, timeDisplayedRightLabel);
        PaneTools.addGridRow(dataVisualizationPane, row++, 0, "The data will only take into account the values recorded in-between this range", new Label("Downsample range"), downsampleLeftLabel, downsampleSlider, downsampleRightLabel);
        PaneTools.addGridRow(dataVisualizationPane, row++, 0, "Color map", new Label("Color map"), colorMapCombo, colorMapCombo, colorMapCombo);
        PaneTools.addGridRow(dataVisualizationPane, row++, 0, null, colorMapCanvas, colorMapCanvas, colorMapCanvas, colorMapCanvas);
        for (Node child : dataVisualizationPane.getChildren()) {
            if (child == visualizationCheckBox)
                continue;
            if (child == downsampleSlider)
                child.disableProperty().bind(visualizationCheckBox.selectedProperty().not().or(new SimpleBooleanProperty(minDownsample == maxDownsample)));
            else
                // else if (child == downsampleNormalizedRadio)
                // child.disableProperty().bind(visualizationCheckBox.selectedProperty().not().or(new SimpleBooleanProperty(minDownsample == maxDownsample)));
                child.disableProperty().bind(visualizationCheckBox.selectedProperty().not());
        }
        ColumnConstraints col1 = new ColumnConstraints();
        ColumnConstraints col2 = new ColumnConstraints();
        ColumnConstraints col3 = new ColumnConstraints();
        ColumnConstraints col4 = new ColumnConstraints();
        col2.setHgrow(Priority.ALWAYS);
        slideOverviewPane.getColumnConstraints().addAll(col1, col2, col3, col4);
        // --------------------- BOTTOM BUTTON PANE---------------------//
        Button btnExpand = new Button("Show frames");
        Button btnOpen = new Button("Open directory");
        btnOpen.setDisable(tracker.getFile() == null);
        List<Button> buttons = new ArrayList<>();
        btnOpen.setOnAction(e -> GuiTools.browseDirectory(tracker.getFile()));
        btnExpand.setOnAction(e -> {
            if (btnExpand.getText().equals("Show frames")) {
                dialog.setWidth(initialWidth + 700);
                dialog.setResizable(true);
                dialog.setMinWidth(initialWidth + 50);
                dialog.setMinHeight(initialHeight);
                mainLeftPane.setMinWidth(initialWidth);
                mainLeftPane.setMaxWidth(initialWidth);
                mainPane.getItems().add(tablePane);
                mainPane.setDividerPositions(0.0);
                btnExpand.setText("Hide frames");
            } else {
                mainPane.getItems().remove(tablePane);
                btnExpand.setText("Show frames");
                dialog.setWidth(initialWidth + 30);
                dialog.setHeight(initialHeight);
                dialog.setResizable(false);
            }
        });
        buttons.add(btnOpen);
        buttons.add(btnExpand);
        GridPane panelButtons = PaneTools.createColumnGridControls(buttons.toArray(new ButtonBase[0]));
        PaneTools.addGridRow(mainLeftPane, row++, 0, null, panelButtons, panelButtons, panelButtons);
        mainPane.getItems().add(mainLeftPane);
        dialog.setScene(new Scene(mainPane));
    }
    viewer.imageDataProperty().addListener((v, o, n) -> dialog.hide());
    dialog.setOnHiding(e -> {
        viewer.getCustomOverlayLayers().clear();
        playback.doStopPlayback();
        isOpenedProperty.set(false);
    });
    dialog.setResizable(false);
    dialog.show();
    initialWidth = dialog.getWidth();
    initialHeight = dialog.getHeight();
}
Also used : Button(javafx.scene.control.Button) Pos(javafx.geometry.Pos) ImageServer(qupath.lib.images.servers.ImageServer) LoggerFactory(org.slf4j.LoggerFactory) TextFormatter(javafx.scene.control.TextFormatter) DateTimeStringConverter(javafx.util.converter.DateTimeStringConverter) ParameterList(qupath.lib.plugins.parameters.ParameterList) ComboBox(javafx.scene.control.ComboBox) LocationStringFunction(qupath.lib.gui.viewer.overlays.AbstractOverlay.LocationStringFunction) ParseException(java.text.ParseException) TableView(javafx.scene.control.TableView) QuPathGUI(qupath.lib.gui.QuPathGUI) Orientation(javafx.geometry.Orientation) HBox(javafx.scene.layout.HBox) SplitPane(javafx.scene.control.SplitPane) TextField(javafx.scene.control.TextField) BufferedImageOverlay(qupath.lib.gui.viewer.overlays.BufferedImageOverlay) BufferedImage(java.awt.image.BufferedImage) ColorMap(qupath.lib.color.ColorMaps.ColorMap) IconFactory(qupath.lib.gui.tools.IconFactory) ButtonBase(javafx.scene.control.ButtonBase) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) CellDataFeatures(javafx.scene.control.TableColumn.CellDataFeatures) Separator(javafx.scene.control.Separator) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) Priority(javafx.scene.layout.Priority) List(java.util.List) BooleanProperty(javafx.beans.property.BooleanProperty) GuiTools(qupath.lib.gui.tools.GuiTools) ColorMapCanvas(qupath.lib.gui.ColorMapCanvas) ThreadTools(qupath.lib.common.ThreadTools) ObservableList(javafx.collections.ObservableList) BorderPane(javafx.scene.layout.BorderPane) Feature(qupath.lib.gui.viewer.recording.ViewTrackerDataMaps.Feature) ColorMaps(qupath.lib.color.ColorMaps) Scene(javafx.scene.Scene) MouseButton(javafx.scene.input.MouseButton) ColumnConstraints(javafx.scene.layout.ColumnConstraints) SimpleDateFormat(java.text.SimpleDateFormat) FXCollections(javafx.collections.FXCollections) Function(java.util.function.Function) Bindings(javafx.beans.binding.Bindings) ArrayList(java.util.ArrayList) TableColumn(javafx.scene.control.TableColumn) Dialogs(qupath.lib.gui.dialogs.Dialogs) Insets(javafx.geometry.Insets) Slider(javafx.scene.control.Slider) Callback(javafx.util.Callback) Tooltip(javafx.scene.control.Tooltip) ExecutorService(java.util.concurrent.ExecutorService) GridPane(javafx.scene.layout.GridPane) ImageData(qupath.lib.images.ImageData) ProgressIndicator(javafx.scene.control.ProgressIndicator) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) GeneralTools(qupath.lib.common.GeneralTools) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) TimeUnit(java.util.concurrent.TimeUnit) RangeSlider(org.controlsfx.control.RangeSlider) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) SelectionMode(javafx.scene.control.SelectionMode) Stage(javafx.stage.Stage) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) ObservableValue(javafx.beans.value.ObservableValue) Comparator(java.util.Comparator) PaneTools(qupath.lib.gui.tools.PaneTools) CellDataFeatures(javafx.scene.control.TableColumn.CellDataFeatures) ColumnConstraints(javafx.scene.layout.ColumnConstraints) Node(javafx.scene.Node) ObservableValue(javafx.beans.value.ObservableValue) Label(javafx.scene.control.Label) ArrayList(java.util.ArrayList) SplitPane(javafx.scene.control.SplitPane) Button(javafx.scene.control.Button) MouseButton(javafx.scene.input.MouseButton) Stage(javafx.stage.Stage) TextField(javafx.scene.control.TextField) GridPane(javafx.scene.layout.GridPane) ComboBox(javafx.scene.control.ComboBox) Tooltip(javafx.scene.control.Tooltip) Scene(javafx.scene.Scene) TableColumn(javafx.scene.control.TableColumn) CheckBox(javafx.scene.control.CheckBox) DateTimeStringConverter(javafx.util.converter.DateTimeStringConverter) ParameterList(qupath.lib.plugins.parameters.ParameterList) BorderPane(javafx.scene.layout.BorderPane) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) HBox(javafx.scene.layout.HBox) Insets(javafx.geometry.Insets) Slider(javafx.scene.control.Slider) RangeSlider(org.controlsfx.control.RangeSlider) ColorMap(qupath.lib.color.ColorMaps.ColorMap) ProgressIndicator(javafx.scene.control.ProgressIndicator) ButtonBase(javafx.scene.control.ButtonBase) RangeSlider(org.controlsfx.control.RangeSlider) ColorMapCanvas(qupath.lib.gui.ColorMapCanvas) ParseException(java.text.ParseException) SimpleDateFormat(java.text.SimpleDateFormat) Separator(javafx.scene.control.Separator)

Aggregations

BufferedImage (java.awt.image.BufferedImage)1 ParseException (java.text.ParseException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 ArrayList (java.util.ArrayList)1 Comparator (java.util.Comparator)1 List (java.util.List)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 TimeUnit (java.util.concurrent.TimeUnit)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 Bindings (javafx.beans.binding.Bindings)1 BooleanProperty (javafx.beans.property.BooleanProperty)1 ObjectProperty (javafx.beans.property.ObjectProperty)1 SimpleBooleanProperty (javafx.beans.property.SimpleBooleanProperty)1 SimpleObjectProperty (javafx.beans.property.SimpleObjectProperty)1 ObservableValue (javafx.beans.value.ObservableValue)1 FXCollections (javafx.collections.FXCollections)1 ObservableList (javafx.collections.ObservableList)1 Insets (javafx.geometry.Insets)1