Added delete button to preset row in table.
authorrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Fri, 11 May 2012 03:02:35 +0000 (03:02 +0000)
committerrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Fri, 11 May 2012 03:02:35 +0000 (03:02 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@665 180e2498-e6e9-4542-8430-84ac67f01cd8

core/src/net/sf/openrocket/gui/preset/ButtonColumn.java [new file with mode: 0644]
core/src/net/sf/openrocket/gui/preset/ComponentPresetPanel.java

diff --git a/core/src/net/sf/openrocket/gui/preset/ButtonColumn.java b/core/src/net/sf/openrocket/gui/preset/ButtonColumn.java
new file mode 100644 (file)
index 0000000..13b8653
--- /dev/null
@@ -0,0 +1,238 @@
+package net.sf.openrocket.gui.preset;
+
+import javax.swing.AbstractCellEditor;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JTable;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.LineBorder;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+/**
+ *  The ButtonColumn class provides a renderer and an editor that looks like a
+ *  JButton. The renderer and editor will then be used for a specified column
+ *  in the table. The TableModel will contain the String to be displayed on
+ *  the button.
+ *
+ *  The button can be invoked by a mouse click or by pressing the space bar
+ *  when the cell has focus. Optionaly a mnemonic can be set to invoke the
+ *  button. When the button is invoked the provided Action is invoked. The
+ *  source of the Action will be the table. The action command will contain
+ *  the model row number of the button that was clicked.
+ *
+ * Credits: A post by Rob Camick   http://tips4java.wordpress.com/2009/07/12/table-button-column/
+ */
+public class ButtonColumn extends AbstractCellEditor
+       implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener
+{
+       private JTable table;
+       private Action action;
+       private int mnemonic;
+       private Border originalBorder;
+       private Border focusBorder;
+
+       private JButton renderButton;
+       private JButton editButton;
+       private Object editorValue;
+       private boolean isButtonColumnEditor;
+
+       /**
+        *  Create the ButtonColumn to be used as a renderer and editor. The
+        *  renderer and editor will automatically be installed on the TableColumn
+        *  of the specified column.
+        *
+        *  @param table the table containing the button renderer/editor
+        *  @param action the Action to be invoked when the button is invoked
+        *  @param column the column to which the button renderer/editor is added
+        */
+       public ButtonColumn(JTable table, Action action, int column)
+       {
+               this.table = table;
+               this.action = action;
+
+               renderButton = new JButton();
+               editButton = new JButton();
+               editButton.setFocusPainted( false );
+               editButton.addActionListener( this );
+               originalBorder = editButton.getBorder();
+               setFocusBorder( new LineBorder(Color.BLUE) );
+
+               TableColumnModel columnModel = table.getColumnModel();
+               columnModel.getColumn(column).setCellRenderer( this );
+               columnModel.getColumn(column).setCellEditor( this );
+               table.addMouseListener( this );
+       }
+
+
+       /**
+        *  Get foreground color of the button when the cell has focus
+        *
+        *  @return the foreground color
+        */
+       public Border getFocusBorder()
+       {
+               return focusBorder;
+       }
+
+       /**
+        *  The foreground color of the button when the cell has focus
+        *
+        *  @param focusBorder the foreground color
+        */
+       public void setFocusBorder(Border focusBorder)
+       {
+               this.focusBorder = focusBorder;
+               editButton.setBorder( focusBorder );
+       }
+
+       public int getMnemonic()
+       {
+               return mnemonic;
+       }
+
+       /**
+        *  The mnemonic to activate the button when the cell has focus
+        *
+        *  @param mnemonic the mnemonic
+        */
+       public void setMnemonic(int mnemonic)
+       {
+               this.mnemonic = mnemonic;
+               renderButton.setMnemonic(mnemonic);
+               editButton.setMnemonic(mnemonic);
+       }
+
+       @Override
+       public Component getTableCellEditorComponent(
+               JTable table, Object value, boolean isSelected, int row, int column)
+       {
+               if (value == null)
+               {
+                       editButton.setText( "" );
+                       editButton.setIcon( null );
+               }
+               else if (value instanceof Icon)
+               {
+                       editButton.setText( "" );
+                       editButton.setIcon( (Icon)value );
+               }
+               else
+               {
+                       editButton.setText( value.toString() );
+                       editButton.setIcon( null );
+               }
+
+               this.editorValue = value;
+               return editButton;
+       }
+
+       @Override
+       public Object getCellEditorValue()
+       {
+               return editorValue;
+       }
+
+//
+//  Implement TableCellRenderer interface
+//
+       public Component getTableCellRendererComponent(
+               JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
+       {
+               if (isSelected)
+               {
+                       renderButton.setForeground(table.getSelectionForeground());
+                       renderButton.setBackground(table.getSelectionBackground());
+               }
+               else
+               {
+                       renderButton.setForeground(table.getForeground());
+                       renderButton.setBackground(UIManager.getColor("Button.background"));
+               }
+
+               if (hasFocus)
+               {
+                       renderButton.setBorder( focusBorder );
+               }
+               else
+               {
+                       renderButton.setBorder( originalBorder );
+               }
+
+//             renderButton.setText( (value == null) ? "" : value.toString() );
+               if (value == null)
+               {
+                       renderButton.setText( "" );
+                       renderButton.setIcon( null );
+               }
+               else if (value instanceof Icon)
+               {
+                       renderButton.setText( "" );
+                       renderButton.setIcon( (Icon)value );
+               }
+               else
+               {
+                       renderButton.setText( value.toString() );
+                       renderButton.setIcon( null );
+               }
+
+               return renderButton;
+       }
+
+//
+//  Implement ActionListener interface
+//
+       /*
+        *      The button has been pressed. Stop editing and invoke the custom Action
+        */
+       public void actionPerformed(ActionEvent e)
+       {
+               int row = table.convertRowIndexToModel( table.getEditingRow() );
+               fireEditingStopped();
+
+               //  Invoke the Action
+
+               ActionEvent event = new ActionEvent(
+                       table,
+                       ActionEvent.ACTION_PERFORMED,
+                       "" + row);
+               action.actionPerformed(event);
+       }
+
+//
+//  Implement MouseListener interface
+//
+       /*
+        *  When the mouse is pressed the editor is invoked. If you then drag
+        *  the mouse to another cell before releasing it, the editor is still
+        *  active. Make sure editing is stopped when the mouse is released.
+        */
+    public void mousePressed(MouseEvent e)
+    {
+       if (table.isEditing()
+               &&  table.getCellEditor() == this)
+                       isButtonColumnEditor = true;
+    }
+
+    public void mouseReleased(MouseEvent e)
+    {
+       if (isButtonColumnEditor
+       &&  table.isEditing())
+               table.getCellEditor().stopCellEditing();
+
+               isButtonColumnEditor = false;
+    }
+
+    public void mouseClicked(MouseEvent e) {}
+       public void mouseEntered(MouseEvent e) {}
+    public void mouseExited(MouseEvent e) {}
+}
index d1745145e48da8fdcfa2268d58c2eba359499124..6d2ec868806545323e8b699e5c863fd6d0e2fe9e 100644 (file)
@@ -2,6 +2,7 @@ package net.sf.openrocket.gui.preset;
 
 import net.miginfocom.swing.MigLayout;
 import net.sf.openrocket.gui.util.FileHelper;
+import net.sf.openrocket.gui.util.Icons;
 import net.sf.openrocket.gui.util.SwingPreferences;
 import net.sf.openrocket.l10n.ResourceBundleTranslator;
 import net.sf.openrocket.logging.LogHelper;
@@ -10,10 +11,14 @@ import net.sf.openrocket.preset.ComponentPreset;
 import net.sf.openrocket.preset.xml.OpenRocketComponentSaver;
 import net.sf.openrocket.startup.Application;
 
+import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.JButton;
 import javax.swing.JDialog;
 import javax.swing.JFileChooser;
 import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTable;
@@ -31,7 +36,11 @@ import java.util.List;
 
 /**
  * A UI for editing component presets.  Currently this is a standalone application - run the main within this class.
- * TODO: Full I18n TODO: Delete component TODO: Open .orc for editing TODO: Import .csv TODO: Export .csv TODO: Menu
+ * TODO: Full I18n
+ * TODO: Open .orc for editing
+ * TODO: Open .csv
+ * TODO: Save As .csv
+ * TODO: Menu
  */
 public class ComponentPresetPanel extends JPanel implements PresetResultListener {
 
@@ -71,9 +80,22 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
     public ComponentPresetPanel() {
         setLayout(new MigLayout("", "[82.00px][168.00px][84px][117.00px][][222px]", "[346.00px][29px]"));
 
-        model = new DataTableModel(new String[]{"Manufacturer", "Type", "Part No", "Description"});
+        model = new DataTableModel(new String[]{"Manufacturer", "Type", "Part No", "Description", ""});
 
         table = new JTable(model);
+        table.getTableHeader().setFont(new JLabel().getFont());
+        //The action never gets called because the table MouseAdapter intercepts it first.  Still need an empty
+        // instance though.
+        Action action = new AbstractAction() {
+            @Override
+            public void actionPerformed(final ActionEvent e) {
+            }
+        };
+        //Create a editor/renderer for the delete operation.  Instantiation self-registers into the table.
+        new ButtonColumn(table, action, 4);
+        table.getColumnModel().getColumn(4).setMaxWidth(Icons.EDIT_DELETE.getIconWidth());
+        table.getColumnModel().getColumn(4).setMinWidth(Icons.EDIT_DELETE.getIconWidth());
+
         JScrollPane scrollPane = new JScrollPane(table);
         table.setFillsViewportHeight(true);
         table.setAutoCreateRowSorter(true);
@@ -81,11 +103,21 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
 
         table.addMouseListener(new MouseAdapter() {
             public void mouseClicked(MouseEvent e) {
-                if (e.getClickCount() == 2) {
-                    JTable target = (JTable) e.getSource();
-                    int row = target.getSelectedRow();
-                    editingSelected = true;
-                    new PresetEditorDialog(ComponentPresetPanel.this, (ComponentPreset) model.getAssociatedObject(row)).setVisible(true);
+                JTable target = (JTable) e.getSource();
+                if (target.getSelectedColumn() == 4) {
+                    if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(ComponentPresetPanel.this,
+                            "Do you want to delete this preset?",
+                            "Confirm Delete", JOptionPane.YES_OPTION,
+                            JOptionPane.QUESTION_MESSAGE)) {
+                        model.removeRow(target.getSelectedRow());
+                    }
+                }
+                else {
+                    if (e.getClickCount() == 2) {
+                        int row = target.getSelectedRow();
+                        editingSelected = true;
+                        new PresetEditorDialog(ComponentPresetPanel.this, (ComponentPreset) model.getAssociatedObject(row)).setVisible(true);
+                    }
                 }
             }
         });
@@ -108,13 +140,9 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
                 try {
                     saveAsORC();
                 }
-                catch (JAXBException e1) {
-                    //TODO
-                    e1.printStackTrace();
-                }
-                catch (IOException e1) {
-                    //TODO
-                    e1.printStackTrace();
+                catch (Exception e1) {
+                    JOptionPane.showMessageDialog(ComponentPresetPanel.this, e1.getLocalizedMessage(),
+                            "Error saving ORC file.", JOptionPane.ERROR_MESSAGE);
                 }
             }
         });
@@ -144,7 +172,8 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
             DataTableModel model = (DataTableModel) table.getModel();
             //Is this a new preset?
             if (!editingSelected) {
-                model.addRow(new String[]{preset.getManufacturer().getDisplayName(), preset.getType().name(), preset.getPartNo(), preset.get(ComponentPreset.DESCRIPTION)}, preset);
+                model.addRow(new Object[]{preset.getManufacturer().getDisplayName(), preset.getType().name(),
+                        preset.getPartNo(), preset.get(ComponentPreset.DESCRIPTION), Icons.EDIT_DELETE}, preset);
             }
             else {
                 //This is a modified preset; update all of the columns and the stored associated instance.