From 941050ecf0d71d3d72c56e968e417d981d79c040 Mon Sep 17 00:00:00 2001 From: Pieter12345 Date: Mon, 18 Mar 2019 19:45:29 +0100 Subject: [PATCH] Add contextual menus to input fields - Add contextual menus to text-based monitors (serial / network monitor). - Add contextual menu to installer dialog search filter fields (library manager / contribution manager). - Make installer dialogs focus the search filter field on window-open. This prevents pastes from ending up elsewhere in the case that they are performed before the field has been focussed at least once. Fixes #8423. --- .../contributions/ui/FilterJTextField.java | 19 ++++++++++++ .../contributions/ui/InstallerJDialog.java | 29 +++++++++++++++++++ .../processing/app/AbstractTextMonitor.java | 20 +++++++++++++ 3 files changed, 68 insertions(+) diff --git a/app/src/cc/arduino/contributions/ui/FilterJTextField.java b/app/src/cc/arduino/contributions/ui/FilterJTextField.java index 43fb35f9f..f4cb34203 100644 --- a/app/src/cc/arduino/contributions/ui/FilterJTextField.java +++ b/app/src/cc/arduino/contributions/ui/FilterJTextField.java @@ -124,4 +124,23 @@ public class FilterJTextField extends JTextField { setFont(getFont().deriveFont(Font.PLAIN)); } } + + @Override + public void paste() { + + // Same precondition check as JTextComponent#paste(). + if (!isEditable() || !isEnabled()) { + return; + } + + // Disable hint to prevent the focus handler from clearing the pasted text. + if (showingHint) { + showingHint = false; + setText(""); + updateStyle(); + } + + // Perform the paste. + super.paste(); + } } diff --git a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java index 466bd0dfa..9aa0cd70e 100644 --- a/app/src/cc/arduino/contributions/ui/InstallerJDialog.java +++ b/app/src/cc/arduino/contributions/ui/InstallerJDialog.java @@ -45,8 +45,10 @@ import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; +import java.awt.event.WindowAdapter; import java.util.function.Predicate; +import javax.swing.Action; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -54,6 +56,7 @@ import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; @@ -64,6 +67,7 @@ import javax.swing.border.EmptyBorder; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; +import javax.swing.text.DefaultEditorKit; import cc.arduino.contributions.ui.listeners.AbstractKeyListener; import processing.app.Base; @@ -130,6 +134,31 @@ public abstract class InstallerJDialog extends JDialog { } }; + // Add cut/copy/paste contextual menu to the search filter 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); + + filterField.setComponentPopupMenu(menu); + + // Focus the filter field when the window opens. + addWindowListener(new WindowAdapter() { + @Override + public void windowOpened(WindowEvent e) { + filterField.requestFocus(); + } + }); + filtersContainer = new JPanel(); filtersContainer.setLayout(new BoxLayout(filtersContainer, BoxLayout.X_AXIS)); filtersContainer.add(Box.createHorizontalStrut(5)); diff --git a/app/src/processing/app/AbstractTextMonitor.java b/app/src/processing/app/AbstractTextMonitor.java index 64a0928e5..46d8c6a61 100644 --- a/app/src/processing/app/AbstractTextMonitor.java +++ b/app/src/processing/app/AbstractTextMonitor.java @@ -14,6 +14,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.StringTokenizer; +import javax.swing.Action; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -21,11 +22,13 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.text.DefaultCaret; +import javax.swing.text.DefaultEditorKit; import cc.arduino.packages.BoardPort; @@ -82,6 +85,23 @@ public abstract class AbstractTextMonitor extends AbstractMonitor { } }); + // 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")); clearButton = new JButton(tr("Clear output"));