Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
72b2588
Add flatlaf-3.7.1.jar
mbahler Mar 13, 2026
0c44012
Changed settings window to JDialog.
mbahler Mar 16, 2026
187a885
Changes
mbahler Mar 16, 2026
f8a445b
Added serial port refresh button and refresh button icon. Fixes#139. …
mbahler Mar 16, 2026
70ce7ef
Updated refresh button icon. added Edit Baud rate icon.
mbahler Mar 17, 2026
5557c8e
Settings changes remain on CANCEL press. FixesUI: Setting changes rem…
mbahler Mar 17, 2026
532eaaa
Implemented for advanced options. Added settings window listener to r…
mbahler Mar 17, 2026
620849d
Implemented for timestamp checkbox.
mbahler Mar 17, 2026
7c60474
Format.
mbahler Mar 17, 2026
4c78d24
Added baud rate edit button.
mbahler Mar 17, 2026
0356303
Added BaudRate edit dialog.
mbahler Mar 20, 2026
252446c
Added BaudEditTextarea line reader.
mbahler Mar 21, 2026
c8a12b7
Write custom baudRates to baud rate combo box.
mbahler Mar 22, 2026
af7a6b0
Changed main window frame and canvas to more descriptive names.
mbahler Mar 24, 2026
59d38ec
Disable not active window.
mbahler Mar 24, 2026
6f882a9
Fix custom baud edit crash.
mbahler Mar 26, 2026
b2afbc9
custom baud rates save-cancel with CANCEL/OK button operations
mbahler Mar 26, 2026
a8844f8
Started customBaudRate preference entry
mbahler Mar 26, 2026
cae5396
Merge branch 'bonner72:main' into SettingsWin_Mod
mbahler Mar 26, 2026
3ce8ed9
Import necessary libraries only.
mbahler Mar 27, 2026
7d6067c
Merge branch 'SettingsWin_Mod' of https://github.com/mbahler/SerialTe…
mbahler Mar 27, 2026
6394359
Finished adding custom baudRates to preference.csv
mbahler Mar 27, 2026
088d1e3
Reduce number of default baudRate options.
mbahler Mar 27, 2026
3bae152
Merge branch 'main' into SettingsWin_Mod
mbahler Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"cSpell.words": ["Cascadia", "Lucida"]
"cSpell.words": [
"Autoscrolls",
"Cascadia",
"flatlaf",
"formdev",
"Lucida",
"mbahler"
],
"include": "**/*.{ts,js,php,css,scss,html,pde}"
}
9 changes: 8 additions & 1 deletion mainCode/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"cSpell.words": ["lstop", "tstamp"]
"cSpell.words": [
"Autoscrolls",
"baudedit",
"flatlaf",
"formdev",
"lstop",
"tstamp"
]
}
120 changes: 120 additions & 0 deletions mainCode/baudEditPopup.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// TODO(mbahler): Add custom baud rate read/write handler to preferences.csv
public void initDialogBaudEdit() {
dialogBaudEdit = new JDialog(dialogSettingsMain, "Baud Rate list");
dialogBaudEdit.setSize(new Dimension(300, 300));
dialogBaudEdit.setResizable(false);
dialogBaudEdit.setAlwaysOnTop(true);
dialogBaudEdit.setLocationRelativeTo(dialogSettingsMain);
dialogBaudEdit.setLayout(layoutBaudEdit);
dialogBaudEdit.getContentPane().setBackground(Color.WHITE);
dialogBaudEdit.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialogBaudEdit.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
buttonBaudEditCancel.doClick(); //simulate cancel button click
}
}
);

// initialize and add text area to dialogBaudEdit
textAreaBaudEdit = new JTextArea(java.util.Arrays.toString(baudRateList).replace(",", "\n").replace("[", "").replace("]", "").replace(" ", "").trim());
scrollPaneBaudEdit = new JScrollPane(textAreaBaudEdit);
scrollPaneBaudEdit.setPreferredSize(new Dimension(274, 226));
textAreaBaudEdit.setBackground(Color.WHITE);
textAreaBaudEdit.setLineWrap(true);
textAreaBaudEdit.setAutoscrolls(true);

layoutBaudEdit.putConstraint(SpringLayout.WEST, scrollPaneBaudEdit, 5, SpringLayout.WEST, dialogBaudEdit);
layoutBaudEdit.putConstraint(SpringLayout.NORTH, scrollPaneBaudEdit, 5, SpringLayout.NORTH, dialogBaudEdit);
dialogBaudEdit.add(scrollPaneBaudEdit);


