src/share/classes/sun/tools/jconsole/ConnectDialog.java

Print this page




  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) {


 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 


 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 }


  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 

  33 import javax.swing.*;

  34 import javax.swing.border.*;
  35 import javax.swing.event.*;
  36 import javax.swing.plaf.basic.BasicRadioButtonUI;
  37 import javax.swing.table.*;
  38 
  39 import sun.tools.jconsole.resources.Messages;
  40 
  41 
  42 import static java.awt.BorderLayout.*;
  43 import static javax.swing.ListSelectionModel.*;

  44 import static sun.tools.jconsole.Utilities.*;
  45 
  46 @SuppressWarnings("serial")
  47 public class ConnectDialog extends InternalDialog
  48                 implements DocumentListener, FocusListener,
  49                            ItemListener, ListSelectionListener, KeyListener {
  50 
  51     private static final int COL_NAME = 0;
  52     private static final int COL_PID  = 1;
  53 
  54 
  55     JConsole jConsole;
  56     JTextField userNameTF, passwordTF;
  57     JRadioButton localRadioButton, remoteRadioButton;
  58     JLabel localMessageLabel, remoteMessageLabel;
  59     JTextField remoteTF;
  60     JButton connectButton, cancelButton;
  61     JPanel radioButtonPanel;
  62 
  63     private Icon mastheadIcon =
  64         new MastheadIcon(Messages.CONNECT_DIALOG_MASTHEAD_TITLE);
  65     private Color hintTextColor, disabledTableCellColor;
  66 
  67     // The table of managed VM (local process)
  68     JTable vmTable;
  69     ManagedVmTableModel vmModel = null;
  70 
  71     JScrollPane localTableScrollPane = null;
  72 
  73     private Action connectAction, cancelAction;
  74 
  75 
  76     public ConnectDialog(JConsole jConsole) {
  77         super(jConsole, Messages.CONNECT_DIALOG_TITLE, true);
  78 
  79         this.jConsole = jConsole;
  80         setAccessibleDescription(this,
  81                 Messages.CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION);
  82         setDefaultCloseOperation(HIDE_ON_CLOSE);
  83         setResizable(false);
  84         Container cp = (JComponent)getContentPane();
  85 
  86         radioButtonPanel = new JPanel(new BorderLayout(0, 12));
  87         radioButtonPanel.setBorder(new EmptyBorder(6, 12, 12, 12));
  88         ButtonGroup radioButtonGroup = new ButtonGroup();
  89         JPanel bottomPanel = new JPanel(new BorderLayout());
  90 
  91         statusBar = new JLabel(" ", JLabel.CENTER);
  92         setAccessibleName(statusBar,
  93                 Messages.CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME);
  94 
  95         Font normalLabelFont = statusBar.getFont();
  96         Font boldLabelFont = normalLabelFont.deriveFont(Font.BOLD);
  97         Font smallLabelFont = normalLabelFont.deriveFont(normalLabelFont.getSize2D() - 1);
  98 
  99         JLabel mastheadLabel = new JLabel(mastheadIcon);
 100         setAccessibleName(mastheadLabel,
 101                 Messages.CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
 102 
 103         cp.add(mastheadLabel, NORTH);
 104         cp.add(radioButtonPanel, CENTER);
 105         cp.add(bottomPanel, SOUTH);
 106 
 107         createActions();
 108 
 109         remoteTF = new JTextField();
 110         remoteTF.addActionListener(connectAction);
 111         remoteTF.getDocument().addDocumentListener(this);
 112         remoteTF.addFocusListener(this);
 113         remoteTF.setPreferredSize(remoteTF.getPreferredSize());
 114         setAccessibleName(remoteTF,
 115                 Messages.REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME);
 116 
 117         //
 118         // If the VM supports the local attach mechanism (is: Sun
 119         // implementation) then the Local Process panel is created.
 120         //
 121         if (JConsole.isLocalAttachAvailable()) {
 122             vmModel = new ManagedVmTableModel();
 123             vmTable = new LocalTabJTable(vmModel);
 124             vmTable.setSelectionMode(SINGLE_SELECTION);
 125             vmTable.setPreferredScrollableViewportSize(new Dimension(400, 250));
 126             vmTable.setColumnSelectionAllowed(false);
 127             vmTable.addFocusListener(this);
 128             vmTable.getSelectionModel().addListSelectionListener(this);
 129 
 130             TableColumnModel columnModel = vmTable.getColumnModel();
 131 
 132             TableColumn pidColumn = columnModel.getColumn(COL_PID);
 133             pidColumn.setMaxWidth(getLabelWidth("9999999"));
 134             pidColumn.setResizable(false);
 135 
 136             TableColumn cmdLineColumn = columnModel.getColumn(COL_NAME);
 137             cmdLineColumn.setResizable(false);
 138 
 139             localRadioButton = new JRadioButton(Messages.LOCAL_PROCESS_COLON);
 140             localRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.LOCAL_PROCESS_COLON));
 141             localRadioButton.setFont(boldLabelFont);
 142             localRadioButton.addItemListener(this);
 143             radioButtonGroup.add(localRadioButton);
 144 
 145             JPanel localPanel = new JPanel(new BorderLayout());
 146 
 147             JPanel localTablePanel = new JPanel(new BorderLayout());
 148 
 149             radioButtonPanel.add(localPanel, NORTH);
 150 
 151             localPanel.add(localRadioButton, NORTH);
 152             localPanel.add(new Padder(localRadioButton), LINE_START);
 153             localPanel.add(localTablePanel, CENTER);
 154 
 155             localTableScrollPane = new JScrollPane(vmTable);
 156 
 157             localTablePanel.add(localTableScrollPane, NORTH);
 158 
 159             localMessageLabel = new JLabel(" ");
 160             localMessageLabel.setFont(smallLabelFont);
 161             localMessageLabel.setForeground(hintTextColor);
 162             localTablePanel.add(localMessageLabel, SOUTH);
 163         }
 164 
 165         remoteRadioButton = new JRadioButton(Messages.REMOTE_PROCESS_COLON);
 166         remoteRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.REMOTE_PROCESS_COLON));
 167         remoteRadioButton.setFont(boldLabelFont);
 168         radioButtonGroup.add(remoteRadioButton);
 169 
 170         JPanel remotePanel = new JPanel(new BorderLayout());
 171         if (localRadioButton != null) {
 172             remotePanel.add(remoteRadioButton, NORTH);
 173             remotePanel.add(new Padder(remoteRadioButton), LINE_START);
 174 
 175             Action nextRadioButtonAction =
 176                 new AbstractAction("nextRadioButton") {
 177                     public void actionPerformed(ActionEvent ev) {
 178                         JRadioButton rb =
 179                             (ev.getSource() == localRadioButton) ? remoteRadioButton
 180                                                                  : localRadioButton;
 181                         rb.doClick();
 182                         rb.requestFocus();
 183                     }
 184                 };
 185 
 186             localRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
 187             remoteRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
 188 
 189             localRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),
 190                                                "nextRadioButton");
 191             remoteRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
 192                                                 "nextRadioButton");
 193         } else {
 194             JLabel remoteLabel = new JLabel(remoteRadioButton.getText());
 195             remoteLabel.setFont(boldLabelFont);
 196             remotePanel.add(remoteLabel, NORTH);
 197         }
 198         radioButtonPanel.add(remotePanel, SOUTH);
 199 
 200         JPanel remoteTFPanel = new JPanel(new BorderLayout());
 201         remotePanel.add(remoteTFPanel, CENTER);
 202 
 203         remoteTFPanel.add(remoteTF, NORTH);
 204 
 205         remoteMessageLabel = new JLabel("<html>" + Messages.REMOTE_TF_USAGE);
 206         remoteMessageLabel.setFont(smallLabelFont);
 207         remoteMessageLabel.setForeground(hintTextColor);
 208         remoteTFPanel.add(remoteMessageLabel, CENTER);
 209 
 210         JPanel userPwdPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
 211         userPwdPanel.setBorder(new EmptyBorder(12, 0, 0, 0)); // top padding
 212 
 213         int tfWidth = JConsole.IS_WIN ? 12 : 8;
 214 
 215         userNameTF = new JTextField(tfWidth);
 216         userNameTF.addActionListener(connectAction);
 217         userNameTF.getDocument().addDocumentListener(this);
 218         userNameTF.addFocusListener(this);
 219         setAccessibleName(userNameTF,
 220                 Messages.USERNAME_ACCESSIBLE_NAME);
 221         String labelKey = Messages.USERNAME_COLON_;
 222         LabeledComponent lc;
 223         lc = new LabeledComponent(labelKey,
 224                                   Resources.getMnemonicInt(labelKey),
 225                                   userNameTF);
 226         lc.label.setFont(boldLabelFont);
 227         userPwdPanel.add(lc);
 228 
 229         passwordTF = new JPasswordField(tfWidth);
 230         // Heights differ, so fix here
 231         passwordTF.setPreferredSize(userNameTF.getPreferredSize());
 232         passwordTF.addActionListener(connectAction);
 233         passwordTF.getDocument().addDocumentListener(this);
 234         passwordTF.addFocusListener(this);
 235         setAccessibleName(passwordTF,
 236                 Messages.PASSWORD_ACCESSIBLE_NAME);
 237         labelKey = "Password: ";
 238         lc = new LabeledComponent(labelKey,
 239                                   Resources.getMnemonicInt(labelKey),
 240                                   passwordTF);
 241         lc.setBorder(new EmptyBorder(0, 12, 0, 0)); // Left padding
 242         lc.label.setFont(boldLabelFont);
 243         userPwdPanel.add(lc);
 244 
 245         remoteTFPanel.add(userPwdPanel, SOUTH);
 246 
 247         String connectButtonToolTipText =
 248                 Messages.CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
 249         connectButton = new JButton(connectAction);
 250         connectButton.setToolTipText(connectButtonToolTipText);
 251 
 252         cancelButton = new JButton(cancelAction);
 253 
 254         JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
 255         buttonPanel.setBorder(new EmptyBorder(12, 12, 2, 12));
 256         if (JConsole.IS_GTK) {
 257             buttonPanel.add(cancelButton);
 258             buttonPanel.add(connectButton);
 259         } else {
 260             buttonPanel.add(connectButton);
 261             buttonPanel.add(cancelButton);
 262         }
 263         bottomPanel.add(buttonPanel, NORTH);
 264 
 265         bottomPanel.add(statusBar, SOUTH);
 266 
 267         updateButtonStates();
 268         Utilities.updateTransparency(this);
 269     }
 270 
 271     public void revalidate() {
 272         // Adjust some colors
 273         hintTextColor =
 274             ensureContrast(UIManager.getColor("Label.disabledForeground"),
 275                            UIManager.getColor("Panel.background"));
 276         disabledTableCellColor =
 277             ensureContrast(new Color(0x808080),
 278                            UIManager.getColor("Table.background"));
 279 
 280         if (remoteMessageLabel != null) {
 281             remoteMessageLabel.setForeground(hintTextColor);
 282             // Update html color setting
 283             String colorStr =
 284                 String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
 285             remoteMessageLabel.setText("<html><font color=#" + colorStr + ">" +
 286                     Messages.REMOTE_TF_USAGE);
 287         }
 288         if (localMessageLabel != null) {
 289             localMessageLabel.setForeground(hintTextColor);
 290             // Update html color setting
 291             valueChanged(null);
 292         }
 293 
 294         super.revalidate();
 295     }
 296 
 297     private void createActions() {
 298         connectAction = new AbstractAction(Messages.CONNECT) {
 299             /* init */ {
 300                 putValue(Action.MNEMONIC_KEY, Resources.getMnemonicInt(Messages.CONNECT));
 301             }
 302 
 303             public void actionPerformed(ActionEvent ev) {
 304                 if (!isEnabled() || !isVisible()) {
 305                     return;
 306                 }
 307                 setVisible(false);
 308                 statusBar.setText("");
 309 
 310                 if (remoteRadioButton.isSelected()) {
 311                     String txt = remoteTF.getText().trim();
 312                     String userName = userNameTF.getText().trim();
 313                     userName = userName.equals("") ? null : userName;
 314                     String password = passwordTF.getText();
 315                     password = password.equals("") ? null : password;
 316                     try {
 317                         if (txt.startsWith(JConsole.ROOT_URL)) {
 318                             String url = txt;

 319                             jConsole.addUrl(url, userName, password, false);
 320                             remoteTF.setText(JConsole.ROOT_URL);
 321                             return;
 322                         } else {
 323                             String host = remoteTF.getText().trim();
 324                             String port = "0";
 325                             int index = host.lastIndexOf(":");
 326                             if (index >= 0) {
 327                                 port = host.substring(index + 1);
 328                                 host = host.substring(0, index);
 329                             }
 330                             if (host.length() > 0 && port.length() > 0) {
 331                                 int p = Integer.parseInt(port.trim());
 332                                 jConsole.addHost(host, p, userName, password);
 333                                 remoteTF.setText("");
 334                                 userNameTF.setText("");
 335                                 passwordTF.setText("");
 336                                 return;
 337                             }
 338                         }
 339                     } catch (Exception ex) {
 340                         statusBar.setText(ex.toString());
 341                     }
 342                     setVisible(true);
 343                 } else if (localRadioButton != null && localRadioButton.isSelected()) {
 344                     // Try to connect to selected VM. If a connection
 345                     // cannot be established for some reason (the process has
 346                     // terminated for example) then keep the dialog open showing
 347                     // the connect error.
 348                     //
 349                     int row = vmTable.getSelectedRow();
 350                     if (row >= 0) {
 351                         jConsole.addVmid(vmModel.vmAt(row));
 352                     }
 353                     refresh();
 354                 }
 355             }
 356         };
 357 
 358         cancelAction = new AbstractAction(Messages.CANCEL) {
 359             public void actionPerformed(ActionEvent ev) {
 360                 setVisible(false);
 361                 statusBar.setText("");
 362             }
 363         };
 364     }
 365 
 366 
 367     // a label used solely for calculating the width
 368     private static JLabel tmpLabel = new JLabel();
 369     public static int getLabelWidth(String text) {
 370         tmpLabel.setText(text);
 371         return (int) tmpLabel.getPreferredSize().getWidth() + 1;
 372     }
 373 
 374     private class LocalTabJTable extends JTable {
 375         ManagedVmTableModel vmModel;
 376         Border rendererBorder = new EmptyBorder(0, 6, 0, 6);
 377 
 378         public LocalTabJTable(ManagedVmTableModel model) {


 565             });
 566         }
 567     }
 568 
 569     public void keyPressed(KeyEvent e) {
 570     }
 571 
 572     public void keyReleased(KeyEvent e) {
 573     }
 574 
 575 
 576     // ListSelectionListener interface
 577     public void valueChanged(ListSelectionEvent e) {
 578         updateButtonStates();
 579         String labelText = " "; // Non-empty to reserve vertical space
 580         int row = vmTable.getSelectedRow();
 581         if (row >= 0) {
 582             LocalVirtualMachine lvm = vmModel.vmAt(row);
 583             if (!lvm.isManageable()) {
 584                 if (lvm.isAttachable()) {
 585                     labelText = Messages.MANAGEMENT_WILL_BE_ENABLED;
 586                 } else {
 587                     labelText = Messages.MANAGEMENT_NOT_ENABLED;
 588                 }
 589             }
 590         }
 591         String colorStr =
 592             String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
 593         localMessageLabel.setText("<html><font color=#" + colorStr + ">" + labelText);
 594     }
 595     // ----
 596 
 597 
 598     // Refresh the list of managed VMs
 599     public void refresh() {
 600         if (vmModel != null) {
 601             // Remember selection
 602             LocalVirtualMachine selected = null;
 603             int row = vmTable.getSelectedRow();
 604             if (row >= 0) {
 605                 selected = vmModel.vmAt(row);
 606             }
 607 


 627             }
 628 
 629             Dimension dim = vmTable.getPreferredSize();
 630 
 631             // Tricky. Reduce height by one to avoid double line at bottom,
 632             // but that causes a scroll bar to appear, so remove it.
 633             dim.height = Math.min(dim.height-1, 100);
 634             localTableScrollPane.setVerticalScrollBarPolicy((dim.height < 100)
 635                                                 ? JScrollPane.VERTICAL_SCROLLBAR_NEVER
 636                                                 : JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
 637             localTableScrollPane.getViewport().setMinimumSize(dim);
 638             localTableScrollPane.getViewport().setPreferredSize(dim);
 639         }
 640         pack();
 641         setLocationRelativeTo(jConsole);
 642     }
 643 
 644     // Represents the list of managed VMs as a tabular data model.
 645     private static class ManagedVmTableModel extends AbstractTableModel {
 646         private static String[] columnNames = {
 647             Messages.COLUMN_NAME,
 648             Messages.COLUMN_PID,
 649         };
 650 
 651         private List<LocalVirtualMachine> vmList;
 652 
 653         public int getColumnCount() {
 654             return columnNames.length;
 655         }
 656 
 657         public String getColumnName(int col) {
 658             return columnNames[col];
 659         }
 660 
 661         public synchronized int getRowCount() {
 662             return vmList.size();
 663         }
 664 
 665         public synchronized Object getValueAt(int row, int col) {
 666             assert col >= 0 && col <= columnNames.length;
 667             LocalVirtualMachine vm = vmList.get(row);
 668             switch (col) {
 669                 case COL_NAME: return vm.displayName();
 670                 case COL_PID:  return vm.vmid();
 671                 default: return null;
 672             }
 673         }
 674 
 675         public Class<?> getColumnClass(int column) {
 676             switch (column) {
 677                 case COL_NAME: return String.class;
 678                 case COL_PID:  return Integer.class;
 679                 default: return super.getColumnClass(column);
 680             }
 681         }
 682 
 683         public ManagedVmTableModel() {
 684             refresh();
 685         }
 686 
 687 
 688         public synchronized LocalVirtualMachine vmAt(int pos) {
 689             return vmList.get(pos);
 690         }
 691 
 692         public synchronized void refresh() {
 693             Map<Integer, LocalVirtualMachine> map =
 694                 LocalVirtualMachine.getAllVirtualMachines();
 695             vmList = new ArrayList<LocalVirtualMachine>();
 696             vmList.addAll(map.values());
 697 
 698             // data has changed
 699             fireTableDataChanged();
 700         }
 701     }
 702 







 703     // A blank component that takes up as much space as the
 704     // button part of a JRadioButton.
 705     private static class Padder extends JPanel {
 706         JRadioButton radioButton;
 707 
 708         Padder(JRadioButton radioButton) {
 709             this.radioButton = radioButton;
 710 
 711             setAccessibleName(this, Messages.BLANK);
 712         }
 713 
 714         public Dimension getPreferredSize() {
 715             Rectangle r = getTextRectangle(radioButton);
 716             int w = (r != null && r.x > 8) ? r.x : 22;
 717 
 718             return new Dimension(w, 0);
 719         }
 720 
 721         private static Rectangle getTextRectangle(AbstractButton button) {
 722             String text = button.getText();
 723             Icon icon = (button.isEnabled()) ? button.getIcon() : button.getDisabledIcon();
 724 
 725             if (icon == null && button.getUI() instanceof BasicRadioButtonUI) {
 726                 icon = ((BasicRadioButtonUI)button.getUI()).getDefaultIcon();
 727             }
 728 
 729             if ((icon == null) && (text == null)) {
 730                 return null;
 731             }
 732 
 733             Rectangle paintIconR = new Rectangle();
 734             Rectangle paintTextR = new Rectangle();
 735             Rectangle paintViewR = new Rectangle();
 736             Insets paintViewInsets = new Insets(0, 0, 0, 0);
 737 
 738             paintViewInsets = button.getInsets(paintViewInsets);
 739             paintViewR.x = paintViewInsets.left;
 740             paintViewR.y = paintViewInsets.top;
 741             paintViewR.width = button.getWidth() - (paintViewInsets.left + paintViewInsets.right);
 742             paintViewR.height = button.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
 743 
 744             Graphics g = button.getGraphics();
 745             if (g == null) {
 746                 return null;
 747             }

 748                 SwingUtilities.layoutCompoundLabel(button,
 749                                                    g.getFontMetrics(),
 750                                                    text,
 751                                                    icon,
 752                                                    button.getVerticalAlignment(),
 753                                                    button.getHorizontalAlignment(),
 754                                                    button.getVerticalTextPosition(),
 755                                                    button.getHorizontalTextPosition(),
 756                                                    paintViewR,
 757                                                    paintIconR,
 758                                                    paintTextR,
 759                                                    button.getIconTextGap());
 760 
 761             return paintTextR;
 762         }
 763     }
 764 
 765 }