package com.ibm.nmon.gui.table; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import javax.swing.KeyStroke; import java.awt.BorderLayout; import java.awt.Component; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.AbstractAction; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import com.ibm.nmon.gui.GUIDialog; import com.ibm.nmon.gui.GUITable; import com.ibm.nmon.gui.Styles; import com.ibm.nmon.gui.main.NMONVisualizerGui; /** * <p> * JDialog for selecting which columns to display in a {@link ChoosableColumnTableModel}. * </p> * * <p> * This dialog creates a list containing the names of the columns from the model along with a * checkbox to select if the column should be displayed or not. Buttons and keyboard shortcuts are * also added to let the user select none, all or a default set of columns. The default set of * columns is defined in the table model. The model also defines the columns that cannot be * disabled. * </p> */ public final class TableColumnChooser extends GUIDialog { private static final long serialVersionUID = -9173600303234433460L; private final ChoosableColumnTableModel tableModel; public TableColumnChooser(NMONVisualizerGui gui, JFrame parent, ChoosableColumnTableModel choosableTableModel) { super(gui, parent, "Select Columns"); setModal(true); setIconImage(Styles.buildIcon("table.png").getImage()); setLayout(new BorderLayout()); this.tableModel = choosableTableModel; // do not allow column names (column 0) to be edited // only allow changing the checkbox if the column can be disabled; note that checkbox should // not show up anyway - see CheckBoxCellRenderer DefaultTableModel model = new DefaultTableModel() { private static final long serialVersionUID = 947165395586168365L; @Override public boolean isCellEditable(int row, int column) { return column == 1 && tableModel.canDisableColumn(row); } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex == 1) { return Boolean.class; } else { return String.class; } } }; model.addColumn("Column"); model.addColumn("Display?"); for (String columnName : tableModel.getAllColumns()) { model.addRow(new Object[] { columnName, Boolean.valueOf(tableModel.getEnabled(columnName)) }); } GUITable table = new GUITable(gui, model); table.getColumnModel().getColumn(0).setMinWidth(100); table.getColumnModel().getColumn(1).setMaxWidth(60); table.setDefaultRenderer(Boolean.class, new CheckBoxCellRenderer()); JScrollPane scrollPane = new JScrollPane(table); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.getViewport().setPreferredSize(new java.awt.Dimension(200, 150)); scrollPane.setBorder(Styles.DOUBLE_LINE_BORDER); add(scrollPane, BorderLayout.CENTER); JButton all = new JButton("All"); all.addActionListener(allAction); JButton none = new JButton("None"); none.setIcon(Styles.CLEAR_ICON); none.addActionListener(noneAction); JButton defaults = new JButton("Default"); defaults.addActionListener(defaultsAction); JPanel temp = new JPanel(); temp.add(all); temp.add(none); temp.add(defaults); add(temp, BorderLayout.PAGE_START); JButton ok = new JButton("OK"); ok.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { DefaultTableModel model = getModel(); for (int i = 0; i < model.getRowCount(); i++) { TableColumnChooser.this.tableModel.setEnabled((String) model.getValueAt(i, 0), (Boolean) model.getValueAt(i, 1)); } dispose(); } }); temp = new JPanel(); temp.add(ok); add(temp, BorderLayout.PAGE_END); getRootPane().setDefaultButton(ok); JPanel content = (JPanel) getContentPane(); ActionMap actions = content.getActionMap(); InputMap inputs = content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); actions.put("all", allAction); actions.put("none", noneAction); actions.put("defaults", defaultsAction); inputs.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK), "all"); inputs.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK), "none"); inputs.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_DOWN_MASK), "defaults"); setVisible(true); } private final AbstractAction allAction = new AbstractAction() { private static final long serialVersionUID = 5118961708188081301L; @Override public void actionPerformed(ActionEvent e) { DefaultTableModel model = getModel(); for (int i = 0; i < model.getRowCount(); i++) { model.setValueAt(true, i, 1); } } }; private final AbstractAction noneAction = new AbstractAction() { private static final long serialVersionUID = -6547510475096869295L; @Override public void actionPerformed(ActionEvent e) { DefaultTableModel model = getModel(); for (int i = 0; i < model.getRowCount(); i++) { if (tableModel.canDisableColumn(i)) { model.setValueAt(false, i, 1); } } } }; private final AbstractAction defaultsAction = new AbstractAction() { private static final long serialVersionUID = -826694390009398839L; @Override public void actionPerformed(ActionEvent e) { DefaultTableModel model = getModel(); for (int i = 0; i < model.getRowCount(); i++) { model.setValueAt(tableModel.getDefaultColumnState(i), i, 1); } } }; private final DefaultTableModel getModel() { return (DefaultTableModel) ((GUITable) ((JScrollPane) TableColumnChooser.this.getContentPane().getComponent(0)) .getViewport().getComponent(0)).getModel(); } private final class CheckBoxCellRenderer implements TableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JComponent renderer = null; boolean red = false; // note 'row' here since each column in the summary table is a row in this chooser table if (!tableModel.canDisableColumn(row)) { JLabel required = new JLabel("Required"); required.setHorizontalAlignment(SwingConstants.CENTER); if (!isSelected) { red = true; } renderer = required; } else { Boolean b = (Boolean) value; JCheckBox checkBox = new JCheckBox(); checkBox.setHorizontalAlignment(SwingConstants.CENTER); if (b != null) { checkBox.setSelected(b); } renderer = checkBox; } // the default check box renderer does not use the correct, alternating colors // this code is modified from http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6723524 Component other = (JLabel) table.getDefaultRenderer(String.class).getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); java.awt.Color bg = other.getBackground(); if (isSelected) { renderer.setForeground(table.getSelectionForeground()); renderer.setBackground(table.getSelectionBackground()); } else { renderer.setForeground(red ? java.awt.Color.RED : other.getForeground()); renderer.setBackground(new java.awt.Color(bg.getRed(), bg.getGreen(), bg.getBlue())); } renderer.setOpaque(true); return renderer; } } }