// initialize and add OK button to dialogBaudEdit
buttonBaudEditOk = new JButton("OK");
buttonBaudEditOk.setPreferredSize(new Dimension(60, 20));
buttonBaudEditOk.setFocusPainted(false);
layoutBaudEdit.putConstraint(SpringLayout.EAST, buttonBaudEditOk, 0, SpringLayout.EAST, scrollPaneBaudEdit);
layoutBaudEdit.putConstraint(SpringLayout.NORTH, buttonBaudEditOk, 5, SpringLayout.SOUTH, scrollPaneBaudEdit);
dialogBaudEdit.add(buttonBaudEditOk);
buttonBaudEditOk.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
/*Process TextArea Get text from textArea and append it to string array*/
int textAreaBaudEditLineCount = textAreaBaudEdit.getLineCount();
String[] textAreaBaudEditArray = {};
try {// Traverse the text in the JTextArea line by line
for (int i = 0; i < textAreaBaudEditLineCount; i ++) {
int start = textAreaBaudEdit.getLineStartOffset(i);
int end = textAreaBaudEdit.getLineEndOffset(i);
//processLine(textArea.getText(start, end-start));
// Step 1: Create a new array with length = original length + 1
textAreaBaudEditArray = Arrays.copyOf(textAreaBaudEditArray, textAreaBaudEditArray.length + 1);

// Step 2: Add the new element to the last index of the new array
textAreaBaudEditArray[textAreaBaudEditArray.length - 1] = textAreaBaudEdit.getText(start, end-start).trim();
systemPrintln(textAreaBaudEdit.getText(start, end-start).trim());
}
}
catch(BadLocationException e) {
// Handle exception as you see fit
}
//end Process TextArea
baudRateList = textAreaBaudEditArray;
newBaudRateModel = new DefaultComboBoxModel(baudRateList); // populate newBaudRateModel with textAreaBaudEdit's text
comboBoxBaudRate.setModel(newBaudRateModel); // set comboBoxBaudRate's model to currBaudRateModel
dialogSettingsMain.setEnabled(true); // enable settings window
dialogBaudEdit.setVisible(false); // hide baud edit window
systemPrintln("buttonBaudEditOk clicked @ " + millis()); // print debug statement
}
}
);

// initialize and add CANCEL button to dialogBaudEdit
buttonBaudEditCancel = new JButton("CANCEL");
buttonBaudEditCancel.setPreferredSize(new Dimension(60, 20));
buttonBaudEditCancel.setMargin(new Insets(0, 0, 0, 0));
buttonBaudEditCancel.setFocusPainted(false);
layoutBaudEdit.putConstraint(SpringLayout.EAST, buttonBaudEditCancel, -5, SpringLayout.WEST, buttonBaudEditOk);
layoutBaudEdit.putConstraint(SpringLayout.NORTH, buttonBaudEditCancel, 5, SpringLayout.SOUTH, scrollPaneBaudEdit);
dialogBaudEdit.add(buttonBaudEditCancel);
buttonBaudEditCancel.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent actionEvent) {
/*Process TextArea Get text from textArea and append it to string array*/
int textAreaBaudEditLineCount = textAreaBaudEdit.getLineCount();
String[] textAreaBaudEditArray = {};
try {// Traverse the text in the JTextArea line by line
for (int i = 0; i < textAreaBaudEditLineCount; i ++) {
int start = textAreaBaudEdit.getLineStartOffset(i);
int end = textAreaBaudEdit.getLineEndOffset(i);
//processLine(textArea.getText(start, end-start));
// Step 1: Create a new array with length = original length + 1
textAreaBaudEditArray = Arrays.copyOf(textAreaBaudEditArray, textAreaBaudEditArray.length + 1);

// Step 2: Add the new element to the last index of the new array
textAreaBaudEditArray[textAreaBaudEditArray.length - 1] = textAreaBaudEdit.getText(start, end-start).trim();
systemPrintln(textAreaBaudEdit.getText(start, end-start).trim());
}
}
catch(BadLocationException e) {
// Handle exception as you see fit
}
//end Process TextArea
if (!textAreaBaudEditArray.equals(baudRateList)) {
textAreaBaudEdit.setText(java.util.Arrays.toString(baudRateList).replace(",", "\n").replace("[", "\n").replace("]", "\n").replace(" ", "").trim());
}
dialogSettingsMain.setEnabled(true); //enable settings window
dialogBaudEdit.setVisible(false); //hide baud edit window
}
}
);

