History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/jconsole/ConnectDialog.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/jconsole/ConnectDialog.java+779−0
@@ -0,0 +1,779 @@
1+/*
2+ * Copyright (c) 2004, 2006, 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.util.List;
29+import java.awt.*;
30+import java.awt.event.*;
31+import java.util.*;
32+import java.net.MalformedURLException;
33+import java.io.IOException;
34+
35+import javax.accessibility.*;
36+import javax.swing.*;
37+import javax.swing.Timer;
38+import javax.swing.border.*;
39+import javax.swing.event.*;
40+import javax.swing.plaf.basic.BasicRadioButtonUI;
41+import javax.swing.table.*;
42+
43+import javax.management.remote.JMXServiceURL;
44+import javax.management.remote.JMXConnector;
45+
46+import static java.awt.BorderLayout.*;
47+import static javax.swing.ListSelectionModel.*;
48+import static sun.tools.jconsole.Resources.*;
49+import static sun.tools.jconsole.Utilities.*;
50+
51+@SuppressWarnings("serial")
52+public class ConnectDialog extends InternalDialog
53+ implements DocumentListener, FocusListener,
54+ ItemListener, ListSelectionListener, KeyListener {
55+
56+ private static final int COL_NAME = 0;
57+ private static final int COL_PID = 1;
58+
59+
60+ JConsole jConsole;
61+ JTextField userNameTF, passwordTF;
62+ JRadioButton localRadioButton, remoteRadioButton;
63+ JLabel localMessageLabel, remoteMessageLabel;
64+ JTextField remoteTF;
65+ JButton connectButton, cancelButton;
66+ JPanel radioButtonPanel;
67+
68+ private Icon mastheadIcon =
69+ new MastheadIcon(getText("ConnectDialog.masthead.title"));
70+ private Color hintTextColor, disabledTableCellColor;
71+
72+ // The table of managed VM (local process)
73+ JTable vmTable;
74+ ManagedVmTableModel vmModel = null;
75+
76+ JScrollPane localTableScrollPane = null;
77+
78+ private Action connectAction, cancelAction;
79+
80+
81+ public ConnectDialog(JConsole jConsole) {
82+ super(jConsole, Resources.getText("ConnectDialog.title"), true);
83+
84+ this.jConsole = jConsole;
85+ setAccessibleDescription(this,
86+ getText("ConnectDialog.accessibleDescription"));
87+ setDefaultCloseOperation(HIDE_ON_CLOSE);
88+ setResizable(false);
89+ Container cp = (JComponent)getContentPane();
90+
91+ radioButtonPanel = new JPanel(new BorderLayout(0, 12));
92+ radioButtonPanel.setBorder(new EmptyBorder(6, 12, 12, 12));
93+ ButtonGroup radioButtonGroup = new ButtonGroup();
94+ JPanel bottomPanel = new JPanel(new BorderLayout());
95+
96+ statusBar = new JLabel(" ", JLabel.CENTER);
97+ setAccessibleName(statusBar,
98+ getText("ConnectDialog.statusBar.accessibleName"));
99+
100+ Font normalLabelFont = statusBar.getFont();
101+ Font boldLabelFont = normalLabelFont.deriveFont(Font.BOLD);
102+ Font smallLabelFont = normalLabelFont.deriveFont(normalLabelFont.getSize2D() - 1);
103+
104+ JLabel mastheadLabel = new JLabel(mastheadIcon);
105+ setAccessibleName(mastheadLabel,
106+ getText("ConnectDialog.masthead.accessibleName"));
107+
108+ cp.add(mastheadLabel, NORTH);
109+ cp.add(radioButtonPanel, CENTER);
110+ cp.add(bottomPanel, SOUTH);
111+
112+ createActions();
113+
114+ remoteTF = new JTextField();
115+ remoteTF.addActionListener(connectAction);
116+ remoteTF.getDocument().addDocumentListener(this);
117+ remoteTF.addFocusListener(this);
118+ remoteTF.setPreferredSize(remoteTF.getPreferredSize());
119+ setAccessibleName(remoteTF,
120+ getText("Remote Process.textField.accessibleName"));
121+
122+ //
123+ // If the VM supports the local attach mechanism (is: Sun
124+ // implementation) then the Local Process panel is created.
125+ //
126+ if (JConsole.isLocalAttachAvailable()) {
127+ vmModel = new ManagedVmTableModel();
128+ vmTable = new LocalTabJTable(vmModel);
129+ vmTable.setSelectionMode(SINGLE_SELECTION);
130+ vmTable.setPreferredScrollableViewportSize(new Dimension(400, 250));
131+ vmTable.setColumnSelectionAllowed(false);
132+ vmTable.addFocusListener(this);
133+ vmTable.getSelectionModel().addListSelectionListener(this);
134+
135+ TableColumnModel columnModel = vmTable.getColumnModel();
136+
137+ TableColumn pidColumn = columnModel.getColumn(COL_PID);
138+ pidColumn.setMaxWidth(getLabelWidth("9999999"));
139+ pidColumn.setResizable(false);
140+
141+ TableColumn cmdLineColumn = columnModel.getColumn(COL_NAME);
142+ cmdLineColumn.setResizable(false);
143+
144+ localRadioButton = new JRadioButton(getText("Local Process:"));
145+ localRadioButton.setMnemonic(getMnemonicInt("Local Process:"));
146+ localRadioButton.setFont(boldLabelFont);
147+ localRadioButton.addItemListener(this);
148+ radioButtonGroup.add(localRadioButton);
149+
150+ JPanel localPanel = new JPanel(new BorderLayout());
151+
152+ JPanel localTablePanel = new JPanel(new BorderLayout());
153+
154+ radioButtonPanel.add(localPanel, NORTH);
155+
156+ localPanel.add(localRadioButton, NORTH);
157+ localPanel.add(new Padder(localRadioButton), LINE_START);
158+ localPanel.add(localTablePanel, CENTER);
159+
160+ localTableScrollPane = new JScrollPane(vmTable);
161+
162+ localTablePanel.add(localTableScrollPane, NORTH);
163+
164+ localMessageLabel = new JLabel(" ");
165+ localMessageLabel.setFont(smallLabelFont);
166+ localMessageLabel.setForeground(hintTextColor);
167+ localTablePanel.add(localMessageLabel, SOUTH);
168+ }
169+
170+ remoteRadioButton = new JRadioButton(getText("Remote Process:"));
171+ remoteRadioButton.setMnemonic(getMnemonicInt("Remote Process:"));
172+ remoteRadioButton.setFont(boldLabelFont);
173+ radioButtonGroup.add(remoteRadioButton);
174+
175+ JPanel remotePanel = new JPanel(new BorderLayout());
176+ if (localRadioButton != null) {
177+ remotePanel.add(remoteRadioButton, NORTH);
178+ remotePanel.add(new Padder(remoteRadioButton), LINE_START);
179+
180+ Action nextRadioButtonAction =
181+ new AbstractAction("nextRadioButton") {
182+ public void actionPerformed(ActionEvent ev) {
183+ JRadioButton rb =
184+ (ev.getSource() == localRadioButton) ? remoteRadioButton
185+ : localRadioButton;
186+ rb.doClick();
187+ rb.requestFocus();
188+ }
189+ };
190+
191+ localRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
192+ remoteRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
193+
194+ localRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),
195+ "nextRadioButton");
196+ remoteRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
197+ "nextRadioButton");
198+ } else {
199+ JLabel remoteLabel = new JLabel(remoteRadioButton.getText());
200+ remoteLabel.setFont(boldLabelFont);
201+ remotePanel.add(remoteLabel, NORTH);
202+ }
203+ radioButtonPanel.add(remotePanel, SOUTH);
204+
205+ JPanel remoteTFPanel = new JPanel(new BorderLayout());
206+ remotePanel.add(remoteTFPanel, CENTER);
207+
208+ remoteTFPanel.add(remoteTF, NORTH);
209+
210+ remoteMessageLabel = new JLabel("<html>" + getText("remoteTF.usage"));
211+ remoteMessageLabel.setFont(smallLabelFont);
212+ remoteMessageLabel.setForeground(hintTextColor);
213+ remoteTFPanel.add(remoteMessageLabel, CENTER);
214+
215+ JPanel userPwdPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
216+ userPwdPanel.setBorder(new EmptyBorder(12, 0, 0, 0)); // top padding
217+
218+ int tfWidth = JConsole.IS_WIN ? 12 : 8;
219+
220+ userNameTF = new JTextField(tfWidth);
221+ userNameTF.addActionListener(connectAction);
222+ userNameTF.getDocument().addDocumentListener(this);
223+ userNameTF.addFocusListener(this);
224+ setAccessibleName(userNameTF,
225+ getText("Username.accessibleName"));
226+ String labelKey = "Username: ";
227+ LabeledComponent lc;
228+ lc = new LabeledComponent(getText(labelKey),
229+ getMnemonicInt(labelKey),
230+ userNameTF);
231+ lc.label.setFont(boldLabelFont);
232+ userPwdPanel.add(lc);
233+
234+ passwordTF = new JPasswordField(tfWidth);
235+ // Heights differ, so fix here
236+ passwordTF.setPreferredSize(userNameTF.getPreferredSize());
237+ passwordTF.addActionListener(connectAction);
238+ passwordTF.getDocument().addDocumentListener(this);
239+ passwordTF.addFocusListener(this);
240+ setAccessibleName(passwordTF,
241+ getText("Password.accessibleName"));
242+ labelKey = "Password: ";
243+ lc = new LabeledComponent(getText(labelKey),
244+ getMnemonicInt(labelKey),
245+ passwordTF);
246+ lc.setBorder(new EmptyBorder(0, 12, 0, 0)); // Left padding
247+ lc.label.setFont(boldLabelFont);
248+ userPwdPanel.add(lc);
249+
250+ remoteTFPanel.add(userPwdPanel, SOUTH);
251+
252+ String connectButtonToolTipText =
253+ getText("ConnectDialog.connectButton.toolTip");
254+ connectButton = new JButton(connectAction);
255+ connectButton.setToolTipText(connectButtonToolTipText);
256+
257+ cancelButton = new JButton(cancelAction);
258+
259+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
260+ buttonPanel.setBorder(new EmptyBorder(12, 12, 2, 12));
261+ if (JConsole.IS_GTK) {
262+ buttonPanel.add(cancelButton);
263+ buttonPanel.add(connectButton);
264+ } else {
265+ buttonPanel.add(connectButton);
266+ buttonPanel.add(cancelButton);
267+ }
268+ bottomPanel.add(buttonPanel, NORTH);
269+
270+ bottomPanel.add(statusBar, SOUTH);
271+
272+ updateButtonStates();
273+ Utilities.updateTransparency(this);
274+ }
275+
276+ public void revalidate() {
277+ // Adjust some colors
278+ hintTextColor =
279+ ensureContrast(UIManager.getColor("Label.disabledForeground"),
280+ UIManager.getColor("Panel.background"));
281+ disabledTableCellColor =
282+ ensureContrast(new Color(0x808080),
283+ UIManager.getColor("Table.background"));
284+
285+ if (remoteMessageLabel != null) {
286+ remoteMessageLabel.setForeground(hintTextColor);
287+ // Update html color setting
288+ String colorStr =
289+ String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
290+ remoteMessageLabel.setText("<html><font color=#" + colorStr + ">" +
291+ getText("remoteTF.usage"));
292+ }
293+ if (localMessageLabel != null) {
294+ localMessageLabel.setForeground(hintTextColor);
295+ // Update html color setting
296+ valueChanged(null);
297+ }
298+
299+ super.revalidate();
300+ }
301+
302+ private void createActions() {
303+ connectAction = new AbstractAction(getText("Connect")) {
304+ /* init */ {
305+ putValue(Action.MNEMONIC_KEY, getMnemonicInt("Connect"));
306+ }
307+
308+ public void actionPerformed(ActionEvent ev) {
309+ if (!isEnabled() || !isVisible()) {
310+ return;
311+ }
312+ setVisible(false);
313+ statusBar.setText("");
314+
315+ if (remoteRadioButton.isSelected()) {
316+ String txt = remoteTF.getText().trim();
317+ String userName = userNameTF.getText().trim();
318+ userName = userName.equals("") ? null : userName;
319+ String password = passwordTF.getText();
320+ password = password.equals("") ? null : password;
321+ try {
322+ if (txt.startsWith(JConsole.ROOT_URL)) {
323+ String url = txt;
324+ String msg = null;
325+ jConsole.addUrl(url, userName, password, false);
326+ remoteTF.setText(JConsole.ROOT_URL);
327+ return;
328+ } else {
329+ String host = remoteTF.getText().trim();
330+ String port = "0";
331+ int index = host.lastIndexOf(":");
332+ if (index >= 0) {
333+ port = host.substring(index + 1);
334+ host = host.substring(0, index);
335+ }
336+ if (host.length() > 0 && port.length() > 0) {
337+ int p = Integer.parseInt(port.trim());
338+ jConsole.addHost(host, p, userName, password);
339+ remoteTF.setText("");
340+ userNameTF.setText("");
341+ passwordTF.setText("");
342+ return;
343+ }
344+ }
345+ } catch (Exception ex) {
346+ statusBar.setText(ex.toString());
347+ }
348+ setVisible(true);
349+ } else if (localRadioButton != null && localRadioButton.isSelected()) {
350+ // Try to connect to selected VM. If a connection
351+ // cannot be established for some reason (the process has
352+ // terminated for example) then keep the dialog open showing
353+ // the connect error.
354+ //
355+ int row = vmTable.getSelectedRow();
356+ if (row >= 0) {
357+ jConsole.addVmid(vmModel.vmAt(row));
358+ }
359+ refresh();
360+ }
361+ }
362+ };
363+
364+ cancelAction = new AbstractAction(getText("Cancel")) {
365+ public void actionPerformed(ActionEvent ev) {
366+ setVisible(false);
367+ statusBar.setText("");
368+ }
369+ };
370+ }
371+
372+
373+ // a label used solely for calculating the width
374+ private static JLabel tmpLabel = new JLabel();
375+ public static int getLabelWidth(String text) {
376+ tmpLabel.setText(text);
377+ return (int) tmpLabel.getPreferredSize().getWidth() + 1;
378+ }
379+
380+ private class LocalTabJTable extends JTable {
381+ ManagedVmTableModel vmModel;
382+ Border rendererBorder = new EmptyBorder(0, 6, 0, 6);
383+
384+ public LocalTabJTable(ManagedVmTableModel model) {
385+ super(model);
386+ this.vmModel = model;
387+
388+ // Remove vertical lines, expect for GTK L&F.
389+ // (because GTK doesn't show header dividers)
390+ if (!JConsole.IS_GTK) {
391+ setShowVerticalLines(false);
392+ setIntercellSpacing(new Dimension(0, 1));
393+ }
394+
395+ // Double-click handler
396+ addMouseListener(new MouseAdapter() {
397+ public void mouseClicked(MouseEvent evt) {
398+ if (evt.getClickCount() == 2) {
399+ connectButton.doClick();
400+ }
401+ }
402+ });
403+
404+ // Enter should call default action
405+ getActionMap().put("connect", connectAction);
406+ InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
407+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "connect");
408+ }
409+
410+ public String getToolTipText(MouseEvent e) {
411+ String tip = null;
412+ java.awt.Point p = e.getPoint();
413+ int rowIndex = rowAtPoint(p);
414+ int colIndex = columnAtPoint(p);
415+ int realColumnIndex = convertColumnIndexToModel(colIndex);
416+
417+ if (realColumnIndex == COL_NAME) {
418+ LocalVirtualMachine vmd = vmModel.vmAt(rowIndex);
419+ tip = vmd.toString();
420+ }
421+ return tip;
422+ }
423+
424+ public TableCellRenderer getCellRenderer(int row, int column) {
425+ return new DefaultTableCellRenderer() {
426+ public Component getTableCellRendererComponent(JTable table,
427+ Object value,
428+ boolean isSelected,
429+ boolean hasFocus,
430+ int row,
431+ int column) {
432+ Component comp =
433+ super.getTableCellRendererComponent(table, value, isSelected,
434+ hasFocus, row, column);
435+
436+ if (!isSelected) {
437+ LocalVirtualMachine lvm = vmModel.vmAt(row);
438+ if (!lvm.isManageable() && !lvm.isAttachable()) {
439+ comp.setForeground(disabledTableCellColor);
440+ }
441+ }
442+
443+ if (comp instanceof JLabel) {
444+ JLabel label = (JLabel)comp;
445+ label.setBorder(rendererBorder);
446+
447+ if (value instanceof Integer) {
448+ label.setHorizontalAlignment(JLabel.RIGHT);
449+ }
450+ }
451+
452+ return comp;
453+ }
454+ };
455+ }
456+ }
457+
458+ public void setConnectionParameters(String url,
459+ String host,
460+ int port,
461+ String userName,
462+ String password,
463+ String msg) {
464+ if ((url != null && url.length() > 0) ||
465+ (host != null && host.length() > 0 && port > 0)) {
466+
467+ remoteRadioButton.setSelected(true);
468+ if (url != null && url.length() > 0) {
469+ remoteTF.setText(url);
470+ } else {
471+ remoteTF.setText(host+":"+port);
472+ }
473+ userNameTF.setText((userName != null) ? userName : "");
474+ passwordTF.setText((password != null) ? password : "");
475+
476+ statusBar.setText((msg != null) ? msg : "");
477+ if (getPreferredSize().width > getWidth()) {
478+ pack();
479+ }
480+ remoteTF.requestFocus();
481+ remoteTF.selectAll();
482+ }
483+ }
484+
485+
486+ public void itemStateChanged(ItemEvent ev) {
487+ if (!localRadioButton.isSelected()) {
488+ vmTable.getSelectionModel().clearSelection();
489+ }
490+ updateButtonStates();
491+ }
492+
493+ private void updateButtonStates() {
494+ boolean connectEnabled = false;
495+
496+ if (remoteRadioButton.isSelected()) {
497+ connectEnabled = JConsole.isValidRemoteString(remoteTF.getText());
498+ } else if (localRadioButton != null && localRadioButton.isSelected()) {
499+ int row = vmTable.getSelectedRow();
500+ if (row >= 0) {
501+ LocalVirtualMachine lvm = vmModel.vmAt(row);
502+ connectEnabled = (lvm.isManageable() || lvm.isAttachable());
503+ }
504+ }
505+
506+ connectAction.setEnabled(connectEnabled);
507+ }
508+
509+ public void insertUpdate(DocumentEvent e) {
510+ updateButtonStates();
511+ }
512+
513+ public void removeUpdate(DocumentEvent e) {
514+ updateButtonStates();
515+ }
516+
517+ public void changedUpdate(DocumentEvent e) {
518+ updateButtonStates();
519+ }
520+
521+ public void focusGained(FocusEvent e) {
522+ Object source = e.getSource();
523+ Component opposite = e.getOppositeComponent();
524+
525+ if (!e.isTemporary() &&
526+ source instanceof JTextField &&
527+ opposite instanceof JComponent &&
528+ SwingUtilities.getRootPane(opposite) == getRootPane()) {
529+
530+ ((JTextField)source).selectAll();
531+ }
532+
533+ if (source == remoteTF) {
534+ remoteRadioButton.setSelected(true);
535+ } else if (source == vmTable) {
536+ localRadioButton.setSelected(true);
537+ if (vmModel.getRowCount() == 1) {
538+ // if there's only one process then select the row
539+ vmTable.setRowSelectionInterval(0, 0);
540+ }
541+ }
542+ updateButtonStates();
543+ }
544+
545+ public void focusLost(FocusEvent e) {
546+ }
547+
548+ public void keyTyped(KeyEvent e) {
549+ char c = e.getKeyChar();
550+ if (c == KeyEvent.VK_ESCAPE) {
551+ setVisible(false);
552+ } else if (!(Character.isDigit(c) ||
553+ c == KeyEvent.VK_BACK_SPACE ||
554+ c == KeyEvent.VK_DELETE)) {
555+ getToolkit().beep();
556+ e.consume();
557+ }
558+ }
559+
560+ public void setVisible(boolean b) {
561+ boolean wasVisible = isVisible();
562+ super.setVisible(b);
563+ if (b && !wasVisible) {
564+ SwingUtilities.invokeLater(new Runnable() {
565+ public void run() {
566+ if (remoteRadioButton.isSelected()) {
567+ remoteTF.requestFocus();
568+ remoteTF.selectAll();
569+ }
570+ }
571+ });
572+ }
573+ }
574+
575+ public void keyPressed(KeyEvent e) {
576+ }
577+
578+ public void keyReleased(KeyEvent e) {
579+ }
580+
581+
582+ // ListSelectionListener interface
583+ public void valueChanged(ListSelectionEvent e) {
584+ updateButtonStates();
585+ String labelText = " "; // Non-empty to reserve vertical space
586+ int row = vmTable.getSelectedRow();
587+ if (row >= 0) {
588+ LocalVirtualMachine lvm = vmModel.vmAt(row);
589+ if (!lvm.isManageable()) {
590+ if (lvm.isAttachable()) {
591+ labelText = getText("Management Will Be Enabled");
592+ } else {
593+ labelText = getText("Management Not Enabled");
594+ }
595+ }
596+ }
597+ String colorStr =
598+ String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
599+ localMessageLabel.setText("<html><font color=#" + colorStr + ">" + labelText);
600+ }
601+ // ----
602+
603+
604+ // Refresh the list of managed VMs
605+ public void refresh() {
606+ if (vmModel != null) {
607+ // Remember selection
608+ LocalVirtualMachine selected = null;
609+ int row = vmTable.getSelectedRow();
610+ if (row >= 0) {
611+ selected = vmModel.vmAt(row);
612+ }
613+
614+ vmModel.refresh();
615+
616+ int selectRow = -1;
617+ int n = vmModel.getRowCount();
618+ if (selected != null) {
619+ for (int i = 0; i < n; i++) {
620+ LocalVirtualMachine lvm = vmModel.vmAt(i);
621+ if (selected.vmid() == lvm.vmid() &&
622+ selected.toString().equals(lvm.toString())) {
623+
624+ selectRow = i;
625+ break;
626+ }
627+ }
628+ }
629+ if (selectRow > -1) {
630+ vmTable.setRowSelectionInterval(selectRow, selectRow);
631+ } else {
632+ vmTable.getSelectionModel().clearSelection();
633+ }
634+
635+ Dimension dim = vmTable.getPreferredSize();
636+
637+ // Tricky. Reduce height by one to avoid double line at bottom,
638+ // but that causes a scroll bar to appear, so remove it.
639+ dim.height = Math.min(dim.height-1, 100);
640+ localTableScrollPane.setVerticalScrollBarPolicy((dim.height < 100)
641+ ? JScrollPane.VERTICAL_SCROLLBAR_NEVER
642+ : JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
643+ localTableScrollPane.getViewport().setMinimumSize(dim);
644+ localTableScrollPane.getViewport().setPreferredSize(dim);
645+ }
646+ pack();
647+ setLocationRelativeTo(jConsole);
648+ }
649+
650+ // Represents the list of managed VMs as a tabular data model.
651+ private static class ManagedVmTableModel extends AbstractTableModel {
652+ private static String[] columnNames = {
653+ Resources.getText("Column.Name"),
654+ Resources.getText("Column.PID"),
655+ };
656+
657+ private List<LocalVirtualMachine> vmList;
658+
659+ public int getColumnCount() {
660+ return columnNames.length;
661+ }
662+
663+ public String getColumnName(int col) {
664+ return columnNames[col];
665+ }
666+
667+ public synchronized int getRowCount() {
668+ return vmList.size();
669+ }
670+
671+ public synchronized Object getValueAt(int row, int col) {
672+ assert col >= 0 && col <= columnNames.length;
673+ LocalVirtualMachine vm = vmList.get(row);
674+ switch (col) {
675+ case COL_NAME: return vm.displayName();
676+ case COL_PID: return vm.vmid();
677+ default: return null;
678+ }
679+ }
680+
681+ public Class getColumnClass(int column) {
682+ switch (column) {
683+ case COL_NAME: return String.class;
684+ case COL_PID: return Integer.class;
685+ default: return super.getColumnClass(column);
686+ }
687+ }
688+
689+ public ManagedVmTableModel() {
690+ refresh();
691+ }
692+
693+
694+ public synchronized LocalVirtualMachine vmAt(int pos) {
695+ return vmList.get(pos);
696+ }
697+
698+ public synchronized void refresh() {
699+ Map<Integer, LocalVirtualMachine> map =
700+ LocalVirtualMachine.getAllVirtualMachines();
701+ vmList = new ArrayList<LocalVirtualMachine>();
702+ vmList.addAll(map.values());
703+
704+ // data has changed
705+ fireTableDataChanged();
706+ }
707+ }
708+
709+
710+ // Convenience method
711+ private static String getText(String key) {
712+ return Resources.getText(key);
713+ }
714+
715+
716+ // A blank component that takes up as much space as the
717+ // button part of a JRadioButton.
718+ private static class Padder extends JPanel {
719+ JRadioButton radioButton;
720+
721+ Padder(JRadioButton radioButton) {
722+ this.radioButton = radioButton;
723+
724+ setAccessibleName(this, getText("Blank"));
725+ }
726+
727+ public Dimension getPreferredSize() {
728+ Rectangle r = getTextRectangle(radioButton);
729+ int w = (r != null && r.x > 8) ? r.x : 22;
730+
731+ return new Dimension(w, 0);
732+ }
733+
734+ private static Rectangle getTextRectangle(AbstractButton button) {
735+ String text = button.getText();
736+ Icon icon = (button.isEnabled()) ? button.getIcon() : button.getDisabledIcon();
737+
738+ if (icon == null && button.getUI() instanceof BasicRadioButtonUI) {
739+ icon = ((BasicRadioButtonUI)button.getUI()).getDefaultIcon();
740+ }
741+
742+ if ((icon == null) && (text == null)) {
743+ return null;
744+ }
745+
746+ Rectangle paintIconR = new Rectangle();
747+ Rectangle paintTextR = new Rectangle();
748+ Rectangle paintViewR = new Rectangle();
749+ Insets paintViewInsets = new Insets(0, 0, 0, 0);
750+
751+ paintViewInsets = button.getInsets(paintViewInsets);
752+ paintViewR.x = paintViewInsets.left;
753+ paintViewR.y = paintViewInsets.top;
754+ paintViewR.width = button.getWidth() - (paintViewInsets.left + paintViewInsets.right);
755+ paintViewR.height = button.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
756+
757+ Graphics g = button.getGraphics();
758+ if (g == null) {
759+ return null;
760+ }
761+ String clippedText =
762+ SwingUtilities.layoutCompoundLabel(button,
763+ g.getFontMetrics(),
764+ text,
765+ icon,
766+ button.getVerticalAlignment(),
767+ button.getHorizontalAlignment(),
768+ button.getVerticalTextPosition(),
769+ button.getHorizontalTextPosition(),
770+ paintViewR,
771+ paintIconR,
772+ paintTextR,
773+ button.getIconTextGap());
774+
775+ return paintTextR;
776+ }
777+ }
778+
779+}