From 6b839349fb2bd3c71f9c6e91878951c8e9acc3c1 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Fri, 21 Apr 2023 21:43:48 +0200 Subject: [PATCH] Fixed some issues with pre-loading data. --- recorder/pom.xml | 18 +++ .../running_every_day/RecorderApp.java | 2 + .../view/AggregateStatisticsPanel.java | 4 +- .../view/RecorderAppWindow.java | 15 ++- .../view/RunRecordsPanel.java | 108 +++++++++--------- .../view/WindowDataSourceCloser.java | 1 + .../view/chart/DateSeriesChartRenderer.java | 3 + .../view/chart/JFreeChartRenderer.java | 14 +-- 8 files changed, 97 insertions(+), 68 deletions(-) diff --git a/recorder/pom.xml b/recorder/pom.xml index a1241c4..a91d322 100644 --- a/recorder/pom.xml +++ b/recorder/pom.xml @@ -32,4 +32,22 @@ + + + + maven-assembly-plugin + + + + com.github.andrewlalis.running_every_day.RecorderApp + + + + jar-with-dependencies + + + + + + \ No newline at end of file diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/RecorderApp.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/RecorderApp.java index 07abea3..cd30783 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/RecorderApp.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/RecorderApp.java @@ -24,6 +24,8 @@ public class RecorderApp { System.out.println("Added App Window close listener"); window.setVisible(true); System.out.println("Set App Window as visible"); + window.initComponentData(); + System.out.println("Initialized component data"); } catch (SQLException e) { JOptionPane.showMessageDialog(null, "Failed to open database: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/AggregateStatisticsPanel.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/AggregateStatisticsPanel.java index 673e101..e76c76c 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/AggregateStatisticsPanel.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/AggregateStatisticsPanel.java @@ -33,8 +33,10 @@ public class AggregateStatisticsPanel extends JPanel { refreshButton.addActionListener(e -> refreshStats()); controlsPanel.add(refreshButton); this.add(controlsPanel, BorderLayout.NORTH); + } -// SwingUtilities.invokeLater(this::refreshStats); + public void init() { + SwingUtilities.invokeLater(this::refreshStats); } private void refreshStats() { diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RecorderAppWindow.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RecorderAppWindow.java index dc241d0..dd7428b 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RecorderAppWindow.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RecorderAppWindow.java @@ -6,8 +6,14 @@ import javax.swing.*; import java.awt.*; public class RecorderAppWindow extends JFrame { + private final RunRecordsPanel runRecordsPanel; + private final AggregateStatisticsPanel aggregateStatisticsPanel; + public RecorderAppWindow(DataSource dataSource) { super("Run-Recorder"); + this.runRecordsPanel = new RunRecordsPanel(dataSource); + this.aggregateStatisticsPanel = new AggregateStatisticsPanel(dataSource); + this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setContentPane(buildGui(dataSource)); this.setPreferredSize(new Dimension(1000, 600)); @@ -15,10 +21,15 @@ public class RecorderAppWindow extends JFrame { this.setLocationRelativeTo(null); } + public void initComponentData() { + runRecordsPanel.init(); + aggregateStatisticsPanel.init(); + } + private Container buildGui(DataSource dataSource) { JTabbedPane tabbedPane = new JTabbedPane(); - tabbedPane.addTab("Run Records", new RunRecordsPanel(dataSource)); - tabbedPane.addTab("Aggregate Statistics", new AggregateStatisticsPanel(dataSource)); + tabbedPane.addTab("Run Records", runRecordsPanel); + tabbedPane.addTab("Aggregate Statistics", aggregateStatisticsPanel); tabbedPane.addTab("Charts", new ChartsPanel(dataSource)); return tabbedPane; } diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RunRecordsPanel.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RunRecordsPanel.java index 0fe786e..93eb24e 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RunRecordsPanel.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/RunRecordsPanel.java @@ -5,6 +5,8 @@ import com.github.andrewlalis.running_every_day.data.db.DataSource; import com.github.andrewlalis.running_every_day.data.db.Queries; import javax.swing.*; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; import java.awt.*; import java.math.BigDecimal; import java.math.RoundingMode; @@ -22,17 +24,28 @@ public class RunRecordsPanel extends JPanel { private final DataSource dataSource; private final RunRecordTableModel tableModel; - private final JTextField currentPageField; - private final JButton firstPageButton; - private final JButton previousPageButton; - private final JButton nextPageButton; - private final JButton lastPageButton; + private final JTextField currentPageField = new JTextField("1", 3); + private final JButton firstPageButton = new JButton("First Page"); + private final JButton previousPageButton = new JButton("Previous Page"); + private final JButton nextPageButton = new JButton("Next Page"); + private final JButton lastPageButton = new JButton("Last Page"); public RunRecordsPanel(DataSource dataSource) { super(new BorderLayout()); this.dataSource = dataSource; this.tableModel = new RunRecordTableModel(dataSource); + tableModel.addTableModelListener(e -> updateButtonStates()); + this.add(buildTablePanel(), BorderLayout.CENTER); + this.add(buildPaginationPanel(), BorderLayout.SOUTH); + this.add(buildActionsPanel(), BorderLayout.NORTH); + } + + public void init() { + SwingUtilities.invokeLater(tableModel::firstPage); + } + + private Container buildTablePanel() { var table = new JTable(tableModel); table.getTableHeader().setReorderingAllowed(false); table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); @@ -48,56 +61,10 @@ public class RunRecordsPanel extends JPanel { for (int i = 0; i < 7; i++) { table.getColumnModel().getColumn(i).setResizable(false); } - var scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); - this.add(scrollPane, BorderLayout.CENTER); - - JPanel paginationPanel = new JPanel(new GridLayout(1, 6)); - firstPageButton = new JButton("First Page"); - firstPageButton.addActionListener(e -> { - tableModel.firstPage(); - updateButtonStates(); - }); - previousPageButton = new JButton("Previous Page"); - previousPageButton.addActionListener(e -> { - tableModel.previousPage(); - updateButtonStates(); - }); - nextPageButton = new JButton("Next Page"); - nextPageButton.addActionListener(e -> { - tableModel.nextPage(); - updateButtonStates(); - }); - lastPageButton = new JButton("Last Page"); - lastPageButton.addActionListener(e -> { - tableModel.lastPage(); - updateButtonStates(); - }); - - JPanel currentPagePanel = new JPanel(); - currentPagePanel.add(new JLabel("Current Page: ")); - this.currentPageField = new JTextField("1", 3); - currentPagePanel.add(this.currentPageField); - - JPanel pageSizePanel = new JPanel(); - pageSizePanel.add(new JLabel("Page Size: ")); - JComboBox pageSizeSelector = new JComboBox<>(new Integer[]{5, 10, 20, 50, 100, 500}); - pageSizeSelector.setSelectedItem(tableModel.getPagination().size()); - pageSizeSelector.addItemListener(e -> { - int size = (int) e.getItem(); - tableModel.setPageSize(size); - updateButtonStates(); - }); - pageSizePanel.add(pageSizeSelector); - - paginationPanel.add(firstPageButton); - paginationPanel.add(previousPageButton); - paginationPanel.add(currentPagePanel); - paginationPanel.add(pageSizePanel); - paginationPanel.add(nextPageButton); - paginationPanel.add(lastPageButton); - - this.add(paginationPanel, BorderLayout.SOUTH); + return new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + } + private JPanel buildActionsPanel() { JPanel actionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); JButton addActionButton = new JButton("Add a Record"); addActionButton.addActionListener(e -> { @@ -111,7 +78,37 @@ public class RunRecordsPanel extends JPanel { JButton generateRandomDataButton = new JButton("Generate Random Data"); generateRandomDataButton.addActionListener(e -> generateRandomData()); actionsPanel.add(generateRandomDataButton); - this.add(actionsPanel, BorderLayout.NORTH); + return actionsPanel; + } + + private JPanel buildPaginationPanel() { + JPanel paginationPanel = new JPanel(new GridLayout(1, 6)); + firstPageButton.addActionListener(e -> tableModel.firstPage()); + previousPageButton.addActionListener(e -> tableModel.previousPage()); + nextPageButton.addActionListener(e -> tableModel.nextPage()); + lastPageButton.addActionListener(e -> tableModel.lastPage()); + + JPanel currentPagePanel = new JPanel(); + currentPagePanel.add(new JLabel("Current Page: ")); + currentPagePanel.add(this.currentPageField); + + JPanel pageSizePanel = new JPanel(); + pageSizePanel.add(new JLabel("Page Size: ")); + JComboBox pageSizeSelector = new JComboBox<>(new Integer[]{5, 10, 20, 50, 100, 500}); + pageSizeSelector.setSelectedItem(tableModel.getPagination().size()); + pageSizeSelector.addItemListener(e -> { + int size = (int) e.getItem(); + tableModel.setPageSize(size); + }); + pageSizePanel.add(pageSizeSelector); + + paginationPanel.add(firstPageButton); + paginationPanel.add(previousPageButton); + paginationPanel.add(currentPagePanel); + paginationPanel.add(pageSizePanel); + paginationPanel.add(nextPageButton); + paginationPanel.add(lastPageButton); + return paginationPanel; } private void updateButtonStates() { @@ -151,7 +148,6 @@ public class RunRecordsPanel extends JPanel { c.commit(); c.setAutoCommit(true); tableModel.firstPage(); - updateButtonStates(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/WindowDataSourceCloser.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/WindowDataSourceCloser.java index 5f80c93..e57020d 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/WindowDataSourceCloser.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/WindowDataSourceCloser.java @@ -20,6 +20,7 @@ public class WindowDataSourceCloser extends WindowAdapter { public void windowClosing(WindowEvent e) { try { dataSource.close(); + System.out.println("Data source closed"); } catch (SQLException ex) { ex.printStackTrace(); } diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/DateSeriesChartRenderer.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/DateSeriesChartRenderer.java index f4da993..5411003 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/DateSeriesChartRenderer.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/DateSeriesChartRenderer.java @@ -53,6 +53,9 @@ public class DateSeriesChartRenderer extends JFreeChartRenderer { false ); } + if (series.getItemCount() < 2) { + throw new IllegalStateException("Not enough data."); + } XYDataset dataset = new TimeSeriesCollection(series); DateAxis domainAxis = new DateAxis(); diff --git a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/JFreeChartRenderer.java b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/JFreeChartRenderer.java index 3f4c20c..d5c9a9f 100644 --- a/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/JFreeChartRenderer.java +++ b/recorder/src/main/java/com/github/andrewlalis/running_every_day/view/chart/JFreeChartRenderer.java @@ -17,14 +17,10 @@ public abstract class JFreeChartRenderer implements ChartRenderer { protected abstract JFreeChart getChart() throws Exception; protected void applyCustomStyles(JFreeChart chart) {} - public void refresh() { - try { - lastChart = getChart(); - standardChartTheme.apply(lastChart); - applyCustomStyles(lastChart); - } catch (Exception e) { - e.printStackTrace(); - } + public void refresh() throws Exception { + lastChart = getChart(); + standardChartTheme.apply(lastChart); + applyCustomStyles(lastChart); } @Override @@ -35,7 +31,7 @@ public abstract class JFreeChartRenderer implements ChartRenderer { } lastChart.draw(graphics, area); } catch (Exception e) { - graphics.setColor(Color.BLACK); + graphics.setColor(Color.RED); graphics.setBackground(Color.WHITE); graphics.fill(area); graphics.drawString("Error: " + e.getMessage(), 20, 40);