mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
add permanent refresh button enabled when tags are updated
This commit is contained in:
parent
dfce250309
commit
c98658f88e
@ -1,79 +1,106 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.scene.text.*?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import java.lang.*?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.geometry.*?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.MenuButton?>
|
||||||
<?import javafx.scene.image.*?>
|
<?import javafx.scene.control.Separator?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.control.ToggleButton?>
|
||||||
<?import jfxtras.scene.control.*?>
|
<?import javafx.scene.control.ToolBar?>
|
||||||
<?import org.controlsfx.control.*?>
|
<?import javafx.scene.image.Image?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
<?import javafx.scene.layout.Region?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.text.Font?>
|
||||||
|
<?import jfxtras.scene.control.LocalDateTimeTextField?>
|
||||||
|
<?import org.controlsfx.control.SegmentedButton?>
|
||||||
|
|
||||||
<fx:root prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
|
<fx:root prefHeight="-1.0" prefWidth="-1.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
<top>
|
<top>
|
||||||
<ToolBar fx:id="toolBar" prefWidth="200.0" BorderPane.alignment="CENTER">
|
<HBox BorderPane.alignment="CENTER">
|
||||||
<items>
|
<children>
|
||||||
<HBox alignment="CENTER" BorderPane.alignment="CENTER">
|
<ToolBar fx:id="toolBar" prefWidth="200.0" HBox.hgrow="ALWAYS">
|
||||||
<children>
|
<items>
|
||||||
<Label fx:id="visualizationModeLabel">
|
<HBox alignment="CENTER" BorderPane.alignment="CENTER">
|
||||||
<HBox.margin>
|
<children>
|
||||||
<Insets right="5.0" />
|
<Label fx:id="visualizationModeLabel">
|
||||||
</HBox.margin>
|
<HBox.margin>
|
||||||
<font>
|
<Insets right="5.0" />
|
||||||
<Font name="System Bold" size="14.0" />
|
</HBox.margin>
|
||||||
</font>
|
|
||||||
</Label>
|
|
||||||
|
|
||||||
<org.controlsfx.control.SegmentedButton maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity">
|
|
||||||
<buttons>
|
|
||||||
<ToggleButton fx:id="countsToggle" alignment="TOP_LEFT" mnemonicParsing="false" selected="true">
|
|
||||||
<graphic>
|
|
||||||
<ImageView fitHeight="16.0" fitWidth="16.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
|
|
||||||
<image>
|
|
||||||
<Image url="@../images/chart_bar.png" />
|
|
||||||
</image>
|
|
||||||
</ImageView>
|
|
||||||
</graphic>
|
|
||||||
<font>
|
<font>
|
||||||
<Font name="System Bold" size="16.0" />
|
<Font name="System Bold" size="14.0" />
|
||||||
</font>
|
</font>
|
||||||
</ToggleButton>
|
</Label>
|
||||||
<ToggleButton fx:id="detailsToggle" alignment="CENTER_RIGHT" layoutX="74.0" mnemonicParsing="false" selected="false">
|
|
||||||
<graphic>
|
<org.controlsfx.control.SegmentedButton maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity">
|
||||||
<ImageView fitHeight="16.0" fitWidth="16.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true" rotate="0.0" smooth="true" style="-fx-background-color:white;" x="2.0" y="1.0">
|
<buttons>
|
||||||
<image>
|
<ToggleButton fx:id="countsToggle" alignment="TOP_LEFT" mnemonicParsing="false" selected="true">
|
||||||
<Image url="@../images/20140521121247760_easyicon_net_32_colorized.png" />
|
<graphic>
|
||||||
</image>
|
<ImageView fitHeight="16.0" fitWidth="16.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
|
||||||
</ImageView>
|
<image>
|
||||||
</graphic>
|
<Image url="@../images/chart_bar.png" />
|
||||||
<font>
|
</image>
|
||||||
<Font name="System Bold" size="16.0" />
|
</ImageView>
|
||||||
</font>
|
</graphic>
|
||||||
</ToggleButton>
|
<font>
|
||||||
</buttons>
|
<Font name="System Bold" size="16.0" />
|
||||||
|
</font>
|
||||||
</org.controlsfx.control.SegmentedButton>
|
</ToggleButton>
|
||||||
</children>
|
<ToggleButton fx:id="detailsToggle" alignment="CENTER_RIGHT" layoutX="74.0" mnemonicParsing="false" selected="false">
|
||||||
<padding>
|
<graphic>
|
||||||
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
<ImageView fitHeight="16.0" fitWidth="16.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true" rotate="0.0" smooth="true" style="-fx-background-color:white;" x="2.0" y="1.0">
|
||||||
</padding>
|
<image>
|
||||||
<BorderPane.margin>
|
<Image url="@../images/20140521121247760_easyicon_net_32_colorized.png" />
|
||||||
<Insets left="10.0" />
|
</image>
|
||||||
</BorderPane.margin>
|
</ImageView>
|
||||||
</HBox>
|
</graphic>
|
||||||
<Separator orientation="VERTICAL" />
|
<font>
|
||||||
<Button fx:id="snapShotButton" mnemonicParsing="false">
|
<Font name="System Bold" size="16.0" />
|
||||||
<graphic>
|
</font>
|
||||||
|
</ToggleButton>
|
||||||
|
</buttons>
|
||||||
|
|
||||||
|
</org.controlsfx.control.SegmentedButton>
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
||||||
|
</padding>
|
||||||
|
<BorderPane.margin>
|
||||||
|
<Insets left="10.0" />
|
||||||
|
</BorderPane.margin>
|
||||||
|
</HBox>
|
||||||
|
</items>
|
||||||
|
</ToolBar>
|
||||||
|
<ToolBar maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
|
||||||
|
<items>
|
||||||
|
<Separator orientation="VERTICAL" />
|
||||||
|
<Button fx:id="snapShotButton" mnemonicParsing="false">
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||||
|
<image>
|
||||||
|
<Image url="@../images/image.png" />
|
||||||
|
</image>
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
<Separator halignment="LEFT" maxWidth="1.7976931348623157E308" orientation="VERTICAL" />
|
||||||
|
<Button fx:id="refreshButton" alignment="CENTER_RIGHT" mnemonicParsing="false" text="Refresh">
|
||||||
|
<graphic>
|
||||||
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
<ImageView fitHeight="16.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../images/image.png" />
|
<Image url="@../images/arrow-circle-double-135.png" />
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
</graphic>
|
</graphic>
|
||||||
</Button>
|
</Button>
|
||||||
<Separator orientation="VERTICAL" />
|
</items>
|
||||||
</items>
|
</ToolBar>
|
||||||
</ToolBar>
|
</children>
|
||||||
|
</HBox>
|
||||||
</top>
|
</top>
|
||||||
<bottom>
|
<bottom>
|
||||||
<VBox maxHeight="-Infinity">
|
<VBox maxHeight="-Infinity">
|
||||||
|
@ -29,6 +29,7 @@ import java.util.function.Supplier;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
|
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
@ -96,16 +97,16 @@ import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
|||||||
* TODO: refactor common code out of histogram and CountsView? -jm
|
* TODO: refactor common code out of histogram and CountsView? -jm
|
||||||
*/
|
*/
|
||||||
final public class VisualizationPanel extends BorderPane {
|
final public class VisualizationPanel extends BorderPane {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(VisualizationPanel.class.getName());
|
||||||
|
|
||||||
private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS
|
private static final Image INFORMATION = new Image("org/sleuthkit/autopsy/timeline/images/information.png", 16, 16, true, true); // NON-NLS
|
||||||
private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS
|
private static final Image REFRESH = new Image("org/sleuthkit/autopsy/timeline/images/arrow-circle-double-135.png"); // NON-NLS
|
||||||
private static final Background background = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY));
|
private static final Background background = new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY));
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private LoggedTask<Void> histogramTask;
|
private LoggedTask<Void> histogramTask;
|
||||||
|
|
||||||
private final EventsTree eventsTree;
|
private final EventsTree eventsTree;
|
||||||
private AbstractVisualizationPane<?, ?, ?, ?> visualization;
|
private AbstractVisualizationPane<?, ?, ?, ?> visualization;
|
||||||
//// range slider and histogram componenets
|
//// range slider and histogram componenets
|
||||||
@ -120,13 +121,13 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private StackPane rangeHistogramStack;
|
private StackPane rangeHistogramStack;
|
||||||
|
|
||||||
private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75);
|
private final RangeSlider rangeSlider = new RangeSlider(0, 1.0, .25, .75);
|
||||||
|
|
||||||
//// time range selection components
|
//// time range selection components
|
||||||
@FXML
|
@FXML
|
||||||
private MenuButton zoomMenuButton;
|
private MenuButton zoomMenuButton;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button zoomOutButton;
|
private Button zoomOutButton;
|
||||||
@FXML
|
@FXML
|
||||||
@ -158,13 +159,15 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button snapShotButton;
|
private Button snapShotButton;
|
||||||
@FXML
|
@FXML
|
||||||
|
private Button refreshButton;
|
||||||
|
@FXML
|
||||||
private Label visualizationModeLabel;
|
private Label visualizationModeLabel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wraps contained visualization so that we can show notifications over it.
|
* wraps contained visualization so that we can show notifications over it.
|
||||||
*/
|
*/
|
||||||
private final NotificationPane notificationPane = new NotificationPane();
|
private final NotificationPane notificationPane = new NotificationPane();
|
||||||
|
private final ReadOnlyBooleanWrapper needsRefresh = new ReadOnlyBooleanWrapper(false);
|
||||||
private final TimeLineController controller;
|
private final TimeLineController controller;
|
||||||
private final FilteredEventsModel filteredEvents;
|
private final FilteredEventsModel filteredEvents;
|
||||||
|
|
||||||
@ -190,7 +193,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
/**
|
/**
|
||||||
* hides the notification pane on any event
|
* hides the notification pane on any event
|
||||||
*/
|
*/
|
||||||
private final InvalidationListener zoomListener = any -> notificationPane.hide();
|
private final InvalidationListener zoomListener = any -> setNeedsRefresh(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* listen to change in end time picker and push to controller
|
* listen to change in end time picker and push to controller
|
||||||
@ -225,14 +228,14 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
private static LocalDateTime epochMillisToLocalDateTime(long millis) {
|
private static LocalDateTime epochMillisToLocalDateTime(long millis) {
|
||||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), TimeLineController.getTimeZoneID());
|
return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), TimeLineController.getTimeZoneID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public VisualizationPanel(@Nonnull TimeLineController controller, @Nonnull EventsTree eventsTree) {
|
public VisualizationPanel(@Nonnull TimeLineController controller, @Nonnull EventsTree eventsTree) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.filteredEvents = controller.getEventsModel();
|
this.filteredEvents = controller.getEventsModel();
|
||||||
this.eventsTree = eventsTree;
|
this.eventsTree = eventsTree;
|
||||||
FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS
|
FXMLConstructor.construct(this, "VisualizationPanel.fxml"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML // This method is called by the FXMLLoader when initialization is complete
|
@FXML // This method is called by the FXMLLoader when initialization is complete
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"VisualizationPanel.visualizationModeLabel.text=Visualization Mode:",
|
"VisualizationPanel.visualizationModeLabel.text=Visualization Mode:",
|
||||||
@ -266,7 +269,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
controller.setViewMode(VisualizationMode.DETAIL);
|
controller.setViewMode(VisualizationMode.DETAIL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (countsToggle.getToggleGroup() != null) {
|
if (countsToggle.getToggleGroup() != null) {
|
||||||
countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener);
|
countsToggle.getToggleGroup().selectedToggleProperty().addListener(toggleListener);
|
||||||
} else {
|
} else {
|
||||||
@ -279,6 +282,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
|
|
||||||
//configure snapshor button / action
|
//configure snapshor button / action
|
||||||
ActionUtils.configureButton(new SaveSnapshotAsReport(controller, VisualizationPanel.this), snapShotButton);
|
ActionUtils.configureButton(new SaveSnapshotAsReport(controller, VisualizationPanel.this), snapShotButton);
|
||||||
|
ActionUtils.configureButton(new Refresh(), refreshButton);
|
||||||
|
|
||||||
/////configure start and end pickers
|
/////configure start and end pickers
|
||||||
startLabel.setText(Bundle.VisualizationPanel_startLabel_text());
|
startLabel.setText(Bundle.VisualizationPanel_startLabel_text());
|
||||||
@ -343,9 +347,9 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
refreshHistorgram();
|
refreshHistorgram();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setViewMode(VisualizationMode visualizationMode) {
|
private void setViewMode(VisualizationMode visualizationMode) {
|
||||||
switch (visualizationMode) {
|
switch (visualizationMode) {
|
||||||
case COUNTS:
|
case COUNTS:
|
||||||
@ -357,75 +361,83 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
detailsToggle.setSelected(true);
|
detailsToggle.setSelected(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void setVisualization(final AbstractVisualizationPane<?, ?, ?, ?> newViz) {
|
private synchronized void setVisualization(final AbstractVisualizationPane<?, ?, ?, ?> newViz) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
synchronized (VisualizationPanel.this) {
|
if (visualization != null) {
|
||||||
if (visualization != null) {
|
toolBar.getItems().removeAll(visualization.getSettingsNodes());
|
||||||
toolBar.getItems().removeAll(visualization.getSettingsNodes());
|
visualization.dispose();
|
||||||
visualization.dispose();
|
}
|
||||||
}
|
|
||||||
|
visualization = newViz;
|
||||||
visualization = newViz;
|
visualization.update();
|
||||||
visualization.update();
|
toolBar.getItems().addAll(newViz.getSettingsNodes());
|
||||||
toolBar.getItems().addAll(newViz.getSettingsNodes());
|
|
||||||
|
notificationPane.setContent(visualization);
|
||||||
notificationPane.setContent(visualization);
|
if (visualization instanceof DetailViewPane) {
|
||||||
if (visualization instanceof DetailViewPane) {
|
Platform.runLater(() -> {
|
||||||
Platform.runLater(() -> {
|
((DetailViewPane) visualization).setHighLightedEvents(eventsTree.getSelectedEvents());
|
||||||
((DetailViewPane) visualization).setHighLightedEvents(eventsTree.getSelectedEvents());
|
eventsTree.setDetailViewPane((DetailViewPane) visualization);
|
||||||
eventsTree.setDetailViewPane((DetailViewPane) visualization);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
visualization.hasEvents.addListener((observable, oldValue, newValue) -> {
|
|
||||||
if (newValue == false) {
|
|
||||||
|
|
||||||
notificationPane.setContent(
|
|
||||||
new StackPane(visualization,
|
|
||||||
new Region() {
|
|
||||||
{
|
|
||||||
setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)));
|
|
||||||
setOpacity(.3);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new NoEventsDialog(() -> notificationPane.setContent(visualization))));
|
|
||||||
} else {
|
|
||||||
notificationPane.setContent(visualization);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
visualization.hasEvents.addListener((observable, oldValue, newValue) -> {
|
||||||
|
if (newValue == false) {
|
||||||
|
|
||||||
|
notificationPane.setContent(
|
||||||
|
new StackPane(visualization,
|
||||||
|
new Region() {
|
||||||
|
{
|
||||||
|
setBackground(new Background(new BackgroundFill(Color.GREY, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||||
|
setOpacity(.3);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new NoEventsDialog(() -> notificationPane.setContent(visualization))));
|
||||||
|
} else {
|
||||||
|
notificationPane.setContent(visualization);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
setNeedsRefresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@NbBundle.Messages("VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.")
|
@NbBundle.Messages("VisualizationPanel.tagsAddedOrDeleted=Tags have been created and/or deleted. The visualization may not be up to date.")
|
||||||
public void handleTimeLineTagEvent(TagsUpdatedEvent event) {
|
public void handleTimeLineTagEvent(TagsUpdatedEvent event) {
|
||||||
Platform.runLater(() -> {
|
setNeedsRefresh(true);
|
||||||
notificationPane.setCloseButtonVisible(false);
|
|
||||||
notificationPane.getActions().setAll(new Refresh());
|
|
||||||
notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void handleRefreshRequestedEvent(RefreshRequestedEvent event) {
|
public void handleRefreshRequestedEvent(RefreshRequestedEvent event) {
|
||||||
Platform.runLater(notificationPane::hide);
|
setNeedsRefresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setNeedsRefresh(Boolean needsRefresh) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
VisualizationPanel.this.needsRefresh.set(needsRefresh);
|
||||||
|
if (needsRefresh) {
|
||||||
|
notificationPane.show(Bundle.VisualizationPanel_tagsAddedOrDeleted(), new ImageView(INFORMATION));
|
||||||
|
} else {
|
||||||
|
notificationPane.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
synchronized private void refreshHistorgram() {
|
synchronized private void refreshHistorgram() {
|
||||||
|
|
||||||
if (histogramTask != null) {
|
if (histogramTask != null) {
|
||||||
histogramTask.cancel(true);
|
histogramTask.cancel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
histogramTask = new LoggedTask<Void>(
|
histogramTask = new LoggedTask<Void>(
|
||||||
NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.title"), true) { // NON-NLS
|
NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.title"), true) { // NON-NLS
|
||||||
private final Lighting lighting = new Lighting();
|
private final Lighting lighting = new Lighting();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void call() throws Exception {
|
protected Void call() throws Exception {
|
||||||
|
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.preparing")); // NON-NLS
|
||||||
|
|
||||||
long max = 0;
|
long max = 0;
|
||||||
@ -442,9 +454,9 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.resetUI")); // NON-NLS
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ArrayList<Long> bins = new ArrayList<>();
|
ArrayList<Long> bins = new ArrayList<>();
|
||||||
|
|
||||||
DateTime start = timeRange.getStart();
|
DateTime start = timeRange.getStart();
|
||||||
while (timeRange.contains(start)) {
|
while (timeRange.contains(start)) {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
@ -455,21 +467,21 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
//increment for next iteration
|
//increment for next iteration
|
||||||
|
|
||||||
start = end;
|
start = end;
|
||||||
|
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.queryDb")); // NON-NLS
|
||||||
//query for current range
|
//query for current range
|
||||||
long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum();
|
long count = filteredEvents.getEventCounts(interval).values().stream().mapToLong(Long::valueOf).sum();
|
||||||
bins.add(count);
|
bins.add(count);
|
||||||
|
|
||||||
max = Math.max(count, max);
|
max = Math.max(count, max);
|
||||||
|
|
||||||
final double fMax = Math.log(max);
|
final double fMax = Math.log(max);
|
||||||
final ArrayList<Long> fbins = new ArrayList<>(bins);
|
final ArrayList<Long> fbins = new ArrayList<>(bins);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS
|
updateMessage(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.histogramTask.updateUI2")); // NON-NLS
|
||||||
|
|
||||||
histogramBox.getChildren().clear();
|
histogramBox.getChildren().clear();
|
||||||
|
|
||||||
for (Long bin : fbins) {
|
for (Long bin : fbins) {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
break;
|
break;
|
||||||
@ -492,41 +504,41 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
new Thread(histogramTask).start();
|
new Thread(histogramTask).start();
|
||||||
controller.monitorTask(histogramTask);
|
controller.monitorTask(histogramTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshTimeUI() {
|
private void refreshTimeUI() {
|
||||||
refreshTimeUI(filteredEvents.timeRangeProperty().get());
|
refreshTimeUI(filteredEvents.timeRangeProperty().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshTimeUI(Interval interval) {
|
private void refreshTimeUI(Interval interval) {
|
||||||
|
|
||||||
RangeDivisionInfo rangeDivisionInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
RangeDivisionInfo rangeDivisionInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.getSpanningInterval());
|
||||||
|
|
||||||
final long minTime = rangeDivisionInfo.getLowerBound();
|
final long minTime = rangeDivisionInfo.getLowerBound();
|
||||||
final long maxTime = rangeDivisionInfo.getUpperBound();
|
final long maxTime = rangeDivisionInfo.getUpperBound();
|
||||||
|
|
||||||
long startMillis = interval.getStartMillis();
|
long startMillis = interval.getStartMillis();
|
||||||
long endMillis = interval.getEndMillis();
|
long endMillis = interval.getEndMillis();
|
||||||
|
|
||||||
if (minTime > 0 && maxTime > minTime) {
|
if (minTime > 0 && maxTime > minTime) {
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
startPicker.localDateTimeProperty().removeListener(startListener);
|
startPicker.localDateTimeProperty().removeListener(startListener);
|
||||||
endPicker.localDateTimeProperty().removeListener(endListener);
|
endPicker.localDateTimeProperty().removeListener(endListener);
|
||||||
rangeSlider.highValueChangingProperty().removeListener(rangeSliderListener);
|
rangeSlider.highValueChangingProperty().removeListener(rangeSliderListener);
|
||||||
rangeSlider.lowValueChangingProperty().removeListener(rangeSliderListener);
|
rangeSlider.lowValueChangingProperty().removeListener(rangeSliderListener);
|
||||||
|
|
||||||
rangeSlider.setMax((maxTime - minTime));
|
rangeSlider.setMax((maxTime - minTime));
|
||||||
|
|
||||||
rangeSlider.setLowValue(startMillis - minTime);
|
rangeSlider.setLowValue(startMillis - minTime);
|
||||||
rangeSlider.setHighValue(endMillis - minTime);
|
rangeSlider.setHighValue(endMillis - minTime);
|
||||||
startPicker.setLocalDateTime(epochMillisToLocalDateTime(startMillis));
|
startPicker.setLocalDateTime(epochMillisToLocalDateTime(startMillis));
|
||||||
endPicker.setLocalDateTime(epochMillisToLocalDateTime(endMillis));
|
endPicker.setLocalDateTime(epochMillisToLocalDateTime(endMillis));
|
||||||
|
|
||||||
rangeSlider.highValueChangingProperty().addListener(rangeSliderListener);
|
rangeSlider.highValueChangingProperty().addListener(rangeSliderListener);
|
||||||
rangeSlider.lowValueChangingProperty().addListener(rangeSliderListener);
|
rangeSlider.lowValueChangingProperty().addListener(rangeSliderListener);
|
||||||
startPicker.localDateTimeProperty().addListener(startListener);
|
startPicker.localDateTimeProperty().addListener(startListener);
|
||||||
@ -534,10 +546,10 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events")
|
@NbBundle.Messages("NoEventsDialog.titledPane.text=No Visible Events")
|
||||||
private class NoEventsDialog extends StackPane {
|
private class NoEventsDialog extends StackPane {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TitledPane titledPane;
|
private TitledPane titledPane;
|
||||||
@FXML
|
@FXML
|
||||||
@ -550,14 +562,14 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
private Button zoomButton;
|
private Button zoomButton;
|
||||||
@FXML
|
@FXML
|
||||||
private Label noEventsDialogLabel;
|
private Label noEventsDialogLabel;
|
||||||
|
|
||||||
private final Runnable closeCallback;
|
private final Runnable closeCallback;
|
||||||
|
|
||||||
private NoEventsDialog(Runnable closeCallback) {
|
private NoEventsDialog(Runnable closeCallback) {
|
||||||
this.closeCallback = closeCallback;
|
this.closeCallback = closeCallback;
|
||||||
FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS
|
FXMLConstructor.construct(this, "NoEventsDialog.fxml"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void initialize() {
|
void initialize() {
|
||||||
assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
assert resetFiltersButton != null : "fx:id=\"resetFiltersButton\" was not injected: check your FXML file 'NoEventsDialog.fxml'."; // NON-NLS
|
||||||
@ -568,7 +580,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS
|
noEventsDialogLabel.setText(NbBundle.getMessage(NoEventsDialog.class, "VisualizationPanel.noEventsDialogLabel.text")); // NON-NLS
|
||||||
|
|
||||||
dismissButton.setOnAction(actionEvent -> closeCallback.run());
|
dismissButton.setOnAction(actionEvent -> closeCallback.run());
|
||||||
|
|
||||||
ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton);
|
ActionUtils.configureButton(new ZoomToEvents(controller), zoomButton);
|
||||||
ActionUtils.configureButton(new Back(controller), backButton);
|
ActionUtils.configureButton(new Back(controller), backButton);
|
||||||
ActionUtils.configureButton(new ResetFilters(controller), resetFiltersButton);
|
ActionUtils.configureButton(new ResetFilters(controller), resetFiltersButton);
|
||||||
@ -580,15 +592,15 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* the selected LocalDateTime as start/end to the timelinecontroller.
|
* the selected LocalDateTime as start/end to the timelinecontroller.
|
||||||
*/
|
*/
|
||||||
private class PickerListener implements InvalidationListener {
|
private class PickerListener implements InvalidationListener {
|
||||||
|
|
||||||
private final BiFunction< Interval, Long, Interval> intervalMapper;
|
private final BiFunction< Interval, Long, Interval> intervalMapper;
|
||||||
private final Supplier<LocalDateTimeTextField> pickerSupplier;
|
private final Supplier<LocalDateTimeTextField> pickerSupplier;
|
||||||
|
|
||||||
PickerListener(Supplier<LocalDateTimeTextField> pickerSupplier, BiFunction<Interval, Long, Interval> intervalMapper) {
|
PickerListener(Supplier<LocalDateTimeTextField> pickerSupplier, BiFunction<Interval, Long, Interval> intervalMapper) {
|
||||||
this.pickerSupplier = pickerSupplier;
|
this.pickerSupplier = pickerSupplier;
|
||||||
this.intervalMapper = intervalMapper;
|
this.intervalMapper = intervalMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidated(Observable observable) {
|
public void invalidated(Observable observable) {
|
||||||
LocalDateTime pickerTime = pickerSupplier.get().getLocalDateTime();
|
LocalDateTime pickerTime = pickerSupplier.get().getLocalDateTime();
|
||||||
@ -603,7 +615,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* callback that disabled date/times outside the span of the current case.
|
* callback that disabled date/times outside the span of the current case.
|
||||||
*/
|
*/
|
||||||
private class LocalDateDisabler implements Callback<LocalDateTimePicker.LocalDateTimeRange, Void> {
|
private class LocalDateDisabler implements Callback<LocalDateTimePicker.LocalDateTimeRange, Void> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void call(LocalDateTimePicker.LocalDateTimeRange viewedRange) {
|
public Void call(LocalDateTimePicker.LocalDateTimeRange viewedRange) {
|
||||||
startPicker.disabledLocalDateTimes().clear();
|
startPicker.disabledLocalDateTimes().clear();
|
||||||
@ -613,7 +625,7 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
Interval spanningInterval = filteredEvents.getSpanningInterval();
|
Interval spanningInterval = filteredEvents.getSpanningInterval();
|
||||||
long spanStartMillis = spanningInterval.getStartMillis();
|
long spanStartMillis = spanningInterval.getStartMillis();
|
||||||
long spaneEndMillis = spanningInterval.getEndMillis();
|
long spaneEndMillis = spanningInterval.getEndMillis();
|
||||||
|
|
||||||
LocalDate rangeStartLocalDate = viewedRange.getStartLocalDateTime().toLocalDate();
|
LocalDate rangeStartLocalDate = viewedRange.getStartLocalDateTime().toLocalDate();
|
||||||
LocalDate rangeEndLocalDate = viewedRange.getEndLocalDateTime().toLocalDate().plusDays(1);
|
LocalDate rangeEndLocalDate = viewedRange.getEndLocalDateTime().toLocalDate().plusDays(1);
|
||||||
//iterate over days of the displayed range and disable ones not in spanning interval
|
//iterate over days of the displayed range and disable ones not in spanning interval
|
||||||
@ -641,11 +653,11 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
* picker to reset if invalid info was entered
|
* picker to reset if invalid info was entered
|
||||||
*/
|
*/
|
||||||
private final LocalDateTimeTextField picker;
|
private final LocalDateTimeTextField picker;
|
||||||
|
|
||||||
LocalDateTimeValidator(LocalDateTimeTextField picker) {
|
LocalDateTimeValidator(LocalDateTimeTextField picker) {
|
||||||
this.picker = picker;
|
this.picker = picker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean call(LocalDateTime param) {
|
public Boolean call(LocalDateTime param) {
|
||||||
long epochMilli = localDateTimeToEpochMilli(param);
|
long epochMilli = localDateTimeToEpochMilli(param);
|
||||||
@ -660,15 +672,16 @@ final public class VisualizationPanel extends BorderPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Refresh extends Action {
|
private class Refresh extends Action {
|
||||||
|
|
||||||
@NbBundle.Messages({"VisualizationPanel.refresh=refresh"})
|
@NbBundle.Messages({"VisualizationPanel.refresh=refresh"})
|
||||||
Refresh() {
|
Refresh() {
|
||||||
super(Bundle.VisualizationPanel_refresh());
|
super(Bundle.VisualizationPanel_refresh());
|
||||||
|
|
||||||
setGraphic(new ImageView(REFRESH));
|
setGraphic(new ImageView(REFRESH));
|
||||||
setEventHandler(actionEvent -> filteredEvents.refresh());
|
setEventHandler(actionEvent -> filteredEvents.refresh());
|
||||||
|
disabledProperty().bind(needsRefresh.not());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user