diff --git a/libs/derbyshared.jar b/libs/derbyshared.jar new file mode 100644 index 0000000..ca71ed0 Binary files /dev/null and b/libs/derbyshared.jar differ diff --git a/libs/derbytools.jar b/libs/derbytools.jar new file mode 100644 index 0000000..cf104e5 Binary files /dev/null and b/libs/derbytools.jar differ diff --git a/src/jdiskmark/AdvancedOptionsFrame.form b/src/jdiskmark/AdvancedOptionsFrame.form new file mode 100644 index 0000000..6e6412c --- /dev/null +++ b/src/jdiskmark/AdvancedOptionsFrame.form @@ -0,0 +1,85 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/jdiskmark/AdvancedOptionsFrame.java b/src/jdiskmark/AdvancedOptionsFrame.java new file mode 100644 index 0000000..5274b41 --- /dev/null +++ b/src/jdiskmark/AdvancedOptionsFrame.java @@ -0,0 +1,112 @@ + +package jdiskmark; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + + +/** + * + * @author james + */ +public class AdvancedOptionsFrame extends javax.swing.JFrame { + + /** + * Creates new form AdvancedOptionsFrame + */ + @SuppressWarnings("unchecked") + public AdvancedOptionsFrame() { + getContentPane().setLayout(new java.awt.BorderLayout()); + initComponents(); + + // --- Existing combo setup --- + setLocationRelativeTo(Gui.mainFrame); + DefaultComboBoxModel rModeModel = + new DefaultComboBoxModel<>(RenderFrequencyMode.values()); + renderModeCombo.setModel(rModeModel); + } + + + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + renderModeCombo = new javax.swing.JComboBox(); + jButton1 = new javax.swing.JButton(); + + setTitle("Advanced Options"); + + jLabel1.setText("Render Mode"); + + renderModeCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "" })); + renderModeCombo.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + renderModeComboActionPerformed(evt); + } + }); + + jButton1.setLabel("Close"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addGap(18, 18, 18) + .addComponent(renderModeCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(177, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButton1) + .addGap(26, 26, 26)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(renderModeCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 227, Short.MAX_VALUE) + .addComponent(jButton1) + .addGap(18, 18, 18)) + ); + + pack(); + }// //GEN-END:initComponents + + private void renderModeComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_renderModeComboActionPerformed + try { + App.rmOption = (RenderFrequencyMode) renderModeCombo.getSelectedItem(); + } catch (RuntimeException re) { + System.err.print(" error casting item object" + re.getMessage()); + } + }//GEN-LAST:event_renderModeComboActionPerformed + + private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed + setVisible(false); + }//GEN-LAST:event_closeButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JComboBox renderModeCombo; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/jdiskmark/App.java b/src/jdiskmark/App.java index ddfb7e1..c681aa8 100644 --- a/src/jdiskmark/App.java +++ b/src/jdiskmark/App.java @@ -68,6 +68,9 @@ public static enum State { IDLE_STATE, DISK_TEST_STATE }; public static int blockSizeKb = 512; // size of a block in KBs public static int numOfThreads = 1; // number of threads + // advanced options + public static RenderFrequencyMode rmOption = RenderFrequencyMode.PER_SAMPLE; + public static BenchmarkWorker worker = null; public static int nextSampleNumber = 1; // number of the next sample public static double wMax = -1, wMin = -1, wAvg = -1, wAcc = -1; @@ -156,6 +159,7 @@ public static void init() { Gui.mainFrame = new MainFrame(); Gui.runPanel.hideFirstColumn(); Gui.selFrame = new SelectDriveFrame(); + Gui.advancedFrame = new AdvancedOptionsFrame(); System.out.println(App.getConfigString()); Gui.mainFrame.loadConfig(); Gui.mainFrame.setLocationRelativeTo(null); @@ -250,7 +254,11 @@ public static void loadConfig() { value = p.getProperty("palette", String.valueOf(Gui.palette)); Gui.palette = Gui.Palette.valueOf(value); - } + + value = p.getProperty("renderMode", String.valueOf(rmOption)); + rmOption = RenderFrequencyMode.valueOf(value.toUpperCase()); + + } public static void saveConfig() { if (p == null) { p = new Properties(); } @@ -269,6 +277,7 @@ public static void saveConfig() { p.setProperty("numOfThreads", String.valueOf(numOfThreads)); p.setProperty("writeSyncEnable", String.valueOf(writeSyncEnable)); p.setProperty("palette", Gui.palette.name()); + p.setProperty("renderMode", rmOption.name()); // write properties file try { diff --git a/src/jdiskmark/Benchmark.java b/src/jdiskmark/Benchmark.java index 7ede76f..9701c5f 100644 --- a/src/jdiskmark/Benchmark.java +++ b/src/jdiskmark/Benchmark.java @@ -20,6 +20,8 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import jakarta.persistence.Enumerated; +import jakarta.persistence.EnumType; /** * A read or write benchmark @@ -80,6 +82,10 @@ public enum BenchmarkType { // benchmark parameters @Column BenchmarkType benchmarkType; + + @Enumerated(EnumType.STRING) + @Column + private RenderFrequencyMode renderMode = RenderFrequencyMode.PER_SAMPLE; // timestamps @Convert(converter = LocalDateTimeAttributeConverter.class) @@ -129,6 +135,15 @@ public Long getId() { public void setId(Long id) { this.id = id; } + + public RenderFrequencyMode getRenderMode() { + return renderMode != null ? renderMode : RenderFrequencyMode.PER_SAMPLE; + } + + public void setRenderMode(RenderFrequencyMode renderMode) { + this.renderMode = renderMode; + } + public String getDriveInfo() { return driveModel + " - " + partitionId + ": " + getUsageTitleDisplay(); } @@ -138,7 +153,7 @@ public String getUsageTitleDisplay() { public String getUsageColumnDisplay() { return percentUsed + "%"; } - + public String getStartTimeString() { return startTime.format(DATE_FORMAT); } diff --git a/src/jdiskmark/BenchmarkOperation.java b/src/jdiskmark/BenchmarkOperation.java index 11a87d8..9fb1616 100644 --- a/src/jdiskmark/BenchmarkOperation.java +++ b/src/jdiskmark/BenchmarkOperation.java @@ -21,6 +21,9 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import jakarta.persistence.Enumerated; +import jakarta.persistence.EnumType; + /** * A read or write benchmark @@ -229,6 +232,18 @@ public void setIops(long iops) { this.iops = iops; } +// @Enumerated(EnumType.STRING) +// @Column +// private RenderFrequencyMode renderMode; + +// public void setRenderMode(RenderFrequencyMode renderMode) { +// this.renderMode = renderMode; +// } + +// public RenderFrequencyMode getRenderMode() { +// // Gracefully default to PER_SAMPLE if null or missing +// return renderMode != null ? renderMode : RenderFrequencyMode.PER_SAMPLE; +// } // utility methods for collection static List findAll() { diff --git a/src/jdiskmark/BenchmarkPanel.java b/src/jdiskmark/BenchmarkPanel.java index efc634e..a24b791 100644 --- a/src/jdiskmark/BenchmarkPanel.java +++ b/src/jdiskmark/BenchmarkPanel.java @@ -17,6 +17,10 @@ public class BenchmarkPanel extends javax.swing.JPanel { public BenchmarkPanel() { initComponents(); Gui.runPanel = BenchmarkPanel.this; + + // Dynamically add Render Mode column + DefaultTableModel model = (DefaultTableModel) runTable.getModel(); + model.addColumn("Render Mode"); // Tooltip only – keep it simple runTable.setToolTipText("Mode: Write* means Write Sync was enabled"); @@ -123,7 +127,6 @@ public boolean isCellEditable(int rowIndex, int columnIndex) { public void addRun(Benchmark run) { - List operations = run.getOperations(); DefaultTableModel model = (DefaultTableModel) this.runTable.getModel(); for (BenchmarkOperation o : operations) { @@ -142,6 +145,7 @@ public void addRun(Benchmark run) { o.getAccTimeDisplay(), o.getBwMinMaxDisplay(), o.getBwAvgDisplay(), + (o.getRenderMode() != null ? o.getRenderMode().toString() : "-") }); } } diff --git a/src/jdiskmark/BenchmarkWorker.java b/src/jdiskmark/BenchmarkWorker.java index 0de34b9..086482a 100644 --- a/src/jdiskmark/BenchmarkWorker.java +++ b/src/jdiskmark/BenchmarkWorker.java @@ -25,11 +25,19 @@ import static jdiskmark.App.locationDir; import static jdiskmark.App.numOfSamples; + /** * Thread running the disk benchmarking. only one of these threads can run at * once. */ public class BenchmarkWorker extends SwingWorker { + + // Temporary buffer for timed render modes (100/500/1000 ms) + private final List intervalBuffer = new ArrayList<>(); + private long lastPublishTime = System.currentTimeMillis(); + private long nextPublishTime = lastPublishTime; + + public static int[][] divideIntoRanges(int startIndex, int endIndex, int numThreads) { if (numThreads <= 0 || endIndex < startIndex) { @@ -83,6 +91,8 @@ protected Boolean doInBackground() throws Exception { } Gui.updateLegendAndAxis(); + + if (App.autoReset == true) { App.resetTestData(); @@ -109,6 +119,8 @@ protected Boolean doInBackground() throws Exception { List> futures = new ArrayList<>(); Benchmark benchmark = new Benchmark(App.benchmarkType); + benchmark.setRenderMode(App.rmOption); + RenderFrequencyMode renderMode = benchmark.getRenderMode(); // system info benchmark.processorName = App.processorName; @@ -130,7 +142,7 @@ protected Boolean doInBackground() throws Exception { wOperation.ioMode = BenchmarkOperation.IOMode.WRITE; wOperation.blockOrder = App.blockSequence; wOperation.numSamples = App.numOfSamples; - wOperation.numBlocks = App.numOfSamples; + wOperation.numBlocks = App.numOfBlocks; wOperation.blockSize = App.blockSizeKb; wOperation.txSize = App.targetTxSizeKb(); wOperation.numThreads = App.numOfThreads; @@ -141,6 +153,17 @@ protected Boolean doInBackground() throws Exception { if (App.multiFile == false) { testFile = new File(dataDir.getAbsolutePath() + File.separator + "testdata.jdm"); } + + if (renderMode == RenderFrequencyMode.PER_100MS + || renderMode == RenderFrequencyMode.PER_500MS + || renderMode == RenderFrequencyMode.PER_1000MS) { + synchronized (intervalBuffer) { + intervalBuffer.clear(); + } + long now = System.currentTimeMillis(); + lastPublishTime = now; + nextPublishTime = now + renderMode.getIntervalMillis(); + } // GH-20 instantiate threads to operate on each range ExecutorService executorService = Executors.newFixedThreadPool(App.numOfThreads); @@ -156,11 +179,11 @@ protected Boolean doInBackground() throws Exception { if (App.multiFile == true) { testFile = new File(dataDir.getAbsolutePath() + File.separator + "testdata" + s + ".jdm"); - } + } Sample sample = new Sample(WRITE, s); long startTime = System.nanoTime(); long totalBytesWrittenInSample = 0; - String mode = (App.writeSyncEnable) ? "rwd" : "rw"; + String mode = (App.writeSyncEnable) ? "rwd" : "rw"; try { try (RandomAccessFile rAccFile = new RandomAccessFile(testFile, mode)) { @@ -193,20 +216,64 @@ protected Boolean doInBackground() throws Exception { // msg("s:" + s + " write IO is " + sample.getBwMbSecDisplay() + " MB/s " // + "(" + Util.displayString(mbWritten) + "MB written in " // + Util.displayString(sec) + " sec) elapsedNs: " + elapsedTimeNs); - App.updateMetrics(sample); - publish(sample); - - wOperation.bwMax = sample.cumMax; - wOperation.bwMin = sample.cumMin; - wOperation.bwAvg = sample.cumAvg; - wOperation.accAvg = sample.cumAccTimeMs; - wOperation.add(sample); + // Determine when to publish based on render mode + + switch (renderMode) { + case PER_SAMPLE -> { + App.updateMetrics(sample); + publish(sample); + wOperation.add(sample); + } + case PER_OPERATION -> { + wOperation.add(sample); + } + case PER_100MS, PER_500MS, PER_1000MS -> { + long interval = renderMode.getIntervalMillis(); + long now = System.currentTimeMillis(); + + // collect samples into buffer + synchronized (intervalBuffer) { + intervalBuffer.add(sample); + } + + // check if it’s time to flush + if (now >= nextPublishTime) { + synchronized (intervalBuffer) { + for (Sample sm : intervalBuffer) { + App.updateMetrics(sm); + publish(sm); + } + intervalBuffer.clear(); + nextPublishTime = now + interval; + } + lastPublishTime = now; + } + + wOperation.add(sample); + } + + } } })); } executorService.shutdown(); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + + if (!wOperation.getSamples().isEmpty()) { + Sample last = wOperation.getSamples().get(wOperation.getSamples().size() - 1); + wOperation.bwMax = last.cumMax; + wOperation.bwMin = last.cumMin; + wOperation.bwAvg = last.cumAvg; + wOperation.accAvg = last.cumAccTimeMs; + } + + if (renderMode == RenderFrequencyMode.PER_OPERATION) { + for (Sample s : wOperation.getSamples()) { + App.updateMetrics(s); + publish(s); + } + } // GH-10 file IOPS processing wOperation.endTime = LocalDateTime.now(); @@ -224,7 +291,7 @@ protected Boolean doInBackground() throws Exception { BenchmarkOperation rOperation = new BenchmarkOperation(); rOperation.setBenchmark(benchmark); // operation parameters - rOperation.ioMode = BenchmarkOperation.IOMode.READ; + rOperation.ioMode = BenchmarkOperation.IOMode.READ; rOperation.blockOrder = App.blockSequence; rOperation.numSamples = App.numOfSamples; rOperation.numBlocks = App.numOfBlocks; @@ -283,20 +350,60 @@ protected Boolean doInBackground() throws Exception { // msg("s:" + s + " read IO is " + sample.getBwMbSecDisplay() + " MB/s " // + "(" + Util.displayString(mbRead) + "MB read in " // + Util.displayString(sec) + " sec) elapsedNs: " + elapsedTimeNs); - App.updateMetrics(sample); - publish(sample); - rOperation.bwMax = sample.cumMax; - rOperation.bwMin = sample.cumMin; - rOperation.bwAvg = sample.cumAvg; - rOperation.accAvg = sample.cumAccTimeMs; - rOperation.add(sample); + switch (renderMode) { + case PER_SAMPLE -> { + App.updateMetrics(sample); + publish(sample); + rOperation.add(sample); + } + case PER_OPERATION -> { + rOperation.add(sample); + } + case PER_100MS, PER_500MS, PER_1000MS -> { + long interval = renderMode.getIntervalMillis(); + long now = System.currentTimeMillis(); + + synchronized (intervalBuffer) { + intervalBuffer.add(sample); + } + + if (now >= nextPublishTime) { + synchronized (intervalBuffer) { + for (Sample sm : intervalBuffer) { + App.updateMetrics(sm); + publish(sm); + } + intervalBuffer.clear(); + nextPublishTime = now + interval; + } + lastPublishTime = now; + } + + rOperation.add(sample); + } + } + + if (!rOperation.getSamples().isEmpty()) { + Sample last = rOperation.getSamples().get(rOperation.getSamples().size() - 1); + rOperation.bwMax = last.cumMax; + rOperation.bwMin = last.cumMin; + rOperation.bwAvg = last.cumAvg; + rOperation.accAvg = last.cumAccTimeMs; + } } })); - } + } executorService.shutdown(); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + if (renderMode == RenderFrequencyMode.PER_OPERATION) { + for (Sample s : rOperation.getSamples()) { + App.updateMetrics(s); + publish(s); + } + } + // GH-10 file IOPS processing rOperation.endTime = LocalDateTime.now(); rOperation.setTotalOps(rUnitsComplete[0]); diff --git a/src/jdiskmark/Gui.java b/src/jdiskmark/Gui.java index 081b599..e8299ba 100644 --- a/src/jdiskmark/Gui.java +++ b/src/jdiskmark/Gui.java @@ -12,6 +12,8 @@ import java.util.ArrayList; import javax.swing.JOptionPane; import javax.swing.JProgressBar; +import javax.swing.JLabel; +import javax.swing.JPanel; import org.jfree.chart.ChartMouseEvent; import org.jfree.chart.ChartMouseListener; import javax.swing.UIManager; @@ -26,6 +28,8 @@ import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.RectangleInsets; +import jdiskmark.App; + /** * Store GUI references for easy access @@ -35,8 +39,20 @@ public final class Gui { public static enum Palette { CLASSIC, BLUE_GREEN, BARD_COOL, BARD_WARM }; public static Palette palette = Palette.CLASSIC; + private static jdiskmark.RenderFrequencyMode renderFrequencyMode = jdiskmark.RenderFrequencyMode.PER_SAMPLE; + + public static RenderFrequencyMode getRenderFrequencyMode() { + return renderFrequencyMode; + } + + public static void setRenderFrequencyMode(RenderFrequencyMode mode) { + renderFrequencyMode = mode; + } + public static ChartPanel chartPanel = null; + public static JLabel renderModeLabel = new JLabel("Render Mode: PER_SAMPLE"); public static MainFrame mainFrame = null; + public static AdvancedOptionsFrame advancedFrame = null; public static SelectDriveFrame selFrame = null; public static XYSeries wSeries, wAvgSeries, wMaxSeries, wMinSeries, wDrvAccess; public static XYSeries rSeries, rAvgSeries, rMaxSeries, rMinSeries, rDrvAccess; @@ -87,7 +103,29 @@ public static void configureLaf() { } } - public static ChartPanel createChartPanel() { + public static void updateRenderView() { + RenderFrequencyMode mode = Gui.mainFrame.getRenderMode(); + + boolean showChart = true; // all modes show chart in this example + boolean showTable = (mode == RenderFrequencyMode.PER_100MS || + mode == RenderFrequencyMode.PER_500MS || + mode == RenderFrequencyMode.PER_1000MS); + + if (chartPanel != null) { + chartPanel.setVisible(showChart); + } + + Gui.mainFrame.setTableVisible(showTable); + + } + + public static void refreshRenderLabel() { + if (renderModeLabel != null) { + renderModeLabel.setText("Render Mode: " + getRenderFrequencyMode()); + } + } + + public static JPanel createChartPanel() { wSeries = new XYSeries("Write"); wAvgSeries = new XYSeries("Write Avg"); @@ -175,12 +213,9 @@ public static ChartPanel createChartPanel() { chart = new JFreeChart("", null , plot, true); - // correct the parenthesis from being below vertical centering chart.getTitle().setFont(new Font("Verdana", Font.BOLD, 17)); chartPanel = new ChartPanel(chart) { - // Only way to set the size of chart panel - // ref: http://www.jfree.org/phpBB2/viewtopic.php?p=75516 @Override public Dimension getPreferredSize() { return new Dimension(500, 325); @@ -209,10 +244,35 @@ public void chartMouseMoved(ChartMouseEvent cme) { // no action } }); - updateLegendAndAxis(); - return chartPanel; - } - + updateLegendAndAxis(); + + // Creates a wrapper panel with vertical layout + JPanel wrapperPanel = new JPanel(new java.awt.BorderLayout()); + + // Creates a small left-aligned panel for the label + JPanel topPanel = new JPanel(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 5, 2)); + topPanel.setOpaque(false); + + // Render Mode label + renderModeLabel = new JLabel("Render Mode: " + Gui.getRenderFrequencyMode()); + renderModeLabel.setFont(new Font("Verdana", Font.BOLD, 10)); + renderModeLabel.setForeground(Color.BLACK); + + // Add subtle light-gray background with slight transparency + renderModeLabel.setOpaque(true); + renderModeLabel.setBackground(new Color(240, 240, 240, 200)); // light gray w/ transparency + renderModeLabel.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 6, 2, 6)); // padding + + // Add label to top panel + topPanel.add(renderModeLabel); + + // Add top panel and chart panel to wrapper + wrapperPanel.add(topPanel, java.awt.BorderLayout.NORTH); + wrapperPanel.add(chartPanel, java.awt.BorderLayout.CENTER); + + return wrapperPanel; + } + public static void addWriteSample(Sample s) { wSeries.add(s.sampleNum, s.bwMbSec); wAvgSeries.add(s.sampleNum, s.cumAvg); diff --git a/src/jdiskmark/MainFrame.form b/src/jdiskmark/MainFrame.form index d41a566..25c824b 100644 --- a/src/jdiskmark/MainFrame.form +++ b/src/jdiskmark/MainFrame.form @@ -196,6 +196,16 @@ + + + + + + + + + + @@ -258,12 +268,12 @@ - + - + @@ -356,7 +366,7 @@ - + @@ -407,6 +417,7 @@ + @@ -434,95 +445,101 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - + + + - + - - - - - + + + + + - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -536,96 +553,82 @@ - + - + - - - - + + + + - + - + - + - + + + + + + + + - - + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + @@ -732,9 +735,8 @@ - - - + + diff --git a/src/jdiskmark/MainFrame.java b/src/jdiskmark/MainFrame.java index 7a5a915..3a8d7e4 100644 --- a/src/jdiskmark/MainFrame.java +++ b/src/jdiskmark/MainFrame.java @@ -14,6 +14,14 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.text.DefaultCaret; +import javax.swing.JComboBox; +import javax.swing.JPopupMenu; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.ButtonGroup; + + /** * The parent frame of the app @@ -26,57 +34,134 @@ public final class MainFrame extends javax.swing.JFrame { * Creates new form MainFrame */ - @SuppressWarnings("unchecked") - public MainFrame() { - initComponents(); - - //for diagnostics - //controlsPanel.setBackground(Color.blue); - - DefaultComboBoxModel ioModel - = new DefaultComboBoxModel<>(Benchmark.BenchmarkType.values()); - typeCombo.setModel(ioModel); - - startButton.requestFocus(); - Gui.createChartPanel(); - mountPanel.setLayout(new BorderLayout()); - Gui.chartPanel.setSize(mountPanel.getSize()); - Gui.chartPanel.setSize(mountPanel.getWidth(), 200); - mountPanel.add(Gui.chartPanel); - totalTxProgBar.setStringPainted(true); - totalTxProgBar.setValue(0); - totalTxProgBar.setString(""); - - StringBuilder titleSb = new StringBuilder(); - titleSb.append(getTitle()).append(" ").append(App.VERSION); - - initializeComboSettings(); - - // architecture - if (App.arch != null && !App.arch.isEmpty()) { - titleSb.append(" - ").append(App.arch); - } - - // processor name - if (App.processorName != null && !App.processorName.isEmpty()) { - titleSb.append(" - ").append(App.processorName); - } - - // permission indicator - if (App.isAdmin) titleSb.append(" [Admin]"); - if (App.isRoot) titleSb.append(" [root]"); - - setTitle(titleSb.toString()); - - // auto scroll the text area. - DefaultCaret caret = (DefaultCaret) msgTextArea.getCaret(); - caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); - - // init order combo box - orderComboBox.addItem(BenchmarkOperation.BlockSequence.SEQUENTIAL); - orderComboBox.addItem(BenchmarkOperation.BlockSequence.RANDOM); + private javax.swing.JLabel renderModeLabel; + private javax.swing.JComboBox renderModeCombo; + + private RenderFrequencyMode renderMode = RenderFrequencyMode.PER_SAMPLE; + public RenderFrequencyMode getRenderMode() { + return Gui.getRenderFrequencyMode(); } + @SuppressWarnings("unchecked") + public MainFrame() { + Gui.mainFrame = this; // safe enough here, only reference used after initComponents() + + initComponents(); + + // Submenu for Render Interval + // Render Mode submenu with radio buttons + JMenu renderModeMenu = new JMenu("Render Mode"); + + JRadioButtonMenuItem perSampleItem = new JRadioButtonMenuItem("Per Sample"); + JRadioButtonMenuItem perOperationItem = new JRadioButtonMenuItem("Per Operation"); + JRadioButtonMenuItem per1000msItem = new JRadioButtonMenuItem("Per 1000 ms"); + JRadioButtonMenuItem per500msItem = new JRadioButtonMenuItem("Per 500 ms"); + + ButtonGroup group = new ButtonGroup(); + group.add(perSampleItem); + group.add(perOperationItem); + group.add(per1000msItem); + group.add(per500msItem); + + renderModeMenu.add(perSampleItem); + renderModeMenu.add(perOperationItem); + renderModeMenu.addSeparator(); + renderModeMenu.add(per1000msItem); + renderModeMenu.add(per500msItem); + + // initialize selected item from current app state + switch (Gui.getRenderFrequencyMode()) { + case PER_SAMPLE -> perSampleItem.setSelected(true); + case PER_OPERATION -> perOperationItem.setSelected(true); + case PER_1000MS -> per1000msItem.setSelected(true); + case PER_500MS -> per500msItem.setSelected(true); + } + + perSampleItem.addActionListener(e -> { + Gui.setRenderFrequencyMode(RenderFrequencyMode.PER_SAMPLE); + Gui.renderModeLabel.setText("Render Mode: Per Sample"); + Gui.updateRenderView(); + }); + + perOperationItem.addActionListener(e -> { + Gui.setRenderFrequencyMode(RenderFrequencyMode.PER_OPERATION); + Gui.renderModeLabel.setText("Render Mode: Per Operation"); + Gui.updateRenderView(); + }); + + per1000msItem.addActionListener(e -> { + Gui.setRenderFrequencyMode(RenderFrequencyMode.PER_1000MS); + Gui.renderModeLabel.setText("Render Mode: Per 1000 ms"); + Gui.updateRenderView(); + }); + + per500msItem.addActionListener(e -> { + Gui.setRenderFrequencyMode(RenderFrequencyMode.PER_500MS); + Gui.renderModeLabel.setText("Render Mode: Per 500 ms"); + Gui.updateRenderView(); + }); + + + // Add to Options menu + optionMenu.addSeparator(); + optionMenu.add(renderModeMenu); + + + // --------- EXISTING UI SETUP BELOW --------- + + // for diagnostics + // controlsPanel.setBackground(Color.blue); + + DefaultComboBoxModel ioModel = + new DefaultComboBoxModel<>(Benchmark.BenchmarkType.values()); + typeCombo.setModel(ioModel); + + startButton.requestFocus(); + mountPanel.setLayout(new BorderLayout()); + + JPanel wrapperPanel = Gui.createChartPanel(); + wrapperPanel.setPreferredSize(new java.awt.Dimension(mountPanel.getWidth(), 200)); + mountPanel.add(wrapperPanel, BorderLayout.CENTER); + mountPanel.revalidate(); + mountPanel.repaint(); + + totalTxProgBar.setStringPainted(true); + totalTxProgBar.setValue(0); + totalTxProgBar.setString(""); + + StringBuilder titleSb = new StringBuilder(); + titleSb.append(getTitle()).append(" ").append(App.VERSION); + + initializeComboSettings(); + + // architecture + if (App.arch != null && !App.arch.isEmpty()) { + titleSb.append(" - ").append(App.arch); + } + + // processor name + if (App.processorName != null && !App.processorName.isEmpty()) { + titleSb.append(" - ").append(App.processorName); + } + + // permission indicator + if (App.isAdmin) titleSb.append(" [Admin]"); + if (App.isRoot) titleSb.append(" [root]"); + + setTitle(titleSb.toString()); + + // auto scroll the text area + DefaultCaret caret = (DefaultCaret) msgTextArea.getCaret(); + caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); + + // init order combo box + orderComboBox.addItem(BenchmarkOperation.BlockSequence.SEQUENTIAL); + orderComboBox.addItem(BenchmarkOperation.BlockSequence.RANDOM); + } + + + + public JPanel getMountPanel() { return mountPanel; } @@ -118,9 +203,9 @@ public void loadConfig() { public void initializeComboSettings() { typeCombo.setSelectedItem(App.benchmarkType); - loadSettings(); + loadSettings(); } - + public void loadSettings() { typeCombo.setSelectedItem(App.benchmarkType); numThreadsCombo.setSelectedItem(String.valueOf(App.numOfThreads)); @@ -216,6 +301,8 @@ private void initComponents() { blueGreenPaletteMenuItem = new javax.swing.JRadioButtonMenuItem(); bardCoolPaletteMenuItem = new javax.swing.JRadioButtonMenuItem(); bardWarmPaletteMenuItem = new javax.swing.JRadioButtonMenuItem(); + jSeparator3 = new javax.swing.JPopupMenu.Separator(); + jMenuItem3 = new javax.swing.JMenuItem(); helpMenu = new javax.swing.JMenu(); jMenuItem2 = new javax.swing.JMenuItem(); @@ -284,13 +371,14 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(jLabel15)) .addGap(18, 18, 18) .addComponent(jLabel22) - .addContainerGap(48, Short.MAX_VALUE)) + .addContainerGap(20, Short.MAX_VALUE)) ); tabbedPane.addTab("Drive Location", locationPanel); mountPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); mountPanel.setMaximumSize(new java.awt.Dimension(503, 200)); + mountPanel.setName("renderCombo"); // NOI18N javax.swing.GroupLayout mountPanelLayout = new javax.swing.GroupLayout(mountPanel); mountPanel.setLayout(mountPanelLayout); @@ -341,7 +429,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jLabel4.setText("Benchmark Type"); - typeCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { " ", " " })); + typeCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "" })); typeCombo.setPreferredSize(new java.awt.Dimension(60, 24)); typeCombo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -433,75 +521,78 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlsPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(controlsPanelLayout.createSequentialGroup() + .addComponent(jLabel9) + .addGap(18, 18, 18) + .addComponent(sampleSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(startButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(controlsPanelLayout.createSequentialGroup() + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel13) + .addGroup(controlsPanelLayout.createSequentialGroup() + .addComponent(jLabel18) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(wIopsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(controlsPanelLayout.createSequentialGroup() + .addComponent(jLabel16) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(wAccessLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlsPanelLayout.createSequentialGroup() + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1) + .addComponent(jLabel2) + .addComponent(jLabel3)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(wAvgLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(wMaxLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(wMinLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel20) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(controlsPanelLayout.createSequentialGroup() + .addComponent(jLabel19) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(rIopsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlsPanelLayout.createSequentialGroup() + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel11) + .addComponent(jLabel10) + .addComponent(jLabel12)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(rMinLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(rMaxLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(rAvgLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlsPanelLayout.createSequentialGroup() + .addComponent(jLabel17) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(rAccessLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGroup(controlsPanelLayout.createSequentialGroup() + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel4) + .addComponent(jLabel6) + .addComponent(jLabel8)) + .addGap(18, 18, 18) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(typeCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(blockSizeCombo, 0, 100, Short.MAX_VALUE) + .addComponent(numSamplesCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(numBlocksCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addGroup(controlsPanelLayout.createSequentialGroup() - .addComponent(jLabel9) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel21) + .addComponent(jLabel14)) .addGap(18, 18, 18) - .addComponent(sampleSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(startButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(controlsPanelLayout.createSequentialGroup() .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) - .addComponent(jLabel4) - .addComponent(jLabel14) - .addComponent(jLabel6) - .addComponent(jLabel8) - .addComponent(jLabel21)) - .addGap(18, 18, 18) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(typeCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(numThreadsCombo, 0, 100, Short.MAX_VALUE) - .addComponent(orderComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(numBlocksCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(blockSizeCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(numSamplesCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel13) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addComponent(jLabel18) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(wIopsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addComponent(jLabel16) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(wAccessLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 38, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlsPanelLayout.createSequentialGroup() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel1) - .addComponent(jLabel2) - .addComponent(jLabel3)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(wAvgLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(wMaxLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(wMinLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE))))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel20) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addComponent(jLabel19) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(rIopsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlsPanelLayout.createSequentialGroup() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel10) - .addComponent(jLabel12) - .addComponent(jLabel11)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(rMinLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(rMaxLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(rAvgLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, controlsPanelLayout.createSequentialGroup() - .addComponent(jLabel17) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(rAccessLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))))) - .addGap(2, 2, 2))) + .addComponent(orderComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(numThreadsCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addContainerGap(27, Short.MAX_VALUE)) ); controlsPanelLayout.setVerticalGroup( @@ -510,77 +601,68 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel4) .addComponent(typeCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(numThreadsCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel21)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel21) + .addComponent(numThreadsCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(orderComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel14)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(18, 18, 18) .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) - .addComponent(numBlocksCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(numBlocksCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5)) + .addGap(18, 18, 18) .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel6) .addComponent(blockSizeCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(18, 18, 18) .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel8) .addComponent(numSamplesCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sampleSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel9, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(startButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel9) - .addComponent(sampleSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel13) + .addComponent(jLabel20)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(wMinLabel) + .addComponent(jLabel10) + .addComponent(rMinLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(startButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(18, 18, 18) .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel20, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jLabel13, javax.swing.GroupLayout.Alignment.TRAILING)) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel11) + .addComponent(rMaxLabel)) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(wMaxLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel10) - .addComponent(rMinLabel)) - .addGap(30, 30, 30) - .addComponent(rAvgLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel17) - .addComponent(rAccessLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel19) - .addComponent(rIopsLabel))) - .addGroup(controlsPanelLayout.createSequentialGroup() - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(wMinLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jLabel2) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(wMaxLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel11) - .addComponent(rMaxLabel))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(wAvgLabel) - .addComponent(jLabel12)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel16) - .addComponent(wAccessLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel18) - .addComponent(wIopsLabel)))) - .addContainerGap()) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(wAvgLabel) + .addComponent(jLabel12) + .addComponent(rAvgLabel)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel16) + .addComponent(wAccessLabel) + .addComponent(jLabel17) + .addComponent(rAccessLabel)) + .addGap(8, 8, 8) + .addGroup(controlsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel18) + .addComponent(wIopsLabel) + .addComponent(jLabel19) + .addComponent(rIopsLabel))) ); jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); @@ -770,6 +852,15 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { colorPaletteMenu.add(bardWarmPaletteMenuItem); optionMenu.add(colorPaletteMenu); + optionMenu.add(jSeparator3); + + jMenuItem3.setText("Advanced Options"); + jMenuItem3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItem3ActionPerformed(evt); + } + }); + optionMenu.add(jMenuItem3); menuBar.add(optionMenu); @@ -806,17 +897,17 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(controlsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 391, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(controlsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 419, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(mountPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE) + .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(progressPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); pack(); }// //GEN-END:initComponents - + private void chooseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseButtonActionPerformed Gui.browseLocation(); }//GEN-LAST:event_chooseButtonActionPerformed @@ -994,6 +1085,9 @@ private void numThreadsComboActionPerformed(java.awt.event.ActionEvent evt) {//G } }//GEN-LAST:event_numThreadsComboActionPerformed + private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed + Gui.advancedFrame.setVisible(true); + }//GEN-LAST:event_jMenuItem3ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenu actionMenu; @@ -1038,8 +1132,10 @@ private void numThreadsComboActionPerformed(java.awt.event.ActionEvent evt) {//G private javax.swing.JLabel jLabel9; private javax.swing.JMenuItem jMenuItem1; private javax.swing.JMenuItem jMenuItem2; + private javax.swing.JMenuItem jMenuItem3; private javax.swing.JPopupMenu.Separator jSeparator1; private javax.swing.JPopupMenu.Separator jSeparator2; + private javax.swing.JPopupMenu.Separator jSeparator3; private javax.swing.JPanel locationPanel; private javax.swing.JTextField locationText; private javax.swing.JMenuBar menuBar; @@ -1133,6 +1229,12 @@ public void clearMessages() { msgTextArea.setText(""); } + public void setTableVisible(boolean visible) { + // TEMP: No table component yet, so just log or stub + System.out.println("Requested to set table visibility to: " + visible); + } + + public void adjustSensitivity() { switch (App.state) { case App.State.DISK_TEST_STATE -> { @@ -1159,11 +1261,11 @@ public void adjustSensitivity() { } // Replace lowercase mode options with proper casing - @SuppressWarnings("unchecked") - private void configureModeCombo() { - typeCombo.removeAllItems(); - typeCombo.addItem("Write"); - typeCombo.addItem("Read"); - typeCombo.addItem("Read & Write"); - } +// @SuppressWarnings("unchecked") +// private void configureModeCombo() { +// typeCombo.removeAllItems(); +// typeCombo.addItem("Write"); +// typeCombo.addItem("Read"); +// typeCombo.addItem("Read & Write"); +// } } diff --git a/src/jdiskmark/RenderFrequencyMode.java b/src/jdiskmark/RenderFrequencyMode.java new file mode 100644 index 0000000..7c8ab85 --- /dev/null +++ b/src/jdiskmark/RenderFrequencyMode.java @@ -0,0 +1,29 @@ +package jdiskmark; + +public enum RenderFrequencyMode { + PER_SAMPLE("Per Sample"), + PER_OPERATION("Per Operation"), + PER_100MS("Per 100ms"), + PER_500MS("Per 500ms"), + PER_1000MS("Per 1000ms"); + + private final String label; + + RenderFrequencyMode(String label) { + this.label = label; + } + + @Override + public String toString() { + return label; + } + + public long getIntervalMillis() { + return switch (this) { + case PER_100MS -> 100; + case PER_500MS -> 500; + case PER_1000MS -> 1000; + default -> 0; + }; + } +} \ No newline at end of file diff --git a/src/jdiskmark/RenderFrequencyModeAttributeConverter.java b/src/jdiskmark/RenderFrequencyModeAttributeConverter.java new file mode 100644 index 0000000..790ee19 --- /dev/null +++ b/src/jdiskmark/RenderFrequencyModeAttributeConverter.java @@ -0,0 +1,18 @@ +package jdiskmark; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class RenderFrequencyModeAttributeConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(RenderFrequencyMode mode) { + return (mode == null) ? null : mode.name(); + } + + @Override + public RenderFrequencyMode convertToEntityAttribute(String dbData) { + return (dbData == null) ? null : RenderFrequencyMode.valueOf(dbData); + } +} \ No newline at end of file