3131package org .scijava .ui .swing .console ;
3232
3333import java .awt .*;
34+ import java .awt .event .ActionEvent ;
3435import java .util .function .Predicate ;
3536import java .util .stream .Stream ;
3637
3738import javax .swing .*;
39+ import javax .swing .plaf .basic .BasicArrowButton ;
3840import javax .swing .text .AttributeSet ;
3941import javax .swing .text .MutableAttributeSet ;
4042import javax .swing .text .SimpleAttributeSet ;
@@ -76,6 +78,8 @@ public class LoggingPanel extends JPanel implements LogListener
7678 new TextFilterField (" Text Search (Alt-F)" );
7779 private final ItemTextPane textArea ;
7880
81+ private final JPanel textFilterPanel = new JPanel ();
82+
7983 private final LogFormatter logFormatter = new LogFormatter ();
8084
8185 private LogRecorder recorder ;
@@ -101,6 +105,18 @@ public void setRecorder(LogRecorder recorder) {
101105 recorder .addObservers (textArea ::update );
102106 }
103107
108+ public void setTextFilterVisible (boolean visible ) {
109+ textFilterPanel .setVisible (visible );
110+ }
111+
112+ public void copySelectionToClipboard () {
113+ textArea .copySelectionToClipboard ();
114+ }
115+
116+ public void focusTextFilter () {
117+ textFilter .getComponent ().requestFocus ();
118+ }
119+
104120 public void clear () {
105121 recorder .clear ();
106122 updateFilter ();
@@ -118,11 +134,63 @@ public void messageLogged(LogMessage message) {
118134 private void initGui () {
119135 textFilter .setChangeListener (this ::updateFilter );
120136
137+ JPopupMenu menu = initMenu ();
138+
139+ JButton menuButton = new BasicArrowButton (BasicArrowButton .SOUTH );
140+ menuButton .addActionListener (a ->
141+ menu .show (menuButton , 0 , menuButton .getHeight ()));
142+
143+ textFilterPanel .setLayout (new MigLayout ("insets 0" , "[][grow]" , "[]" ));
144+ textFilterPanel .add (menuButton );
145+ textFilterPanel .add (textFilter .getComponent (), "grow" );
146+
147+ textArea .setPopupMenu (menu );
121148 textArea .getJComponent ().setPreferredSize (new Dimension (200 , 100 ));
122149
123150 this .setLayout (new MigLayout ("insets 0" , "[grow]" , "[][grow]" ));
124- this .add (textFilter . getComponent () , "grow, wrap" );
151+ this .add (textFilterPanel , "grow, wrap" );
125152 this .add (textArea .getJComponent (), "grow" );
153+
154+ registerKeyStroke ("alt F" , "focusTextFilter" , this ::focusTextFilter );
155+ }
156+
157+ private void registerKeyStroke (String keyStroke , String id , final Runnable action ) {
158+ getInputMap (JComponent .WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).put (KeyStroke
159+ .getKeyStroke (keyStroke ), id );
160+ getActionMap ().put (id , new AbstractAction () {
161+
162+ @ Override
163+ public void actionPerformed (ActionEvent actionEvent ) {
164+ action .run ();
165+ }
166+ });
167+ }
168+
169+ private JPopupMenu initMenu () {
170+ JPopupMenu menu = new JPopupMenu ();
171+ menu .add (newMenuItem ("Copy" , "control C" ,
172+ this ::copySelectionToClipboard ));
173+ registerKeyStroke ("control C" , "copyToClipBoard" ,
174+ this ::copySelectionToClipboard );
175+ menu .add (newMenuItem ("Clear" , "alt C" ,
176+ this ::clear ));
177+ registerKeyStroke ("alt C" , "clearLoggingPanel" ,
178+ this ::clear );
179+ return menu ;
180+ }
181+
182+ static private JMenuItem newMenuItem (String text , String keyStroke ,
183+ Runnable runnable )
184+ {
185+ JMenuItem item = newMenuItem (text , runnable );
186+ item .setAccelerator (KeyStroke .getKeyStroke (keyStroke ));
187+ return item ;
188+ }
189+
190+ static private JMenuItem newMenuItem (String text , Runnable runnable ) {
191+ JMenuItem item = new JMenuItem (text );
192+ item .addActionListener (actionEvent -> runnable .run ());
193+ return item ;
126194 }
127195
128196 private void updateFilter () {
0 commit comments