From 5fecda7dee26ed5f7291708bc16b20f13ea6ea79 Mon Sep 17 00:00:00 2001 From: Kelvin Ly Date: Thu, 30 May 2019 13:44:47 -0400 Subject: [PATCH] Add serial input text field to plotter --- app/src/processing/app/SerialPlotter.java | 112 ++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/app/src/processing/app/SerialPlotter.java b/app/src/processing/app/SerialPlotter.java index b234a3e4d..45a52a454 100644 --- a/app/src/processing/app/SerialPlotter.java +++ b/app/src/processing/app/SerialPlotter.java @@ -26,8 +26,12 @@ import processing.app.legacy.PApplet; import java.util.ArrayList; import javax.swing.*; import javax.swing.border.EmptyBorder; +import javax.swing.text.DefaultEditorKit; import java.awt.*; +import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; @@ -40,6 +44,11 @@ public class SerialPlotter extends AbstractMonitor { private Serial serial; private int serialRate, xCount; + private JLabel noLineEndingAlert; + private JTextField textField; + private JButton sendButton; + private JComboBox lineEndings; + private ArrayList graphs; private final static int BUFFER_CAPACITY = 500; @@ -267,10 +276,113 @@ public class SerialPlotter extends AbstractMonitor { pane.add(serialRates); mainPane.add(pane, BorderLayout.SOUTH); + + textField = new JTextField(40); + // textField is selected every time the window is focused + addWindowFocusListener(new WindowAdapter() { + @Override + public void windowGainedFocus(WindowEvent e) { + textField.requestFocusInWindow(); + } + }); + + // Add cut/copy/paste contextual menu to the text input field. + JPopupMenu menu = new JPopupMenu(); + + Action cut = new DefaultEditorKit.CutAction(); + cut.putValue(Action.NAME, tr("Cut")); + menu.add(cut); + + Action copy = new DefaultEditorKit.CopyAction(); + copy.putValue(Action.NAME, tr("Copy")); + menu.add(copy); + + Action paste = new DefaultEditorKit.PasteAction(); + paste.putValue(Action.NAME, tr("Paste")); + menu.add(paste); + + textField.setComponentPopupMenu(menu); + + sendButton = new JButton(tr("Send")); + + JPanel lowerPane = new JPanel(); + lowerPane.setLayout(new BoxLayout(lowerPane, BoxLayout.X_AXIS)); + lowerPane.setBorder(new EmptyBorder(4, 4, 4, 4)); + + noLineEndingAlert = new JLabel(I18n.format(tr("You've pressed {0} but nothing was sent. Should you select a line ending?"), tr("Send"))); + noLineEndingAlert.setToolTipText(noLineEndingAlert.getText()); + noLineEndingAlert.setForeground(pane.getBackground()); + Dimension minimumSize = new Dimension(noLineEndingAlert.getMinimumSize()); + minimumSize.setSize(minimumSize.getWidth() / 3, minimumSize.getHeight()); + noLineEndingAlert.setMinimumSize(minimumSize); + + + lineEndings = new JComboBox(new String[]{tr("No line ending"), tr("Newline"), tr("Carriage return"), tr("Both NL & CR")}); + lineEndings.addActionListener((ActionEvent event) -> { + PreferencesData.setInteger("serial.line_ending", lineEndings.getSelectedIndex()); + noLineEndingAlert.setForeground(pane.getBackground()); + }); + lineEndings.setMaximumSize(lineEndings.getMinimumSize()); + + lowerPane.add(textField); + lowerPane.add(Box.createRigidArea(new Dimension(4, 0))); + lowerPane.add(sendButton); + + pane.add(lowerPane); + pane.add(noLineEndingAlert); + pane.add(Box.createRigidArea(new Dimension(8, 0))); + pane.add(lineEndings); + + applyPreferences(); + + onSendCommand((ActionEvent event) -> { + send(textField.getText()); + textField.setText(""); + }); + + } + + private void send(String string) { + String s = string; + if (serial != null) { + switch (lineEndings.getSelectedIndex()) { + case 1: + s += "\n"; + break; + case 2: + s += "\r"; + break; + case 3: + s += "\r\n"; + break; + default: + break; + } + if ("".equals(s) && lineEndings.getSelectedIndex() == 0 && !PreferencesData.has("runtime.line.ending.alert.notified")) { + noLineEndingAlert.setForeground(Color.RED); + PreferencesData.set("runtime.line.ending.alert.notified", "true"); + } + serial.write(s); + } + } + + public void onSendCommand(ActionListener listener) { + textField.addActionListener(listener); + sendButton.addActionListener(listener); + } + + public void appyPreferences() { + // Apply line endings. + if (PreferencesData.get("serial.line_ending") != null) { + lineEndings.setSelectedIndex(PreferencesData.getInteger("serial.line_ending")); + } } protected void onEnableWindow(boolean enable) { serialRates.setEnabled(enable); + textField.setEnabled(enable); + sendButton.setEnabled(enable); + lineEndings.setEnabled(enable); } private void onSerialRateChange(ActionListener listener) {