| /* | |
| * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| package sun.tools.jconsole; | |
| import java.util.List; | |
| import java.awt.*; | |
| import java.awt.event.*; | |
| import java.util.*; | |
| import javax.swing.*; | |
| import javax.swing.border.*; | |
| import javax.swing.event.*; | |
| import javax.swing.plaf.basic.BasicRadioButtonUI; | |
| import javax.swing.table.*; | |
| import static java.awt.BorderLayout.*; | |
| import static javax.swing.ListSelectionModel.*; | |
| import static sun.tools.jconsole.Utilities.*; | |
| @SuppressWarnings("serial") | |
| public class ConnectDialog extends InternalDialog | |
| implements DocumentListener, FocusListener, | |
| ItemListener, ListSelectionListener, KeyListener { | |
| private static final int COL_NAME = 0; | |
| private static final int COL_PID = 1; | |
| JConsole jConsole; | |
| JTextField userNameTF, passwordTF; | |
| JRadioButton localRadioButton, remoteRadioButton; | |
| JLabel localMessageLabel, remoteMessageLabel; | |
| JTextField remoteTF; | |
| JButton connectButton, cancelButton; | |
| JPanel radioButtonPanel; | |
| private Icon mastheadIcon = | |
| new MastheadIcon(Messages.CONNECT_DIALOG_MASTHEAD_TITLE); | |
| private Color hintTextColor, disabledTableCellColor; | |
| // The table of managed VM (local process) | |
| JTable vmTable; | |
| ManagedVmTableModel vmModel = null; | |
| JScrollPane localTableScrollPane = null; | |
| private Action connectAction, cancelAction; | |
| public ConnectDialog(JConsole jConsole) { | |
| super(jConsole, Messages.CONNECT_DIALOG_TITLE, true); | |
| this.jConsole = jConsole; | |
| setAccessibleDescription(this, | |
| Messages.CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION); | |
| setDefaultCloseOperation(HIDE_ON_CLOSE); | |
| setResizable(false); | |
| Container cp = (JComponent)getContentPane(); | |
| radioButtonPanel = new JPanel(new BorderLayout(0, 12)); | |
| radioButtonPanel.setBorder(new EmptyBorder(6, 12, 12, 12)); | |
| ButtonGroup radioButtonGroup = new ButtonGroup(); | |
| JPanel bottomPanel = new JPanel(new BorderLayout()); | |
| statusBar = new JLabel(" ", JLabel.CENTER); | |
| setAccessibleName(statusBar, | |
| Messages.CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME); | |
| Font normalLabelFont = statusBar.getFont(); | |
| Font boldLabelFont = normalLabelFont.deriveFont(Font.BOLD); | |
| Font smallLabelFont = normalLabelFont.deriveFont(normalLabelFont.getSize2D() - 1); | |
| JLabel mastheadLabel = new JLabel(mastheadIcon); | |
| setAccessibleName(mastheadLabel, | |
| Messages.CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME); | |
| cp.add(mastheadLabel, NORTH); | |
| cp.add(radioButtonPanel, CENTER); | |
| cp.add(bottomPanel, SOUTH); | |
| createActions(); | |
| remoteTF = new JTextField(); | |
| remoteTF.addActionListener(connectAction); | |
| remoteTF.getDocument().addDocumentListener(this); | |
| remoteTF.addFocusListener(this); | |
| remoteTF.setPreferredSize(remoteTF.getPreferredSize()); | |
| setAccessibleName(remoteTF, | |
| Messages.REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME); | |
| // | |
| // If the VM supports the local attach mechanism (is: Sun | |
| // implementation) then the Local Process panel is created. | |
| // | |
| if (JConsole.isLocalAttachAvailable()) { | |
| vmModel = new ManagedVmTableModel(); | |
| vmTable = new LocalTabJTable(vmModel); | |
| vmTable.setSelectionMode(SINGLE_SELECTION); | |
| vmTable.setPreferredScrollableViewportSize(new Dimension(400, 250)); | |
| vmTable.setColumnSelectionAllowed(false); | |
| vmTable.addFocusListener(this); | |
| vmTable.getSelectionModel().addListSelectionListener(this); | |
| TableColumnModel columnModel = vmTable.getColumnModel(); | |
| TableColumn pidColumn = columnModel.getColumn(COL_PID); | |
| pidColumn.setMaxWidth(getLabelWidth("9999999")); | |
| pidColumn.setResizable(false); | |
| TableColumn cmdLineColumn = columnModel.getColumn(COL_NAME); | |
| cmdLineColumn.setResizable(false); | |
| localRadioButton = new JRadioButton(Messages.LOCAL_PROCESS_COLON); | |
| localRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.LOCAL_PROCESS_COLON)); | |
| localRadioButton.setFont(boldLabelFont); | |
| localRadioButton.addItemListener(this); | |
| radioButtonGroup.add(localRadioButton); | |
| JPanel localPanel = new JPanel(new BorderLayout()); | |
| JPanel localTablePanel = new JPanel(new BorderLayout()); | |
| radioButtonPanel.add(localPanel, NORTH); | |
| localPanel.add(localRadioButton, NORTH); | |
| localPanel.add(new Padder(localRadioButton), LINE_START); | |
| localPanel.add(localTablePanel, CENTER); | |
| localTableScrollPane = new JScrollPane(vmTable); | |
| localTablePanel.add(localTableScrollPane, NORTH); | |
| localMessageLabel = new JLabel(" "); | |
| localMessageLabel.setFont(smallLabelFont); | |
| localMessageLabel.setForeground(hintTextColor); | |
| localTablePanel.add(localMessageLabel, SOUTH); | |
| } | |
| remoteRadioButton = new JRadioButton(Messages.REMOTE_PROCESS_COLON); | |
| remoteRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.REMOTE_PROCESS_COLON)); | |
| remoteRadioButton.setFont(boldLabelFont); | |
| radioButtonGroup.add(remoteRadioButton); | |
| JPanel remotePanel = new JPanel(new BorderLayout()); | |
| if (localRadioButton != null) { | |
| remotePanel.add(remoteRadioButton, NORTH); | |
| remotePanel.add(new Padder(remoteRadioButton), LINE_START); | |
| Action nextRadioButtonAction = | |
| new AbstractAction("nextRadioButton") { | |
| public void actionPerformed(ActionEvent ev) { | |
| JRadioButton rb = | |
| (ev.getSource() == localRadioButton) ? remoteRadioButton | |
| : localRadioButton; | |
| rb.doClick(); | |
| rb.requestFocus(); | |
| } | |
| }; | |
| localRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction); | |
| remoteRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction); | |
| localRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), | |
| "nextRadioButton"); | |
| remoteRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), | |
| "nextRadioButton"); | |
| } else { | |
| JLabel remoteLabel = new JLabel(remoteRadioButton.getText()); | |
| remoteLabel.setFont(boldLabelFont); | |
| remotePanel.add(remoteLabel, NORTH); | |
| } | |
| radioButtonPanel.add(remotePanel, SOUTH); | |
| JPanel remoteTFPanel = new JPanel(new BorderLayout()); | |
| remotePanel.add(remoteTFPanel, CENTER); | |
| remoteTFPanel.add(remoteTF, NORTH); | |
| remoteMessageLabel = new JLabel("<html>" + Messages.REMOTE_TF_USAGE + "</html>"); | |
| remoteMessageLabel.setFont(smallLabelFont); | |
| remoteMessageLabel.setForeground(hintTextColor); | |
| remoteTFPanel.add(remoteMessageLabel, CENTER); | |
| JPanel userPwdPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0)); | |
| userPwdPanel.setBorder(new EmptyBorder(12, 0, 0, 0)); // top padding | |
| int tfWidth = JConsole.IS_WIN ? 12 : 8; | |
| userNameTF = new JTextField(tfWidth); | |
| userNameTF.addActionListener(connectAction); | |
| userNameTF.getDocument().addDocumentListener(this); | |
| userNameTF.addFocusListener(this); | |
| setAccessibleName(userNameTF, | |
| Messages.USERNAME_ACCESSIBLE_NAME); | |
| LabeledComponent lc; | |
| lc = new LabeledComponent(Messages.USERNAME_COLON_, | |
| Resources.getMnemonicInt(Messages.USERNAME_COLON_), | |
| userNameTF); | |
| lc.label.setFont(boldLabelFont); | |
| userPwdPanel.add(lc); | |
| passwordTF = new JPasswordField(tfWidth); | |
| // Heights differ, so fix here | |
| passwordTF.setPreferredSize(userNameTF.getPreferredSize()); | |
| passwordTF.addActionListener(connectAction); | |
| passwordTF.getDocument().addDocumentListener(this); | |
| passwordTF.addFocusListener(this); | |
| setAccessibleName(passwordTF, | |
| Messages.PASSWORD_ACCESSIBLE_NAME); | |
| lc = new LabeledComponent(Messages.PASSWORD_COLON_, | |
| Resources.getMnemonicInt(Messages.PASSWORD_COLON_), | |
| passwordTF); | |
| lc.setBorder(new EmptyBorder(0, 12, 0, 0)); // Left padding | |
| lc.label.setFont(boldLabelFont); | |
| userPwdPanel.add(lc); | |
| remoteTFPanel.add(userPwdPanel, SOUTH); | |
| String connectButtonToolTipText = | |
| Messages.CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP; | |
| connectButton = new JButton(connectAction); | |
| connectButton.setToolTipText(connectButtonToolTipText); | |
| cancelButton = new JButton(cancelAction); | |
| JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING)); | |
| buttonPanel.setBorder(new EmptyBorder(12, 12, 2, 12)); | |
| if (JConsole.IS_GTK) { | |
| buttonPanel.add(cancelButton); | |
| buttonPanel.add(connectButton); | |
| } else { | |
| buttonPanel.add(connectButton); | |
| buttonPanel.add(cancelButton); | |
| } | |
| bottomPanel.add(buttonPanel, NORTH); | |
| bottomPanel.add(statusBar, SOUTH); | |
| updateButtonStates(); | |
| Utilities.updateTransparency(this); | |
| } | |
| public void revalidate() { | |
| // Adjust some colors | |
| Color disabledForeground = UIManager.getColor("Label.disabledForeground"); | |
| if (disabledForeground == null) { | |
| // fall back for Nimbus that doesn't support 'Label.disabledForeground' | |
| disabledForeground = UIManager.getColor("Label.disabledText"); | |
| } | |
| hintTextColor = | |
| ensureContrast(disabledForeground, | |
| UIManager.getColor("Panel.background")); | |
| disabledTableCellColor = | |
| ensureContrast(new Color(0x808080), | |
| UIManager.getColor("Table.background")); | |
| if (remoteMessageLabel != null) { | |
| remoteMessageLabel.setForeground(hintTextColor); | |
| // Update html color setting | |
| String colorStr = | |
| String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF); | |
| remoteMessageLabel.setText("<html><font color=#" + colorStr + ">" + | |
| Messages.REMOTE_TF_USAGE); | |
| } | |
| if (localMessageLabel != null) { | |
| localMessageLabel.setForeground(hintTextColor); | |
| // Update html color setting | |
| valueChanged(null); | |
| } | |
| super.revalidate(); | |
| } | |
| private void createActions() { | |
| connectAction = new AbstractAction(Messages.CONNECT) { | |
| /* init */ { | |
| putValue(Action.MNEMONIC_KEY, Resources.getMnemonicInt(Messages.CONNECT)); | |
| } | |
| public void actionPerformed(ActionEvent ev) { | |
| if (!isEnabled() || !isVisible()) { | |
| return; | |
| } | |
| setVisible(false); | |
| statusBar.setText(""); | |
| if (remoteRadioButton.isSelected()) { | |
| String txt = remoteTF.getText().trim(); | |
| String userName = userNameTF.getText().trim(); | |
| userName = userName.isEmpty() ? null : userName; | |
| String password = passwordTF.getText(); | |
| password = password.isEmpty() ? null : password; | |
| try { | |
| if (txt.startsWith(JConsole.ROOT_URL)) { | |
| String url = txt; | |
| jConsole.addUrl(url, userName, password, false); | |
| remoteTF.setText(JConsole.ROOT_URL); | |
| return; | |
| } else { | |
| String host = remoteTF.getText().trim(); | |
| String port = "0"; | |
| int index = host.lastIndexOf(':'); | |
| if (index >= 0) { | |
| port = host.substring(index + 1); | |
| host = host.substring(0, index); | |
| } | |
| if (host.length() > 0 && port.length() > 0) { | |
| int p = Integer.parseInt(port.trim()); | |
| jConsole.addHost(host, p, userName, password); | |
| remoteTF.setText(""); | |
| userNameTF.setText(""); | |
| passwordTF.setText(""); | |
| return; | |
| } | |
| } | |
| } catch (Exception ex) { | |
| statusBar.setText(ex.toString()); | |
| } | |
| setVisible(true); | |
| } else if (localRadioButton != null && localRadioButton.isSelected()) { | |
| // Try to connect to selected VM. If a connection | |
| // cannot be established for some reason (the process has | |
| // terminated for example) then keep the dialog open showing | |
| // the connect error. | |
| // | |
| int row = vmTable.getSelectedRow(); | |
| if (row >= 0) { | |
| jConsole.addVmid(vmModel.vmAt(row)); | |
| } | |
| refresh(); | |
| } | |
| } | |
| }; | |
| cancelAction = new AbstractAction(Messages.CANCEL) { | |
| public void actionPerformed(ActionEvent ev) { | |
| setVisible(false); | |
| statusBar.setText(""); | |
| } | |
| }; | |
| } | |
| // a label used solely for calculating the width | |
| private static JLabel tmpLabel = new JLabel(); | |
| public static int getLabelWidth(String text) { | |
| tmpLabel.setText(text); | |
| return (int) tmpLabel.getPreferredSize().getWidth() + 1; | |
| } | |
| private class LocalTabJTable extends JTable { | |
| ManagedVmTableModel vmModel; | |
| Border rendererBorder = new EmptyBorder(0, 6, 0, 6); | |
| public LocalTabJTable(ManagedVmTableModel model) { | |
| super(model); | |
| this.vmModel = model; | |
| // Remove vertical lines, expect for GTK L&F. | |
| // (because GTK doesn't show header dividers) | |
| if (!JConsole.IS_GTK) { | |
| setShowVerticalLines(false); | |
| setIntercellSpacing(new Dimension(0, 1)); | |
| } | |
| // Double-click handler | |
| addMouseListener(new MouseAdapter() { | |
| public void mouseClicked(MouseEvent evt) { | |
| if (evt.getClickCount() == 2) { | |
| connectButton.doClick(); | |
| } | |
| } | |
| }); | |
| // Enter should call default action | |
| getActionMap().put("connect", connectAction); | |
| InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); | |
| inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "connect"); | |
| } | |
| public String getToolTipText(MouseEvent e) { | |
| String tip = null; | |
| java.awt.Point p = e.getPoint(); | |
| int rowIndex = rowAtPoint(p); | |
| int colIndex = columnAtPoint(p); | |
| int realColumnIndex = convertColumnIndexToModel(colIndex); | |
| if (realColumnIndex == COL_NAME) { | |
| LocalVirtualMachine vmd = vmModel.vmAt(rowIndex); | |
| tip = vmd.toString(); | |
| } | |
| return tip; | |
| } | |
| public TableCellRenderer getCellRenderer(int row, int column) { | |
| return new DefaultTableCellRenderer() { | |
| public Component getTableCellRendererComponent(JTable table, | |
| Object value, | |
| boolean isSelected, | |
| boolean hasFocus, | |
| int row, | |
| int column) { | |
| Component comp = | |
| super.getTableCellRendererComponent(table, value, isSelected, | |
| hasFocus, row, column); | |
| if (!isSelected) { | |
| LocalVirtualMachine lvm = vmModel.vmAt(row); | |
| if (!lvm.isManageable() && !lvm.isAttachable()) { | |
| comp.setForeground(disabledTableCellColor); | |
| } | |
| } | |
| if (comp instanceof JLabel) { | |
| JLabel label = (JLabel)comp; | |
| label.setBorder(rendererBorder); | |
| if (value instanceof Integer) { | |
| label.setHorizontalAlignment(JLabel.RIGHT); | |
| } | |
| } | |
| return comp; | |
| } | |
| }; | |
| } | |
| } | |
| public void setConnectionParameters(String url, | |
| String host, | |
| int port, | |
| String userName, | |
| String password, | |
| String msg) { | |
| if ((url != null && url.length() > 0) || | |
| (host != null && host.length() > 0 && port > 0)) { | |
| remoteRadioButton.setSelected(true); | |
| if (url != null && url.length() > 0) { | |
| remoteTF.setText(url); | |
| } else { | |
| remoteTF.setText(host+":"+port); | |
| } | |
| userNameTF.setText((userName != null) ? userName : ""); | |
| passwordTF.setText((password != null) ? password : ""); | |
| statusBar.setText((msg != null) ? msg : ""); | |
| if (getPreferredSize().width > getWidth()) { | |
| pack(); | |
| } | |
| remoteTF.requestFocus(); | |
| remoteTF.selectAll(); | |
| } | |
| } | |
| public void itemStateChanged(ItemEvent ev) { | |
| if (!localRadioButton.isSelected()) { | |
| vmTable.getSelectionModel().clearSelection(); | |
| } | |
| updateButtonStates(); | |
| } | |
| private void updateButtonStates() { | |
| boolean connectEnabled = false; | |
| if (remoteRadioButton.isSelected()) { | |
| connectEnabled = JConsole.isValidRemoteString(remoteTF.getText()); | |
| } else if (localRadioButton != null && localRadioButton.isSelected()) { | |
| int row = vmTable.getSelectedRow(); | |
| if (row >= 0) { | |
| LocalVirtualMachine lvm = vmModel.vmAt(row); | |
| connectEnabled = (lvm.isManageable() || lvm.isAttachable()); | |
| } | |
| } | |
| connectAction.setEnabled(connectEnabled); | |
| } | |
| public void insertUpdate(DocumentEvent e) { | |
| updateButtonStates(); | |
| } | |
| public void removeUpdate(DocumentEvent e) { | |
| updateButtonStates(); | |
| } | |
| public void changedUpdate(DocumentEvent e) { | |
| updateButtonStates(); | |
| } | |
| public void focusGained(FocusEvent e) { | |
| Object source = e.getSource(); | |
| Component opposite = e.getOppositeComponent(); | |
| if (!e.isTemporary() && | |
| source instanceof JTextField && | |
| opposite instanceof JComponent && | |
| SwingUtilities.getRootPane(opposite) == getRootPane()) { | |
| ((JTextField)source).selectAll(); | |
| } | |
| if (source == remoteTF) { | |
| remoteRadioButton.setSelected(true); | |
| } else if (source == vmTable) { | |
| localRadioButton.setSelected(true); | |
| if (vmModel.getRowCount() == 1) { | |
| // if there's only one process then select the row | |
| vmTable.setRowSelectionInterval(0, 0); | |
| } | |
| } | |
| updateButtonStates(); | |
| } | |
| public void focusLost(FocusEvent e) { | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| char c = e.getKeyChar(); | |
| if (c == KeyEvent.VK_ESCAPE) { | |
| setVisible(false); | |
| } else if (!(Character.isDigit(c) || | |
| c == KeyEvent.VK_BACK_SPACE || | |
| c == KeyEvent.VK_DELETE)) { | |
| getToolkit().beep(); | |
| e.consume(); | |
| } | |
| } | |
| public void setVisible(boolean b) { | |
| boolean wasVisible = isVisible(); | |
| super.setVisible(b); | |
| if (b && !wasVisible) { | |
| SwingUtilities.invokeLater(new Runnable() { | |
| public void run() { | |
| if (remoteRadioButton.isSelected()) { | |
| remoteTF.requestFocus(); | |
| remoteTF.selectAll(); | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| public void keyPressed(KeyEvent e) { | |
| } | |
| public void keyReleased(KeyEvent e) { | |
| } | |
| // ListSelectionListener interface | |
| public void valueChanged(ListSelectionEvent e) { | |
| updateButtonStates(); | |
| String labelText = " "; // Non-empty to reserve vertical space | |
| int row = vmTable.getSelectedRow(); | |
| if (row >= 0) { | |
| LocalVirtualMachine lvm = vmModel.vmAt(row); | |
| if (!lvm.isManageable()) { | |
| if (lvm.isAttachable()) { | |
| labelText = Messages.MANAGEMENT_WILL_BE_ENABLED; | |
| } else { | |
| labelText = Messages.MANAGEMENT_NOT_ENABLED; | |
| } | |
| } | |
| } | |
| String colorStr = | |
| String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF); | |
| localMessageLabel.setText("<html><font color=#" + colorStr + ">" + labelText); | |
| } | |
| // ---- | |
| // Refresh the list of managed VMs | |
| public void refresh() { | |
| if (vmModel != null) { | |
| // Remember selection | |
| LocalVirtualMachine selected = null; | |
| int row = vmTable.getSelectedRow(); | |
| if (row >= 0) { | |
| selected = vmModel.vmAt(row); | |
| } | |
| vmModel.refresh(); | |
| int selectRow = -1; | |
| int n = vmModel.getRowCount(); | |
| if (selected != null) { | |
| for (int i = 0; i < n; i++) { | |
| LocalVirtualMachine lvm = vmModel.vmAt(i); | |
| if (selected.vmid() == lvm.vmid() && | |
| selected.toString().equals(lvm.toString())) { | |
| selectRow = i; | |
| break; | |
| } | |
| } | |
| } | |
| if (selectRow > -1) { | |
| vmTable.setRowSelectionInterval(selectRow, selectRow); | |
| } else { | |
| vmTable.getSelectionModel().clearSelection(); | |
| } | |
| Dimension dim = vmTable.getPreferredSize(); | |
| // Tricky. Reduce height by one to avoid double line at bottom, | |
| // but that causes a scroll bar to appear, so remove it. | |
| dim.height = Math.min(dim.height-1, 100); | |
| localTableScrollPane.setVerticalScrollBarPolicy((dim.height < 100) | |
| ? JScrollPane.VERTICAL_SCROLLBAR_NEVER | |
| : JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); | |
| localTableScrollPane.getViewport().setMinimumSize(dim); | |
| localTableScrollPane.getViewport().setPreferredSize(dim); | |
| } | |
| pack(); | |
| setLocationRelativeTo(jConsole); | |
| } | |
| // Represents the list of managed VMs as a tabular data model. | |
| private static class ManagedVmTableModel extends AbstractTableModel { | |
| private static String[] columnNames = { | |
| Messages.COLUMN_NAME, | |
| Messages.COLUMN_PID, | |
| }; | |
| private List<LocalVirtualMachine> vmList; | |
| public int getColumnCount() { | |
| return columnNames.length; | |
| } | |
| public String getColumnName(int col) { | |
| return columnNames[col]; | |
| } | |
| public synchronized int getRowCount() { | |
| return vmList.size(); | |
| } | |
| public synchronized Object getValueAt(int row, int col) { | |
| assert col >= 0 && col <= columnNames.length; | |
| LocalVirtualMachine vm = vmList.get(row); | |
| switch (col) { | |
| case COL_NAME: return vm.displayName(); | |
| case COL_PID: return vm.vmid(); | |
| default: return null; | |
| } | |
| } | |
| public Class<?> getColumnClass(int column) { | |
| switch (column) { | |
| case COL_NAME: return String.class; | |
| case COL_PID: return Integer.class; | |
| default: return super.getColumnClass(column); | |
| } | |
| } | |
| public ManagedVmTableModel() { | |
| refresh(); | |
| } | |
| public synchronized LocalVirtualMachine vmAt(int pos) { | |
| return vmList.get(pos); | |
| } | |
| public synchronized void refresh() { | |
| Map<Integer, LocalVirtualMachine> map = | |
| LocalVirtualMachine.getAllVirtualMachines(); | |
| vmList = new ArrayList<LocalVirtualMachine>(); | |
| vmList.addAll(map.values()); | |
| // data has changed | |
| fireTableDataChanged(); | |
| } | |
| } | |
| // A blank component that takes up as much space as the | |
| // button part of a JRadioButton. | |
| private static class Padder extends JPanel { | |
| JRadioButton radioButton; | |
| Padder(JRadioButton radioButton) { | |
| this.radioButton = radioButton; | |
| setAccessibleName(this, Messages.BLANK); | |
| } | |
| public Dimension getPreferredSize() { | |
| Rectangle r = getTextRectangle(radioButton); | |
| int w = (r != null && r.x > 8) ? r.x : 22; | |
| return new Dimension(w, 0); | |
| } | |
| private static Rectangle getTextRectangle(AbstractButton button) { | |
| String text = button.getText(); | |
| Icon icon = (button.isEnabled()) ? button.getIcon() : button.getDisabledIcon(); | |
| if (icon == null && button.getUI() instanceof BasicRadioButtonUI) { | |
| icon = ((BasicRadioButtonUI)button.getUI()).getDefaultIcon(); | |
| } | |
| if ((icon == null) && (text == null)) { | |
| return null; | |
| } | |
| Rectangle paintIconR = new Rectangle(); | |
| Rectangle paintTextR = new Rectangle(); | |
| Rectangle paintViewR = new Rectangle(); | |
| Insets paintViewInsets = new Insets(0, 0, 0, 0); | |
| paintViewInsets = button.getInsets(paintViewInsets); | |
| paintViewR.x = paintViewInsets.left; | |
| paintViewR.y = paintViewInsets.top; | |
| paintViewR.width = button.getWidth() - (paintViewInsets.left + paintViewInsets.right); | |
| paintViewR.height = button.getHeight() - (paintViewInsets.top + paintViewInsets.bottom); | |
| Graphics g = button.getGraphics(); | |
| if (g == null) { | |
| return null; | |
| } | |
| SwingUtilities.layoutCompoundLabel(button, | |
| g.getFontMetrics(), | |
| text, | |
| icon, | |
| button.getVerticalAlignment(), | |
| button.getHorizontalAlignment(), | |
| button.getVerticalTextPosition(), | |
| button.getHorizontalTextPosition(), | |
| paintViewR, | |
| paintIconR, | |
| paintTextR, | |
| button.getIconTextGap()); | |
| return paintTextR; | |
| } | |
| } | |
| } |