//dialogBaudEdit.pack();

if (dialogBaudEdit != null && textAreaBaudEdit != null && buttonBaudEditOk != null && buttonBaudEditCancel != null) {
dialogBaudEditIsInit = true;
dialogBaudEdit.setVisible(true); // show baud rate edit window
dialogSettingsMain.setEnabled(false); // disable setting window
} else {
dialogBaudEditIsInit = false;
}
}

Binary file added mainCode/code/flatlaf-3.7.1.jar
Binary file not shown.
Binary file added mainCode/data/editBaud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions mainCode/data/preferences.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mode,theme,font,fontSize
0,1,jetbrains-mono.regular.ttf,14.0
mode,theme,font,fontSize,baudRateList
1,1,jetbrains-mono.regular.ttf,14.0,"[4800, 9600, 38400, 57600, 115200]"
Binary file added mainCode/data/refresh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion mainCode/logData.pde
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,3 @@ public void writeToFile(String data) {
}
}
}

98 changes: 67 additions & 31 deletions mainCode/mainCode.pde
Original file line number Diff line number Diff line change
@@ -1,23 +1,54 @@
import processing.serial.*; //import serial library
import com.formdev.flatlaf.FlatLightLaf; //import flatlaf light theme
import com.formdev.flatlaf.FlatDarkLaf; //import flatlaf dark theme
import java.awt.*; //import awt library
import java.awt.Font; //import awt font library
import java.awt.event.*; //import awt event library
import java.awt.event.KeyAdapter; //import awt key adapter library
import java.awt.event.KeyEvent; //import awt key event library
import java.awt.Dimension.*; //import awt dimension library
import java.awt.image.BufferedImage; //import awt buffered image library
import javax.swing.*; //import swing library
import javax.swing.event.*; //import swing event library
import javax.swing.text.*; //import swing text library
import processing.serial.Serial; // import processing Serial
import com.formdev.flatlaf.FlatLightLaf; // import flatlaf light theme
import com.formdev.flatlaf.FlatDarkLaf; // import flatlaf dark theme
import java.awt.Font; // import java Font
import java.awt.FontFormatException; // import java FontFormatException
import java.awt.event.WindowAdapter; // import java WindowAdapter
import java.awt.event.WindowEvent; // import java WindowEvent
import java.awt.event.ActionListener; // import java ActionListener
import java.awt.event.ActionEvent; // import java ActionEvent
import java.awt.event.KeyAdapter; // import java KeyAdapter
import java.awt.event.KeyEvent; // import java KeyEvent
import java.awt.event.ComponentEvent; // import java ComponentEvent
import java.awt.event.FocusListener; // import java FocusListener
import java.awt.event.FocusEvent; // import java FocusEvent
import java.awt.KeyboardFocusManager; // import java KeyBoardFocusManger
import java.awt.Dimension; // import java dimension library
import java.awt.image.BufferedImage; // import java buffered image library
import java.awt.FlowLayout; // import java FlowLayout
import java.awt.Color; // import java Color
import java.awt.Insets; // import java insets

import javax.swing.JFrame; // import javax JFrame
import javax.swing.JPanel; // import javax JPanel
import javax.swing.JButton; // import javax JButton
import javax.swing.JDialog; // import javax JDialog
import javax.swing.JTextArea; // import javax JTextArea
import javax.swing.JTextField; // import javax JTextField
import javax.swing.JScrollPane; // import javax JScrollPane
import javax.swing.JComboBox; // import javax JComboBox
import javax.swing.JCheckBox; // import javax JCheckBox
import javax.swing.JLabel; // import javax JLabel
import javax.swing.SpringLayout; // import javax SpringLayout
import javax.swing.DefaultComboBoxModel; // import javax DefaultComboBox
import javax.swing.UIManager; // import javax UIManager
import javax.swing.UnsupportedLookAndFeelException; // import javax UnsupportedLookAndFeelManager
import javax.swing.event.DocumentListener; // import javax DocumentListener
import javax.swing.event.DocumentEvent; // import javax DocumentEvent
import javax.swing.text.Highlighter; // import javax Highlighter
import javax.swing.text.DefaultHighlighter; // import javax DefaultHighlighter
import javax.swing.text.BadLocationException; // import javax BadLocationException
import javax.swing.ImageIcon; // import javax ImageIcon
import javax.swing.JFileChooser; // import javax JFileChooser

