36
36
import java .awt .Frame ;
37
37
import java .awt .Image ;
38
38
import java .awt .Point ;
39
- import java .awt .event .ComponentAdapter ;
40
- import java .awt .event .ComponentEvent ;
41
- import java .awt .event .MouseAdapter ;
42
- import java .awt .event .MouseEvent ;
43
- import java .awt .event .WindowAdapter ;
44
- import java .awt .event .WindowEvent ;
39
+ import java .awt .event .*;
45
40
import java .util .Timer ;
46
41
import java .util .TimerTask ;
47
42
55
50
import javax .swing .event .HyperlinkListener ;
56
51
57
52
import cc .arduino .Constants ;
53
+ import processing .app .PreferencesData ;
58
54
import processing .app .Theme ;
59
55
56
+ import java .awt .event .KeyEvent ;
57
+
58
+ import static processing .app .I18n .tr ;
59
+
60
60
public class NotificationPopup extends JDialog {
61
+ public interface OptionalButtonCallbacks {
62
+ void onOptionalButton1Callback ();
63
+ void onOptionalButton2Callback ();
64
+ }
61
65
62
66
private Timer autoCloseTimer = new Timer (false );
63
67
private boolean autoClose = true ;
68
+ private OptionalButtonCallbacks optionalButtonCallbacks ;
64
69
65
70
public NotificationPopup (Frame parent , HyperlinkListener hyperlinkListener ,
66
71
String message ) {
67
- this (parent , hyperlinkListener , message , true );
72
+ this (parent , hyperlinkListener , message , true , null , null , null );
68
73
}
69
74
70
75
public NotificationPopup (Frame parent , HyperlinkListener hyperlinkListener ,
71
76
String message , boolean _autoClose ) {
77
+ this (parent , hyperlinkListener , message , _autoClose , null , null , null );
78
+ }
79
+
80
+ public NotificationPopup (Frame parent , HyperlinkListener hyperlinkListener ,
81
+ String message , boolean _autoClose , OptionalButtonCallbacks listener , String button1Name , String button2Name ) {
72
82
super (parent , false );
73
- autoClose = _autoClose ;
83
+
84
+ if (!PreferencesData .getBoolean ("ide.accessible" )) {
85
+ // often auto-close is too fast for users of screen readers, so don't allow it.
86
+ autoClose = _autoClose ;
87
+ }
88
+ else {
89
+ autoClose = false ;
90
+ }
91
+ optionalButtonCallbacks = listener ;
92
+
74
93
setLayout (new FlowLayout ());
75
94
setDefaultCloseOperation (WindowConstants .DISPOSE_ON_CLOSE );
76
95
setUndecorated (true );
@@ -90,13 +109,89 @@ public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener,
90
109
text .addHyperlinkListener (hyperlinkListener );
91
110
add (text );
92
111
112
+ if (button1Name != null ) {
113
+ JButton optionalButton1 = new JButton (tr (button1Name ));
114
+ MouseAdapter button1Action = new MouseAdapter () {
115
+ @ Override
116
+ public void mouseClicked (MouseEvent e ) {
117
+ if (optionalButtonCallbacks != null ) {
118
+ optionalButtonCallbacks .onOptionalButton1Callback ();
119
+ }
120
+ }
121
+ };
122
+ optionalButton1 .addMouseListener (button1Action );
123
+
124
+ KeyListener button1Key = new KeyListener () {
125
+ public void keyTyped (KeyEvent e ) {
126
+ }
127
+
128
+ public void keyPressed (KeyEvent e ) {
129
+ }
130
+
131
+ public void keyReleased (KeyEvent e ) {
132
+ int key = e .getKeyCode ();
133
+ if ((key == KeyEvent .VK_ENTER ) || (key == KeyEvent .VK_SPACE )) {
134
+ optionalButtonCallbacks .onOptionalButton1Callback ();
135
+ }
136
+ }
137
+ };
138
+ optionalButton1 .addKeyListener (button1Key );
139
+ add (optionalButton1 );
140
+ }
141
+
142
+ if (button2Name != null ) {
143
+ JButton optionalButton2 = new JButton (tr (button2Name ));
144
+ MouseAdapter button2Action = new MouseAdapter () {
145
+ @ Override
146
+ public void mouseClicked (MouseEvent e ) {
147
+ if (optionalButtonCallbacks != null ) {
148
+ optionalButtonCallbacks .onOptionalButton2Callback ();
149
+ }
150
+ }
151
+ };
152
+ optionalButton2 .addMouseListener (button2Action );
153
+
154
+ KeyListener button2Key = new KeyListener () {
155
+ public void keyTyped (KeyEvent e ) {
156
+ }
157
+
158
+ public void keyPressed (KeyEvent e ) {
159
+ }
160
+
161
+ public void keyReleased (KeyEvent e ) {
162
+ int key = e .getKeyCode ();
163
+ if ((key == KeyEvent .VK_ENTER ) || (key == KeyEvent .VK_SPACE )) {
164
+ optionalButtonCallbacks .onOptionalButton2Callback ();
165
+ }
166
+ }
167
+ };
168
+ optionalButton2 .addKeyListener (button2Key );
169
+ add (optionalButton2 );
170
+ }
171
+
93
172
Image close = Theme .getThemeImage ("close" , this , scale (22 ), scale (22 ));
94
173
JButton closeButton = new JButton (new ImageIcon (close ));
95
174
closeButton .setBorder (null );
96
175
closeButton .setBorderPainted (false );
97
176
closeButton .setHideActionText (true );
98
177
closeButton .setOpaque (false );
99
178
closeButton .setBackground (new Color (0 , 0 , 0 , 0 ));
179
+ closeButton .getAccessibleContext ().setAccessibleDescription (tr ("Close" ));
180
+ KeyListener closeKey = new KeyListener () {
181
+ public void keyTyped (KeyEvent e ) {
182
+ }
183
+
184
+ public void keyPressed (KeyEvent e ) {
185
+ }
186
+
187
+ public void keyReleased (KeyEvent e ) {
188
+ int key = e .getKeyCode ();
189
+ if ((key == KeyEvent .VK_ENTER ) || (key == KeyEvent .VK_SPACE )) {
190
+ close ();
191
+ }
192
+ }
193
+ };
194
+ closeButton .addKeyListener (closeKey );
100
195
add (closeButton );
101
196
102
197
MouseAdapter closeOnClick = new MouseAdapter () {
@@ -158,5 +253,9 @@ public void run() {
158
253
}, Constants .NOTIFICATION_POPUP_AUTOCLOSE_DELAY );
159
254
}
160
255
setVisible (true );
256
+ if (PreferencesData .getBoolean ("ide.accessible" )) {
257
+ requestFocus ();
258
+ setModal (true );
259
+ }
161
260
}
162
261
}
0 commit comments