jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2004-2006 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any 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 }