32
32
import javax .swing .border .EmptyBorder ;
33
33
import javax .swing .text .DefaultCaret ;
34
34
import javax .swing .text .DefaultEditorKit ;
35
+ import javax .swing .event .UndoableEditListener ;
36
+ import javax .swing .text .AbstractDocument ;
37
+ import javax .swing .text .Document ;
35
38
36
39
import cc .arduino .packages .BoardPort ;
37
40
@@ -40,14 +43,20 @@ public abstract class AbstractTextMonitor extends AbstractMonitor {
40
43
41
44
protected JLabel noLineEndingAlert ;
42
45
protected TextAreaFIFO textArea ;
46
+ protected HTMLTextAreaFIFO htmlTextArea ;
43
47
protected JScrollPane scrollPane ;
48
+ protected JScrollPane htmlScrollPane ;
44
49
protected JTextField textField ;
45
50
protected JButton sendButton ;
46
51
protected JButton clearButton ;
47
52
protected JCheckBox autoscrollBox ;
48
53
protected JCheckBox addTimeStampBox ;
49
54
protected JComboBox <String > lineEndings ;
50
55
protected JComboBox <String > serialRates ;
56
+ protected Container mainPane ;
57
+ private long lastMessage ;
58
+ private javax .swing .Timer updateTimer ;
59
+ private boolean htmlView = true ;
51
60
52
61
public AbstractTextMonitor (BoardPort boardPort ) {
53
62
super (boardPort );
@@ -69,21 +78,97 @@ public synchronized void addKeyListener(KeyListener l) {
69
78
@ Override
70
79
protected void onCreateWindow (Container mainPane ) {
71
80
81
+ this .mainPane = mainPane ;
72
82
mainPane .setLayout (new BorderLayout ());
73
83
74
84
textArea = new TextAreaFIFO (8_000_000 );
75
85
textArea .setRows (16 );
76
86
textArea .setColumns (40 );
77
87
textArea .setEditable (false );
78
88
89
+ htmlTextArea = new HTMLTextAreaFIFO (8000000 );
90
+ htmlTextArea .setEditable (false );
91
+ htmlTextArea .setOpaque (false );
92
+
79
93
// don't automatically update the caret. that way we can manually decide
80
94
// whether or not to do so based on the autoscroll checkbox.
81
95
((DefaultCaret ) textArea .getCaret ()).setUpdatePolicy (DefaultCaret .NEVER_UPDATE );
96
+ ((DefaultCaret ) htmlTextArea .getCaret ()).setUpdatePolicy (DefaultCaret .NEVER_UPDATE );
97
+
98
+ Document doc = textArea .getDocument ();
99
+ if (doc instanceof AbstractDocument )
100
+ {
101
+ UndoableEditListener [] undoListeners =
102
+ ( (AbstractDocument ) doc ).getUndoableEditListeners ();
103
+ if (undoListeners .length > 0 )
104
+ {
105
+ for (UndoableEditListener undoListener : undoListeners )
106
+ {
107
+ doc .removeUndoableEditListener (undoListener );
108
+ }
109
+ }
110
+ }
111
+
112
+ doc = htmlTextArea .getDocument ();
113
+ if (doc instanceof AbstractDocument )
114
+ {
115
+ UndoableEditListener [] undoListeners =
116
+ ( (AbstractDocument ) doc ).getUndoableEditListeners ();
117
+ if (undoListeners .length > 0 )
118
+ {
119
+ for (UndoableEditListener undoListener : undoListeners )
120
+ {
121
+ doc .removeUndoableEditListener (undoListener );
122
+ }
123
+ }
124
+ }
82
125
83
126
scrollPane = new JScrollPane (textArea );
127
+ scrollPane .setVerticalScrollBarPolicy (JScrollPane .VERTICAL_SCROLLBAR_AS_NEEDED );
128
+ htmlScrollPane = new JScrollPane (htmlTextArea );
129
+ htmlScrollPane .setVerticalScrollBarPolicy (JScrollPane .VERTICAL_SCROLLBAR_AS_NEEDED );
130
+
131
+ ActionListener checkIfSteady = new ActionListener () {
132
+ public void actionPerformed (ActionEvent evt ) {
133
+ if (System .currentTimeMillis () - lastMessage > 200 ) {
134
+ if (htmlView == false && textArea .getLength () < 1000 ) {
135
+
136
+ htmlTextArea .setText ("" );
137
+ boolean res = htmlTextArea .append (textArea .getText ());
138
+ if (res ) {
139
+ htmlView = true ;
140
+ mainPane .remove (scrollPane );
141
+ if (textArea .getCaretPosition () > htmlTextArea .getDocument ().getLength ()) {
142
+ htmlTextArea .setCaretPosition (htmlTextArea .getDocument ().getLength ());
143
+ } else {
144
+ htmlTextArea .setCaretPosition (textArea .getCaretPosition ());
145
+ }
146
+ mainPane .add (htmlScrollPane , BorderLayout .CENTER );
147
+ scrollPane .setVisible (false );
148
+ mainPane .validate ();
149
+ mainPane .repaint ();
150
+ }
151
+ }
152
+ } else {
153
+ if (htmlView == true ) {
154
+ htmlView = false ;
155
+ mainPane .remove (htmlScrollPane );
156
+ mainPane .add (scrollPane , BorderLayout .CENTER );
157
+ scrollPane .setVisible (true );
158
+ mainPane .validate ();
159
+ mainPane .repaint ();
160
+ }
161
+ }
162
+ }
163
+ };
164
+
165
+ updateTimer = new javax .swing .Timer (33 , checkIfSteady );
84
166
85
167
mainPane .add (scrollPane , BorderLayout .CENTER );
86
168
169
+ htmlTextArea .setVisible (true );
170
+ htmlScrollPane .setVisible (true );
171
+
87
172
JPanel upperPane = new JPanel ();
88
173
upperPane .setLayout (new BoxLayout (upperPane , BoxLayout .X_AXIS ));
89
174
upperPane .setBorder (new EmptyBorder (4 , 4 , 4 , 4 ));
@@ -168,6 +253,8 @@ public void windowGainedFocus(WindowEvent e) {
168
253
applyPreferences ();
169
254
170
255
mainPane .add (pane , BorderLayout .SOUTH );
256
+
257
+ updateTimer .start ();
171
258
}
172
259
173
260
@ Override
@@ -191,13 +278,18 @@ protected void onEnableWindow(boolean enable) {
191
278
}
192
279
textArea .invalidate ();
193
280
clearButton .setEnabled (enable );
281
+ htmlTextArea .setEnabled (enable );
194
282
scrollPane .setEnabled (enable );
283
+ htmlScrollPane .setEnabled (enable );
195
284
textField .setEnabled (enable );
196
285
sendButton .setEnabled (enable );
197
286
autoscrollBox .setEnabled (enable );
198
287
addTimeStampBox .setEnabled (enable );
199
288
lineEndings .setEnabled (enable );
200
289
serialRates .setEnabled (enable );
290
+ if (enable == false ) {
291
+ htmlTextArea .setText ("" );
292
+ }
201
293
}
202
294
203
295
public void onSendCommand (ActionListener listener ) {
@@ -215,6 +307,7 @@ public void onSerialRateChange(ActionListener listener) {
215
307
216
308
@ Override
217
309
public void message (String msg ) {
310
+ lastMessage = System .currentTimeMillis ();
218
311
SwingUtilities .invokeLater (() -> updateTextArea (msg ));
219
312
}
220
313
0 commit comments