Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.jconsole/share/classes/sun/tools/jconsole/VMPanel.java
40948 views
1
/*
2
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.tools.jconsole;
27
28
import java.awt.*;
29
import java.awt.event.*;
30
import java.beans.*;
31
import java.lang.reflect.*;
32
import java.util.*;
33
import java.util.List;
34
import java.util.Timer;
35
import javax.swing.*;
36
import javax.swing.plaf.*;
37
38
39
import com.sun.tools.jconsole.JConsolePlugin;
40
import com.sun.tools.jconsole.JConsoleContext;
41
42
import static sun.tools.jconsole.ProxyClient.*;
43
44
@SuppressWarnings("serial")
45
public class VMPanel extends JTabbedPane implements PropertyChangeListener {
46
47
private ProxyClient proxyClient;
48
private Timer timer;
49
private int updateInterval;
50
private String hostName;
51
private int port;
52
private String userName;
53
private String password;
54
private String url;
55
private VMInternalFrame vmIF = null;
56
private static ArrayList<TabInfo> tabInfos = new ArrayList<TabInfo>();
57
private boolean wasConnected = false;
58
private boolean userDisconnected = false;
59
private boolean shouldUseSSL = true;
60
61
// The everConnected flag keeps track of whether the window can be
62
// closed if the user clicks Cancel after a failed connection attempt.
63
//
64
private boolean everConnected = false;
65
66
// The initialUpdate flag is used to enable/disable tabs each time
67
// a connect or reconnect takes place. This flag avoids having to
68
// enable/disable tabs on each update call.
69
//
70
private boolean initialUpdate = true;
71
72
// Each VMPanel has its own instance of the JConsolePlugin
73
// A map of JConsolePlugin to the previous SwingWorker
74
private Map<ExceptionSafePlugin, SwingWorker<?, ?>> plugins = null;
75
private boolean pluginTabsAdded = false;
76
77
// Update these only on the EDT
78
private JOptionPane optionPane;
79
private JProgressBar progressBar;
80
private long time0;
81
82
static {
83
tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true));
84
tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true));
85
tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true));
86
tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true));
87
tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true));
88
tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true));
89
}
90
91
public static TabInfo[] getTabInfos() {
92
return tabInfos.toArray(new TabInfo[tabInfos.size()]);
93
}
94
95
VMPanel(ProxyClient proxyClient, int updateInterval) {
96
this.proxyClient = proxyClient;
97
this.updateInterval = updateInterval;
98
this.hostName = proxyClient.getHostName();
99
this.port = proxyClient.getPort();
100
this.userName = proxyClient.getUserName();
101
this.password = proxyClient.getPassword();
102
this.url = proxyClient.getUrl();
103
104
for (TabInfo tabInfo : tabInfos) {
105
if (tabInfo.tabVisible) {
106
addTab(tabInfo);
107
}
108
}
109
110
plugins = new LinkedHashMap<ExceptionSafePlugin, SwingWorker<?, ?>>();
111
for (JConsolePlugin p : JConsole.getPlugins()) {
112
p.setContext(proxyClient);
113
plugins.put(new ExceptionSafePlugin(p), null);
114
}
115
116
Utilities.updateTransparency(this);
117
118
ToolTipManager.sharedInstance().registerComponent(this);
119
120
// Start listening to connection state events
121
//
122
proxyClient.addPropertyChangeListener(this);
123
124
addMouseListener(new MouseAdapter() {
125
126
public void mouseClicked(MouseEvent e) {
127
if (connectedIconBounds != null
128
&& (e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0
129
&& connectedIconBounds.contains(e.getPoint())) {
130
131
if (isConnected()) {
132
userDisconnected = true;
133
disconnect();
134
wasConnected = false;
135
} else {
136
connect();
137
}
138
repaint();
139
}
140
}
141
});
142
143
}
144
private static Icon connectedIcon16 =
145
new ImageIcon(VMPanel.class.getResource("resources/connected16.png"));
146
private static Icon connectedIcon24 =
147
new ImageIcon(VMPanel.class.getResource("resources/connected24.png"));
148
private static Icon disconnectedIcon16 =
149
new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png"));
150
private static Icon disconnectedIcon24 =
151
new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png"));
152
private Rectangle connectedIconBounds;
153
154
// Override to increase right inset for tab area,
155
// in order to reserve space for the connect toggle.
156
public void setUI(TabbedPaneUI ui) {
157
Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
158
if (insets != null) {
159
insets = (Insets) insets.clone();
160
insets.right += connectedIcon24.getIconWidth() + 8;
161
UIManager.put("TabbedPane.tabAreaInsets", insets);
162
}
163
super.setUI(ui);
164
}
165
166
// Override to paint the connect toggle
167
protected void paintComponent(Graphics g) {
168
super.paintComponent(g);
169
170
Icon icon;
171
Component c0 = getComponent(0);
172
if (c0 != null && c0.getY() > 24) {
173
icon = isConnected() ? connectedIcon24 : disconnectedIcon24;
174
} else {
175
icon = isConnected() ? connectedIcon16 : disconnectedIcon16;
176
}
177
Insets insets = getInsets();
178
int x = getWidth() - insets.right - icon.getIconWidth() - 4;
179
int y = insets.top;
180
if (c0 != null) {
181
y = (c0.getY() - icon.getIconHeight()) / 2;
182
}
183
icon.paintIcon(this, g, x, y);
184
connectedIconBounds = new Rectangle(x, y, icon.getIconWidth(), icon.getIconHeight());
185
}
186
187
public String getToolTipText(MouseEvent event) {
188
if (connectedIconBounds.contains(event.getPoint())) {
189
if (isConnected()) {
190
return Messages.CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_;
191
} else {
192
return Messages.DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_;
193
}
194
} else {
195
return super.getToolTipText(event);
196
}
197
}
198
199
private synchronized void addTab(TabInfo tabInfo) {
200
Tab tab = instantiate(tabInfo);
201
if (tab != null) {
202
addTab(tabInfo.name, tab);
203
} else {
204
tabInfo.tabVisible = false;
205
}
206
}
207
208
private synchronized void insertTab(TabInfo tabInfo, int index) {
209
Tab tab = instantiate(tabInfo);
210
if (tab != null) {
211
insertTab(tabInfo.name, null, tab, null, index);
212
} else {
213
tabInfo.tabVisible = false;
214
}
215
}
216
217
public synchronized void removeTabAt(int index) {
218
super.removeTabAt(index);
219
}
220
221
private Tab instantiate(TabInfo tabInfo) {
222
try {
223
Constructor<?> con = tabInfo.tabClass.getConstructor(VMPanel.class);
224
return (Tab) con.newInstance(this);
225
} catch (Exception ex) {
226
System.err.println(ex);
227
return null;
228
}
229
}
230
231
boolean isConnected() {
232
return proxyClient.isConnected();
233
}
234
235
public int getUpdateInterval() {
236
return updateInterval;
237
}
238
239
/**
240
* WARNING NEVER CALL THIS METHOD TO MAKE JMX REQUEST
241
* IF assertThread == false.
242
* DISPATCHER THREAD IS NOT ASSERTED.
243
* IT IS USED TO MAKE SOME LOCAL MANIPULATIONS.
244
*/
245
ProxyClient getProxyClient(boolean assertThread) {
246
if (assertThread) {
247
return getProxyClient();
248
} else {
249
return proxyClient;
250
}
251
}
252
253
public ProxyClient getProxyClient() {
254
String threadClass = Thread.currentThread().getClass().getName();
255
if (threadClass.equals("java.awt.EventDispatchThread")) {
256
String msg = "Calling VMPanel.getProxyClient() from the Event Dispatch Thread!";
257
new RuntimeException(msg).printStackTrace();
258
System.exit(1);
259
}
260
return proxyClient;
261
}
262
263
public void cleanUp() {
264
//proxyClient.disconnect();
265
for (Tab tab : getTabs()) {
266
tab.dispose();
267
}
268
for (JConsolePlugin p : plugins.keySet()) {
269
p.dispose();
270
}
271
// Cancel pending update tasks
272
//
273
if (timer != null) {
274
timer.cancel();
275
}
276
// Stop listening to connection state events
277
//
278
proxyClient.removePropertyChangeListener(this);
279
}
280
281
// Call on EDT
282
public void connect() {
283
if (isConnected()) {
284
// create plugin tabs if not done
285
createPluginTabs();
286
// Notify tabs
287
fireConnectedChange(true);
288
// Enable/disable tabs on initial update
289
initialUpdate = true;
290
// Start/Restart update timer on connect/reconnect
291
startUpdateTimer();
292
} else {
293
new Thread("VMPanel.connect") {
294
295
public void run() {
296
proxyClient.connect(shouldUseSSL);
297
}
298
}.start();
299
}
300
}
301
302
// Call on EDT
303
public void disconnect() {
304
proxyClient.disconnect();
305
updateFrameTitle();
306
}
307
308
// Called on EDT
309
public void propertyChange(PropertyChangeEvent ev) {
310
String prop = ev.getPropertyName();
311
312
if (prop == CONNECTION_STATE_PROPERTY) {
313
ConnectionState oldState = (ConnectionState) ev.getOldValue();
314
ConnectionState newState = (ConnectionState) ev.getNewValue();
315
switch (newState) {
316
case CONNECTING:
317
onConnecting();
318
break;
319
320
case CONNECTED:
321
if (progressBar != null) {
322
progressBar.setIndeterminate(false);
323
progressBar.setValue(100);
324
}
325
closeOptionPane();
326
updateFrameTitle();
327
// create tabs if not done
328
createPluginTabs();
329
repaint();
330
// Notify tabs
331
fireConnectedChange(true);
332
// Enable/disable tabs on initial update
333
initialUpdate = true;
334
// Start/Restart update timer on connect/reconnect
335
startUpdateTimer();
336
break;
337
338
case DISCONNECTED:
339
if (progressBar != null) {
340
progressBar.setIndeterminate(false);
341
progressBar.setValue(0);
342
closeOptionPane();
343
}
344
vmPanelDied();
345
if (oldState == ConnectionState.CONNECTED) {
346
// Notify tabs
347
fireConnectedChange(false);
348
}
349
break;
350
}
351
}
352
}
353
354
// Called on EDT
355
private void onConnecting() {
356
time0 = System.currentTimeMillis();
357
358
SwingUtilities.getWindowAncestor(this);
359
360
String connectionName = getConnectionName();
361
progressBar = new JProgressBar();
362
progressBar.setIndeterminate(true);
363
JPanel progressPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
364
progressPanel.add(progressBar);
365
366
Object[] message = {
367
"<html><h3>" + Resources.format(Messages.CONNECTING_TO1, connectionName) + "</h3></html>",
368
progressPanel,
369
"<html><b>" + Resources.format(Messages.CONNECTING_TO2, connectionName) + "</b></html>"
370
};
371
372
optionPane =
373
SheetDialog.showOptionDialog(this,
374
message,
375
JOptionPane.DEFAULT_OPTION,
376
JOptionPane.INFORMATION_MESSAGE, null,
377
new String[]{Messages.CANCEL},
378
0);
379
380
381
}
382
383
// Called on EDT
384
private void closeOptionPane() {
385
if (optionPane != null) {
386
new Thread("VMPanel.sleeper") {
387
public void run() {
388
long elapsed = System.currentTimeMillis() - time0;
389
if (elapsed < 2000) {
390
try {
391
sleep(2000 - elapsed);
392
} catch (InterruptedException ex) {
393
// Ignore
394
}
395
}
396
SwingUtilities.invokeLater(new Runnable() {
397
398
public void run() {
399
optionPane.setVisible(false);
400
progressBar = null;
401
}
402
});
403
}
404
}.start();
405
}
406
}
407
408
void updateFrameTitle() {
409
VMInternalFrame vmIF = getFrame();
410
if (vmIF != null) {
411
String displayName = getDisplayName();
412
if (!proxyClient.isConnected()) {
413
displayName = Resources.format(Messages.CONNECTION_NAME__DISCONNECTED_, displayName);
414
}
415
vmIF.setTitle(displayName);
416
}
417
}
418
419
private VMInternalFrame getFrame() {
420
if (vmIF == null) {
421
vmIF = (VMInternalFrame) SwingUtilities.getAncestorOfClass(VMInternalFrame.class,
422
this);
423
}
424
return vmIF;
425
}
426
427
// TODO: this method is not needed when all JConsole tabs
428
// are migrated to use the new JConsolePlugin API.
429
//
430
// A thread safe clone of all JConsole tabs
431
synchronized List<Tab> getTabs() {
432
ArrayList<Tab> list = new ArrayList<Tab>();
433
int n = getTabCount();
434
for (int i = 0; i < n; i++) {
435
Component c = getComponentAt(i);
436
if (c instanceof Tab) {
437
list.add((Tab) c);
438
}
439
}
440
return list;
441
}
442
443
private void startUpdateTimer() {
444
if (timer != null) {
445
timer.cancel();
446
}
447
TimerTask timerTask = new TimerTask() {
448
449
public void run() {
450
update();
451
}
452
};
453
String timerName = "Timer-" + getConnectionName();
454
timer = new Timer(timerName, true);
455
timer.schedule(timerTask, 0, updateInterval);
456
}
457
458
// Call on EDT
459
private void vmPanelDied() {
460
disconnect();
461
462
if (userDisconnected) {
463
userDisconnected = false;
464
return;
465
}
466
467
JOptionPane optionPane;
468
String msgTitle, msgExplanation, buttonStr;
469
470
if (wasConnected) {
471
wasConnected = false;
472
msgTitle = Messages.CONNECTION_LOST1;
473
msgExplanation = Resources.format(Messages.CONNECTING_TO2, getConnectionName());
474
buttonStr = Messages.RECONNECT;
475
} else if (shouldUseSSL) {
476
msgTitle = Messages.CONNECTION_FAILED_SSL1;
477
msgExplanation = Resources.format(Messages.CONNECTION_FAILED_SSL2, getConnectionName());
478
buttonStr = Messages.INSECURE;
479
} else {
480
msgTitle = Messages.CONNECTION_FAILED1;
481
msgExplanation = Resources.format(Messages.CONNECTION_FAILED2, getConnectionName());
482
buttonStr = Messages.CONNECT;
483
}
484
485
optionPane =
486
SheetDialog.showOptionDialog(this,
487
"<html><h3>" + msgTitle + "</h3>" +
488
"<b>" + msgExplanation + "</b>",
489
JOptionPane.DEFAULT_OPTION,
490
JOptionPane.WARNING_MESSAGE, null,
491
new String[]{buttonStr, Messages.CANCEL},
492
0);
493
494
optionPane.addPropertyChangeListener(new PropertyChangeListener() {
495
496
public void propertyChange(PropertyChangeEvent event) {
497
if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
498
Object value = event.getNewValue();
499
500
if (value == Messages.RECONNECT || value == Messages.CONNECT) {
501
connect();
502
} else if (value == Messages.INSECURE) {
503
shouldUseSSL = false;
504
connect();
505
} else if (!everConnected) {
506
try {
507
getFrame().setClosed(true);
508
} catch (PropertyVetoException ex) {
509
// Should not happen, but can be ignored.
510
}
511
}
512
}
513
}
514
});
515
}
516
517
// Note: This method is called on a TimerTask thread. Any GUI manipulation
518
// must be performed with invokeLater() or invokeAndWait().
519
private Object lockObject = new Object();
520
521
private void update() {
522
synchronized (lockObject) {
523
if (!isConnected()) {
524
if (wasConnected) {
525
EventQueue.invokeLater(new Runnable() {
526
527
public void run() {
528
vmPanelDied();
529
}
530
});
531
}
532
wasConnected = false;
533
return;
534
} else {
535
wasConnected = true;
536
everConnected = true;
537
}
538
proxyClient.flush();
539
List<Tab> tabs = getTabs();
540
final int n = tabs.size();
541
for (int i = 0; i < n; i++) {
542
final int index = i;
543
try {
544
if (!proxyClient.isDead()) {
545
// Update tab
546
//
547
tabs.get(index).update();
548
// Enable tab on initial update
549
//
550
if (initialUpdate) {
551
EventQueue.invokeLater(new Runnable() {
552
553
public void run() {
554
setEnabledAt(index, true);
555
}
556
});
557
}
558
}
559
} catch (Exception e) {
560
// Disable tab on initial update
561
//
562
if (initialUpdate) {
563
EventQueue.invokeLater(new Runnable() {
564
public void run() {
565
setEnabledAt(index, false);
566
}
567
});
568
}
569
}
570
}
571
572
// plugin GUI update
573
for (ExceptionSafePlugin p : plugins.keySet()) {
574
SwingWorker<?, ?> sw = p.newSwingWorker();
575
SwingWorker<?, ?> prevSW = plugins.get(p);
576
// schedule SwingWorker to run only if the previous
577
// SwingWorker has finished its task and it hasn't started.
578
if (prevSW == null || prevSW.isDone()) {
579
if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) {
580
plugins.put(p, sw);
581
if (sw != null) {
582
p.executeSwingWorker(sw);
583
}
584
}
585
}
586
}
587
588
// Set the first enabled tab in the tab's list
589
// as the selected tab on initial update
590
//
591
if (initialUpdate) {
592
EventQueue.invokeLater(new Runnable() {
593
public void run() {
594
// Select first enabled tab if current tab isn't.
595
int index = getSelectedIndex();
596
if (index < 0 || !isEnabledAt(index)) {
597
for (int i = 0; i < n; i++) {
598
if (isEnabledAt(i)) {
599
setSelectedIndex(i);
600
break;
601
}
602
}
603
}
604
}
605
});
606
initialUpdate = false;
607
}
608
}
609
}
610
611
public String getHostName() {
612
return hostName;
613
}
614
615
public int getPort() {
616
return port;
617
}
618
619
public String getUserName() {
620
return userName;
621
}
622
623
public String getUrl() {
624
return url;
625
}
626
627
public String getPassword() {
628
return password;
629
}
630
631
public String getConnectionName() {
632
return proxyClient.connectionName();
633
}
634
635
public String getDisplayName() {
636
return proxyClient.getDisplayName();
637
}
638
639
static class TabInfo {
640
641
Class<? extends Tab> tabClass;
642
String name;
643
boolean tabVisible;
644
645
TabInfo(Class<? extends Tab> tabClass, String name, boolean tabVisible) {
646
this.tabClass = tabClass;
647
this.name = name;
648
this.tabVisible = tabVisible;
649
}
650
}
651
652
private void createPluginTabs() {
653
// add plugin tabs if not done
654
if (!pluginTabsAdded) {
655
for (JConsolePlugin p : plugins.keySet()) {
656
Map<String, JPanel> tabs = p.getTabs();
657
for (Map.Entry<String, JPanel> e : tabs.entrySet()) {
658
addTab(e.getKey(), e.getValue());
659
}
660
}
661
pluginTabsAdded = true;
662
}
663
}
664
665
private void fireConnectedChange(boolean connected) {
666
for (Tab tab : getTabs()) {
667
tab.firePropertyChange(JConsoleContext.CONNECTION_STATE_PROPERTY, !connected, connected);
668
}
669
}
670
}
671
672