diff --git a/design/doc-icon.svg b/design/doc-icon.svg
new file mode 100644
index 0000000..d5f1988
--- /dev/null
+++ b/design/doc-icon.svg
@@ -0,0 +1,69 @@
+
+
+
+
diff --git a/src/main/java/com/andrewlalis/perfin/control/Popups.java b/src/main/java/com/andrewlalis/perfin/control/Popups.java
index 7ffa3da..eb2c5d4 100644
--- a/src/main/java/com/andrewlalis/perfin/control/Popups.java
+++ b/src/main/java/com/andrewlalis/perfin/control/Popups.java
@@ -4,6 +4,9 @@ import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.stage.Modality;
+/**
+ * Helper class for standardized popups and confirmation dialogs for the app.
+ */
public class Popups {
public static boolean confirm(String text) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, text);
diff --git a/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java b/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java
index 0ce0b0e..d230778 100644
--- a/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java
+++ b/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java
@@ -70,6 +70,12 @@ public class TransactionsViewController implements RouteSelectionListener {
selectedTransaction.addListener((observable, oldValue, newValue) -> {
transactionViewController.setTransaction(newValue);
});
+
+ // Clear the transactions when a new profile is loaded.
+ Profile.whenLoaded(profile -> {
+ transactionsVBox.getChildren().clear();
+ onRouteSelected(null);
+ });
}
@Override
diff --git a/src/main/java/com/andrewlalis/perfin/view/component/AttachmentPreview.java b/src/main/java/com/andrewlalis/perfin/view/component/AttachmentPreview.java
index 5624923..e6e87c8 100644
--- a/src/main/java/com/andrewlalis/perfin/view/component/AttachmentPreview.java
+++ b/src/main/java/com/andrewlalis/perfin/view/component/AttachmentPreview.java
@@ -6,7 +6,6 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
-import javafx.scene.shape.Rectangle;
import java.io.IOException;
import java.nio.file.Files;
@@ -31,19 +30,25 @@ public class AttachmentPreview extends BorderPane {
nameContainer.setMinHeight(LABEL_SIZE);
contentContainer.setBottom(nameContainer);
- Rectangle placeholder = new Rectangle(IMAGE_SIZE, IMAGE_SIZE);
- placeholder.setFill(Color.WHITE);
- contentContainer.setCenter(placeholder);
-
+ boolean showDocIcon = true;
Set imageTypes = Set.of("image/png", "image/jpeg", "image/gif", "image/bmp");
if (imageTypes.contains(attachment.getContentType())) {
try (var in = Files.newInputStream(attachment.getPath())) {
Image img = new Image(in, IMAGE_SIZE, IMAGE_SIZE, true, true);
contentContainer.setCenter(new ImageView(img));
+ showDocIcon = false;
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
+ if (showDocIcon) {
+ try (var in = AttachmentPreview.class.getResourceAsStream("/images/doc-icon.png")) {
+ Image img = new Image(in, IMAGE_SIZE, IMAGE_SIZE, true, true);
+ contentContainer.setCenter(new ImageView(img));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
BorderPane hoverIndicatorPane = new BorderPane();
hoverIndicatorPane.prefWidthProperty().bind(contentContainer.widthProperty());
diff --git a/src/main/java/com/andrewlalis/perfin/view/component/DataSourcePaginationControls.java b/src/main/java/com/andrewlalis/perfin/view/component/DataSourcePaginationControls.java
index 3911533..d62b589 100644
--- a/src/main/java/com/andrewlalis/perfin/view/component/DataSourcePaginationControls.java
+++ b/src/main/java/com/andrewlalis/perfin/view/component/DataSourcePaginationControls.java
@@ -3,6 +3,7 @@ package com.andrewlalis.perfin.view.component;
import com.andrewlalis.perfin.data.pagination.Page;
import com.andrewlalis.perfin.data.pagination.PageRequest;
import com.andrewlalis.perfin.data.pagination.Sort;
+import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
@@ -10,11 +11,13 @@ import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
+import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;
/**
@@ -48,8 +51,12 @@ public class DataSourcePaginationControls extends BorderPane {
maxPagesLabel.textProperty().bind(maxPages.asString());
TextFlow maxPagesText = new TextFlow(new Text(" / "), maxPagesLabel);
maxPagesText.managedProperty().bind(maxPagesText.visibleProperty());
- maxPagesText.visibleProperty().bind(maxPages.isNotEqualTo(-1));
+ maxPagesText.visibleProperty().bind(maxPages.greaterThan(0));
TextFlow pageText = new TextFlow(new Text("Page "), currentPageLabel, maxPagesText);
+ pageText.setTextAlignment(TextAlignment.CENTER);
+ BorderPane pageTextContainer = new BorderPane(pageText);
+ BorderPane.setAlignment(pageText, Pos.CENTER);
+ pageTextContainer.setStyle("-fx-border-color: blue;");
Button previousPageButton = new Button("Previous Page");
@@ -59,38 +66,45 @@ public class DataSourcePaginationControls extends BorderPane {
nextPageButton.disableProperty().bind(fetching.or(currentPage.greaterThanOrEqualTo(maxPages)));
nextPageButton.setOnAction(event -> setPage(currentPage.get() + 1));
- sorts.addListener((ListChangeListener) c -> {
- setPage(1);
- });
+// sorts.addListener((ListChangeListener) c -> {
+// setPage(1);
+// });
HBox hbox = new HBox(
previousPageButton,
- pageText,
+ pageTextContainer,
nextPageButton
);
+ hbox.getStyleClass().addAll("std-padding", "std-spacing");
setCenter(hbox);
}
public void setPage(int page) {
- try {
- fetching.set(true);
- PageRequest pagination = new PageRequest(page - 1, itemsPerPage.get(), sorts);
- var p = fetcher.fetchPage(pagination);
- int totalResults = fetcher.getTotalCount();
- target.setAll(p.items());
- if (totalResults != -1) {
- int max = totalResults / itemsPerPage.get();
- if (totalResults % itemsPerPage.get() != 0) {
- max += 1;
- }
- maxPages.set(max);
+ fetching.set(true);
+ PageRequest pagination = new PageRequest(page - 1, itemsPerPage.get(), sorts);
+ Thread.ofVirtual().start(() -> {
+ try {
+ var p = fetcher.fetchPage(pagination);
+ int totalResults = fetcher.getTotalCount();
+ Platform.runLater(() -> {
+ target.setAll(p.items());
+ if (totalResults != -1) {
+ int max = totalResults / itemsPerPage.get();
+ if (totalResults % itemsPerPage.get() != 0) {
+ max += 1;
+ }
+ maxPages.set(max);
+ }
+ currentPage.set(page);
+ fetching.set(false);
+ });
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ Platform.runLater(() -> {
+ target.clear();
+ fetching.set(false);
+ });
}
- currentPage.set(page);
- } catch (Exception e) {
- target.clear();
- e.printStackTrace(System.err);
- } finally {
- fetching.set(false);
- }
+ });
}
}
diff --git a/src/main/resources/images/doc-icon.png b/src/main/resources/images/doc-icon.png
new file mode 100644
index 0000000..7abe238
Binary files /dev/null and b/src/main/resources/images/doc-icon.png differ