Added build script and more stuff

This commit is contained in:
Andrew Lalis 2023-04-22 09:43:14 +02:00
parent 6b839349fb
commit 22c1fb6d74
8 changed files with 100 additions and 27 deletions

5
recorder/build.sh Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
mvn clean compile assembly:single
cp target/recorder-*-jar-with-dependencies.jar recorder.jar
chmod +x recorder.jar

View File

@ -81,6 +81,11 @@ public class RunRecordTableModel extends AbstractTableModel {
}
}
public long getRecordIdAtRow(int row) {
if (row < 0 || row >= records.size()) return -1;
return records.get(row).id();
}
@Override
public int getRowCount() {
return records.size();

View File

@ -5,8 +5,6 @@ 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;
@ -24,6 +22,10 @@ public class RunRecordsPanel extends JPanel {
private final DataSource dataSource;
private final RunRecordTableModel tableModel;
private final JTable table;
private final JButton deleteRecordButton = new JButton("Delete Record");
private final JTextField currentPageField = new JTextField("1", 3);
private final JButton firstPageButton = new JButton("First Page");
private final JButton previousPageButton = new JButton("Previous Page");
@ -34,6 +36,7 @@ public class RunRecordsPanel extends JPanel {
super(new BorderLayout());
this.dataSource = dataSource;
this.tableModel = new RunRecordTableModel(dataSource);
this.table = new JTable(tableModel);
tableModel.addTableModelListener(e -> updateButtonStates());
this.add(buildTablePanel(), BorderLayout.CENTER);
@ -46,7 +49,6 @@ public class RunRecordsPanel extends JPanel {
}
private Container buildTablePanel() {
var table = new JTable(tableModel);
table.getTableHeader().setReorderingAllowed(false);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
table.getColumnModel().getColumn(0).setMaxWidth(50);
@ -61,6 +63,9 @@ public class RunRecordsPanel extends JPanel {
for (int i = 0; i < 7; i++) {
table.getColumnModel().getColumn(i).setResizable(false);
}
table.getSelectionModel().addListSelectionListener(e -> {
deleteRecordButton.setEnabled(!e.getValueIsAdjusting() && tableModel.getRecordIdAtRow(table.getSelectedRow()) != -1);
});
return new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
@ -78,6 +83,32 @@ public class RunRecordsPanel extends JPanel {
JButton generateRandomDataButton = new JButton("Generate Random Data");
generateRandomDataButton.addActionListener(e -> generateRandomData());
actionsPanel.add(generateRandomDataButton);
deleteRecordButton.addActionListener(e -> {
long id = tableModel.getRecordIdAtRow(table.getSelectedRow());
if (id != -1) {
int result = JOptionPane.showConfirmDialog(
this,
"Are you sure you want to delete this record? This is permanent.",
"Confirm Deletion",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result == JOptionPane.OK_OPTION) {
try {
dataSource.runRecords().delete(id);
} catch (SQLException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(
this,
"An SQL Exception occurred: " + ex.getMessage(),
"Error",
JOptionPane.ERROR_MESSAGE
);
}
}
}
});
actionsPanel.add(deleteRecordButton);
return actionsPanel;
}

View File

@ -4,5 +4,5 @@ import java.awt.*;
import java.awt.geom.Rectangle2D;
public interface ChartRenderer {
void render(Graphics2D graphics, Rectangle2D area);
void render(Graphics2D graphics, Rectangle2D area, float textScale);
}

View File

@ -23,7 +23,7 @@ public class ChartRenderingPanel extends JPanel implements Consumer<ChartRendere
if (renderer != null) {
Graphics2D g2 = (Graphics2D) g;
Rectangle2D area = new Rectangle2D.Float(0, 0, this.getWidth(), this.getHeight());
renderer.render(g2, area);
renderer.render(g2, area, 1);
} else {
g.drawString("No chart to render", 50, 50);
}

View File

@ -73,7 +73,7 @@ public class DateSeriesChartRenderer extends JFreeChartRenderer {
}
@Override
protected void applyCustomStyles(JFreeChart chart) {
applyStandardXYLineColor(chart, linePaint);
protected void applyCustomStyles(JFreeChart chart, float textScale) {
applyStandardXYLineColor(chart, linePaint, textScale);
}
}

View File

@ -18,6 +18,7 @@ public class ExportChartImageDialog extends JDialog {
private final SpinnerNumberModel widthSpinnerModel = new SpinnerNumberModel(1920, 10, 10000, 1);
private final SpinnerNumberModel heightSpinnerModel = new SpinnerNumberModel(1080, 10, 10000, 1);
private final SpinnerNumberModel textScaleSpinnerModel = new SpinnerNumberModel(1.0, 0.01, 25.0, 0.01);
private final JTextField filePathField = new JTextField();
private Path currentFilePath = Path.of(".").toAbsolutePath().resolve("chart.png");
@ -39,8 +40,10 @@ public class ExportChartImageDialog extends JDialog {
c.gridy = 1;
formPanel.add(new JLabel("Height (px)"), c);
c.gridy = 2;
formPanel.add(new JLabel("File"), c);
formPanel.add(new JLabel("Text Scale"), c);
c.gridy = 3;
formPanel.add(new JLabel("File"), c);
c.gridy = 4;
JButton selectFileButton = new JButton("Select File");
selectFileButton.addActionListener(e -> browseForFilePath());
formPanel.add(selectFileButton, c);
@ -57,8 +60,12 @@ public class ExportChartImageDialog extends JDialog {
JSpinner heightSpinner = new JSpinner(heightSpinnerModel);
heightSpinner.setLocale(Locale.US);
formPanel.add(heightSpinner, c);
c.gridy = 2;
JSpinner textScaleSpinner = new JSpinner(textScaleSpinnerModel);
textScaleSpinner.setLocale(Locale.US);
formPanel.add(textScaleSpinner, c);
c.gridy = 3;
filePathField.setEditable(false);
filePathField.setText(currentFilePath.toAbsolutePath().toString());
filePathField.addMouseListener(new MouseAdapter() {
@ -110,8 +117,9 @@ public class ExportChartImageDialog extends JDialog {
}
int width = (int) widthSpinnerModel.getValue();
int height = (int) heightSpinnerModel.getValue();
double textScale = (Double) textScaleSpinnerModel.getValue();
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
chartRenderer.render(img.createGraphics(), new Rectangle2D.Float(0, 0, width, height));
chartRenderer.render(img.createGraphics(), new Rectangle2D.Float(0, 0, width, height), (float) textScale);
try {
ImageIO.write(img, "png", currentFilePath.toFile());
JOptionPane.showMessageDialog(

View File

@ -4,6 +4,7 @@ import com.github.andrewlalis.running_every_day.Resources;
import org.jfree.chart.ChartTheme;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import java.awt.*;
@ -12,23 +13,27 @@ import java.io.IOException;
public abstract class JFreeChartRenderer implements ChartRenderer {
private JFreeChart lastChart = null;
public static final ChartTheme standardChartTheme = getChartTheme();
private final StandardChartTheme standardChartTheme = getChartTheme();
private static final float SMALL_FONT_BASE_SIZE = 10;
private static final float REGULAR_FONT_BASE_SIZE = 12;
private static final float LARGE_FONT_BASE_SIZE = 18;
private static final float EXTRA_LARGE_FONT_BASE_SIZE = 30;
protected abstract JFreeChart getChart() throws Exception;
protected void applyCustomStyles(JFreeChart chart) {}
public void refresh() throws Exception {
lastChart = getChart();
standardChartTheme.apply(lastChart);
applyCustomStyles(lastChart);
}
protected void applyCustomStyles(JFreeChart chart, float textScale) {}
@Override
public void render(Graphics2D graphics, Rectangle2D area) {
public void render(Graphics2D graphics, Rectangle2D area, float textScale) {
if (textScale < 0) textScale = 1;
try {
if (lastChart == null) {
refresh();
lastChart = getChart();
}
setThemeTextScale(textScale);
standardChartTheme.apply(lastChart);
applyCustomStyles(lastChart, textScale);
lastChart.draw(graphics, area);
} catch (Exception e) {
graphics.setColor(Color.RED);
@ -39,7 +44,7 @@ public abstract class JFreeChartRenderer implements ChartRenderer {
}
}
private static ChartTheme getChartTheme() {
private static StandardChartTheme getChartTheme() {
StandardChartTheme theme = new StandardChartTheme("Standard Theme");
Font baseFont = Font.getFont("sans-serif");
Font lightFont = Font.getFont("sans-serif");
@ -49,10 +54,10 @@ public abstract class JFreeChartRenderer implements ChartRenderer {
} catch (IOException e) {
e.printStackTrace();
}
theme.setSmallFont(baseFont.deriveFont(10f));
theme.setRegularFont(baseFont.deriveFont(12f));
theme.setLargeFont(lightFont.deriveFont(18f));
theme.setExtraLargeFont(lightFont.deriveFont(30f));
theme.setSmallFont(baseFont);
theme.setRegularFont(baseFont);
theme.setLargeFont(lightFont);
theme.setExtraLargeFont(lightFont);
theme.setChartBackgroundPaint(Color.WHITE);
theme.setPlotBackgroundPaint(Color.WHITE);
@ -62,10 +67,29 @@ public abstract class JFreeChartRenderer implements ChartRenderer {
return theme;
}
protected static void applyStandardXYLineColor(JFreeChart chart, Paint paint) {
private void setThemeTextScale(float scale) {
standardChartTheme.setSmallFont(standardChartTheme.getSmallFont().deriveFont(scale * SMALL_FONT_BASE_SIZE));
standardChartTheme.setRegularFont(standardChartTheme.getRegularFont().deriveFont(scale * REGULAR_FONT_BASE_SIZE));
standardChartTheme.setLargeFont(standardChartTheme.getLargeFont().deriveFont(scale * LARGE_FONT_BASE_SIZE));
standardChartTheme.setExtraLargeFont(standardChartTheme.getExtraLargeFont().deriveFont(scale * EXTRA_LARGE_FONT_BASE_SIZE));
}
protected static void applyStandardXYLineColor(JFreeChart chart, Paint paint, float textScale) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) chart.getXYPlot().getRenderer();
renderer.setSeriesPaint(0, paint);
renderer.setSeriesShapesVisible(0, false);
renderer.setSeriesStroke(0, new BasicStroke(3));
renderer.setSeriesStroke(0, new BasicStroke(3 * textScale));
XYPlot plot = chart.getXYPlot();
BasicStroke stroke = new BasicStroke(
textScale,
BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_MITER,
1,
new float[]{2 * textScale, 2 * textScale},
0
);
plot.setDomainGridlineStroke(stroke);
plot.setRangeGridlineStroke(stroke);
}
}