import java.io.File; //import file library
import java.io.FileWriter; //import file writer library
import java.util.Collections; //import collections library
import java.util.Scanner; //import scanner library
import java.util.Arrays; //import arrays library

javax.swing.JFrame frame; //create instance of JFrame
java.awt.Canvas canvas; //create instance of Canvas
javax.swing.JFrame frameMainWindow; //create instance of JFrame
java.awt.Canvas canvasMainWindow; //create instance of Canvas

//append text to textAreaMain
public void textAreaMainMsg(String A, String MSG, String B) {
Expand Down Expand Up @@ -185,23 +216,27 @@ public void setTheme(String theme) {

// Processing setup function
public void setup() {
setTheme("light"); //set software theme
icon = loadImage("icon.png"); //import software icon
bufferedIcon = convertToBufferedImage(icon); //convert PImage to BufferedImage for use as JFrame icon
frame = (javax.swing.JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) ((processing.awt.PSurfaceAWT)surface).getNative();
frame.setLocation(displayWidth/2 - wndMinW/2, displayHeight/2 - wndMinH/2);
frame.setSize(wndMinW, wndMinH);
frame.remove(canvas);
frame.setMinimumSize(new Dimension(wndMinW, wndMinH));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setIconImage(bufferedIcon); //set custom icon
frame.setTitle(versionInfo); //set frame title
frame.setResizable(true); //allow frame resizing
frame.setVisible(true); //make frame visible
setTheme("light"); // set software theme
iconMain = loadImage("icon.png"); // import software icon
iconRefresh = loadImage("refresh.png"); // import refresh button icon
iconEditBaud = loadImage("editBaud.png"); // import edit baud rate button icon
bufferedIconMain = convertToBufferedImage(iconMain); // convert PImage to BufferedImage for use as JFrame icon
bufferedIconRefresh = convertToBufferedImage(iconRefresh); // convert PImage to BufferedImage for use as refresh button icon
bufferedIconEditBaud = convertToBufferedImage(iconEditBaud); // convert PImage to BufferedImage for use as edit baud rate button icon
frameMainWindow = (javax.swing.JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
canvasMainWindow = (processing.awt.PSurfaceAWT.SmoothCanvas) ((processing.awt.PSurfaceAWT)surface).getNative();
frameMainWindow.setLocation(displayWidth/2 - wndMinW/2, displayHeight/2 - wndMinH/2);
frameMainWindow.setSize(wndMinW, wndMinH);
frameMainWindow.remove(canvasMainWindow);
frameMainWindow.setMinimumSize(new Dimension(wndMinW, wndMinH));
frameMainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frameMainWindow.setIconImage(bufferedIconMain); // set custom icon
frameMainWindow.setTitle(versionInfo); // set frame title
frameMainWindow.setResizable(true); // allow frame resizing
frameMainWindow.setVisible(true); // make frame visible

//add component listener for main frame
frame.addComponentListener(new java.awt.event.ComponentAdapter() {
frameMainWindow.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(ComponentEvent e) {
if (mainUiInit == true) { //only run if main UI has been initialized
panelMain.setBounds(0, 0, width, height);
Expand Down Expand Up @@ -272,7 +307,7 @@ public void setup() {
}
textAreaMainMsg("\n", "Enter -h for help", ""); //print help message
systemPrintln("Startup complete" + " @ " + millis());
} // END setup
} // end of setup()

// Processing loop function
public void draw() {
Expand All @@ -282,3 +317,4 @@ public void draw() {
public void settings() {
size(wndMinW, wndMinH);
}

11 changes: 6 additions & 5 deletions mainCode/mainWindowUI.pde
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void drawPanelMain() {
panelMain.setBounds(0, 0, width, height);
panelMain.setBackground(Color.WHITE);
panelMain.setLayout(new FlowLayout());
frame.add(panelMain); //add panel to main frame
frameMainWindow.add(panelMain); //add panel to main frame
systemPrintln("EDT panelMain = " + javax.swing.SwingUtilities.isEventDispatchThread() + " @ " + millis());
panelMain.repaint();
}
Expand Down Expand Up @@ -288,14 +288,15 @@ void drawButtonSettings() {
buttonSettings.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (frameSettings == null) { //if settings window has not been drawn
if (dialogSettingsMain == null) { //if settings window has not been drawn
settingsUI(); //draw settings window
availableCOMs = processing.serial.Serial.list(); //get available serial ports
comboBoxPort.setModel(new DefaultComboBoxModel(availableCOMs));
} else { //otherwise if settings window has been drawn make it visible
frameSettings.setVisible(true);
availableCOMs = processing.serial.Serial.list();//get available serial ports
comboBoxPort.setModel(new DefaultComboBoxModel(availableCOMs));
dialogSettingsMain.setLocationRelativeTo(frameMainWindow); // Center the settings window relative to the main frame
dialogSettingsMain.setVisible(true); // show settings window
frameMainWindow.setEnabled(false); // disable main window
availableCOMs = processing.serial.Serial.list(); // get available serial ports
}
systemPrintln("buttonSettings clicked" + " @ " + millis());
}
Expand Down
18 changes: 9 additions & 9 deletions mainCode/processCommands.pde
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ public void processCommands() {
if (enteredCommand.contains("=")) {
String enteredCommandSplit = enteredCommand.split("=")[1];
if (enteredCommandSplit.equals("true")) {
frameSettings = null; //reset settings frame to force rebuild with new advanced options
dialogSettingsMain = null; //reset settings frame to force rebuild with new advanced options
advancedOptions = true; //enable advanced options
setTableData(); //save advanced options to preferences table
setTableData("advanced"); //save advanced options to preferences table
textAreaMainMsg("\n", "Advanced serial port options enabled.", "");
} else if (enteredCommandSplit.equals("false")) {
frameSettings = null; //reset settings frame to force rebuild with removed advanced options
dialogSettingsMain = null; //reset settings frame to force rebuild with removed advanced options
advancedOptions = false;//disable advanced options
setTableData(); //save advanced options to preferences table
setTableData("advanced"); //save advanced options to preferences table
textAreaMainMsg("\n", "Advanced serial port options disabled.", "");
}
} else {
Expand All @@ -51,12 +51,12 @@ public void processCommands() {
textAreaMainMsg("\n", "Invalid command parameter. Use -tstamp=<true|false>", ""); //invalid format message
}
} else if (enteredCommand.equals("-settings")) { //open settings window
if (frameSettings == null) { //if settings window has not been drawn
if (dialogSettingsMain == null) { //if settings window has not been drawn
settingsUI(); //draw settings window
availableCOMs = processing.serial.Serial.list(); //get available serial ports
comboBoxPort.setModel(new DefaultComboBoxModel(availableCOMs));
} else { //otherwise if settings window has been drawn make it visible
frameSettings.setVisible(true);
dialogSettingsMain.setVisible(true);
availableCOMs = processing.serial.Serial.list();//get available serial ports
comboBoxPort.setModel(new DefaultComboBoxModel(availableCOMs));
}
Expand Down Expand Up @@ -86,7 +86,7 @@ public void processCommands() {
int fontIndex = int(enteredCommandSplit) - 1;
if (fontIndex >= 0 && fontIndex < fontList.length) {
selectedFont = fontList[fontIndex]; //set selected font
setTableData(); //save selected font to preferences table
setTableData("advanced"); //save selected font to preferences table
setFont(selectedFont, selectedFontSize); //apply selected font
textAreaMainMsg("\n", "Set font to " + selectedFont + ".", "");
} else {
Expand All @@ -101,7 +101,7 @@ public void processCommands() {
int fontSize = int(enteredCommandSplit);
if (fontSize == 10 || fontSize == 12 || fontSize == 14 || fontSize == 16 || fontSize == 18) {
selectedFontSize = fontSize; //set selected font size
setTableData(); //save selected font size to preferences table
setTableData("advanced"); //save selected font size to preferences table
setFont(selectedFont, selectedFontSize); //apply selected font size
textAreaMainMsg("\n", "Set font size to " + selectedFontSize + ".", "");
} else {
Expand All @@ -111,4 +111,4 @@ public void processCommands() {
textAreaMainMsg("\n", "Invalid command parameter. Use -fontsize=<size>", ""); //invalid format message
}
}
} // END processCommands
} // end of processCommands()
Loading