26
26
import javax .swing .SwingUtilities ;
27
27
import javax .swing .border .EmptyBorder ;
28
28
import javax .swing .text .DefaultCaret ;
29
+ import javax .swing .event .UndoableEditListener ;
30
+ import javax .swing .text .AbstractDocument ;
31
+ import javax .swing .text .Document ;
29
32
30
33
import cc .arduino .packages .BoardPort ;
31
34
@@ -34,14 +37,20 @@ public abstract class AbstractTextMonitor extends AbstractMonitor {
34
37
35
38
protected JLabel noLineEndingAlert ;
36
39
protected TextAreaFIFO textArea ;
40
+ protected HTMLTextAreaFIFO htmlTextArea ;
37
41
protected JScrollPane scrollPane ;
42
+ protected JScrollPane htmlScrollPane ;
38
43
protected JTextField textField ;
39
44
protected JButton sendButton ;
40
45
protected JButton clearButton ;
41
46
protected JCheckBox autoscrollBox ;
42
47
protected JCheckBox addTimeStampBox ;
43
48
protected JComboBox lineEndings ;
44
49
protected JComboBox serialRates ;
50
+ protected Container mainPane ;
51
+ private long lastMessage ;
52
+ private javax .swing .Timer updateTimer ;
53
+ private boolean htmlView = true ;
45
54
46
55
public AbstractTextMonitor (BoardPort boardPort ) {
47
56
super (boardPort );
@@ -52,6 +61,7 @@ protected void onCreateWindow(Container mainPane) {
52
61
Font editorFont = PreferencesData .getFont ("editor.font" );
53
62
Font font = Theme .scale (new Font (consoleFont .getName (), consoleFont .getStyle (), editorFont .getSize ()));
54
63
64
+ this .mainPane = mainPane ;
55
65
mainPane .setLayout (new BorderLayout ());
56
66
57
67
textArea = new TextAreaFIFO (8_000_000 );
@@ -60,14 +70,90 @@ protected void onCreateWindow(Container mainPane) {
60
70
textArea .setEditable (false );
61
71
textArea .setFont (font );
62
72
73
+ htmlTextArea = new HTMLTextAreaFIFO (8000000 );
74
+ htmlTextArea .setEditable (false );
75
+ htmlTextArea .setFont (font );
76
+ htmlTextArea .setOpaque (false );
77
+
63
78
// don't automatically update the caret. that way we can manually decide
64
79
// whether or not to do so based on the autoscroll checkbox.
65
80
((DefaultCaret ) textArea .getCaret ()).setUpdatePolicy (DefaultCaret .NEVER_UPDATE );
81
+ ((DefaultCaret ) htmlTextArea .getCaret ()).setUpdatePolicy (DefaultCaret .NEVER_UPDATE );
82
+
83
+ Document doc = textArea .getDocument ();
84
+ if (doc instanceof AbstractDocument )
85
+ {
86
+ UndoableEditListener [] undoListeners =
87
+ ( (AbstractDocument ) doc ).getUndoableEditListeners ();
88
+ if (undoListeners .length > 0 )
89
+ {
90
+ for (UndoableEditListener undoListener : undoListeners )
91
+ {
92
+ doc .removeUndoableEditListener (undoListener );
93
+ }
94
+ }
95
+ }
96
+
97
+ doc = htmlTextArea .getDocument ();
98
+ if (doc instanceof AbstractDocument )
99
+ {
100
+ UndoableEditListener [] undoListeners =
101
+ ( (AbstractDocument ) doc ).getUndoableEditListeners ();
102
+ if (undoListeners .length > 0 )
103
+ {
104
+ for (UndoableEditListener undoListener : undoListeners )
105
+ {
106
+ doc .removeUndoableEditListener (undoListener );
107
+ }
108
+ }
109
+ }
66
110
67
111
scrollPane = new JScrollPane (textArea );
112
+ scrollPane .setVerticalScrollBarPolicy (JScrollPane .VERTICAL_SCROLLBAR_AS_NEEDED );
113
+ htmlScrollPane = new JScrollPane (htmlTextArea );
114
+ htmlScrollPane .setVerticalScrollBarPolicy (JScrollPane .VERTICAL_SCROLLBAR_AS_NEEDED );
115
+
116
+ ActionListener checkIfSteady = new ActionListener () {
117
+ public void actionPerformed (ActionEvent evt ) {
118
+ if (System .currentTimeMillis () - lastMessage > 200 ) {
119
+ if (htmlView == false && textArea .getLength () < 1000 ) {
120
+
121
+ htmlTextArea .setText ("" );
122
+ boolean res = htmlTextArea .append (textArea .getText ());
123
+ if (res ) {
124
+ htmlView = true ;
125
+ mainPane .remove (scrollPane );
126
+ if (textArea .getCaretPosition () > htmlTextArea .getDocument ().getLength ()) {
127
+ htmlTextArea .setCaretPosition (htmlTextArea .getDocument ().getLength ());
128
+ } else {
129
+ htmlTextArea .setCaretPosition (textArea .getCaretPosition ());
130
+ }
131
+ mainPane .add (htmlScrollPane , BorderLayout .CENTER );
132
+ scrollPane .setVisible (false );
133
+ mainPane .validate ();
134
+ mainPane .repaint ();
135
+ }
136
+ }
137
+ } else {
138
+ if (htmlView == true ) {
139
+ htmlView = false ;
140
+ mainPane .remove (htmlScrollPane );
141
+ mainPane .add (scrollPane , BorderLayout .CENTER );
142
+ scrollPane .setVisible (true );
143
+ mainPane .validate ();
144
+ mainPane .repaint ();
145
+ }
146
+ }
147
+ }
148
+ };
149
+
150
+ updateTimer = new javax .swing .Timer (33 , checkIfSteady );
68
151
69
152
mainPane .add (scrollPane , BorderLayout .CENTER );
70
153
154
+ htmlTextArea .setVisible (true );
155
+ htmlScrollPane .setVisible (true );
156
+
71
157
JPanel upperPane = new JPanel ();
72
158
upperPane .setLayout (new BoxLayout (upperPane , BoxLayout .X_AXIS ));
73
159
upperPane .setBorder (new EmptyBorder (4 , 4 , 4 , 4 ));
@@ -143,19 +229,26 @@ public void actionPerformed(ActionEvent e) {
143
229
pane .add (clearButton );
144
230
145
231
mainPane .add (pane , BorderLayout .SOUTH );
232
+
233
+ updateTimer .start ();
146
234
}
147
235
148
236
protected void onEnableWindow (boolean enable )
149
237
{
150
238
textArea .setEnabled (enable );
151
239
clearButton .setEnabled (enable );
240
+ htmlTextArea .setEnabled (enable );
152
241
scrollPane .setEnabled (enable );
242
+ htmlScrollPane .setEnabled (enable );
153
243
textField .setEnabled (enable );
154
244
sendButton .setEnabled (enable );
155
245
autoscrollBox .setEnabled (enable );
156
246
addTimeStampBox .setEnabled (enable );
157
247
lineEndings .setEnabled (enable );
158
248
serialRates .setEnabled (enable );
249
+ if (enable == false ) {
250
+ htmlTextArea .setText ("" );
251
+ }
159
252
}
160
253
161
254
public void onSendCommand (ActionListener listener ) {
@@ -172,6 +265,7 @@ public void onSerialRateChange(ActionListener listener) {
172
265
}
173
266
174
267
public void message (String msg ) {
268
+ lastMessage = System .currentTimeMillis ();
175
269
SwingUtilities .invokeLater (() -> updateTextArea (msg ));
176
270
}
177
271
0 commit comments