--- /dev/null
+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) {}
+}
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;
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;
/**
* 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 {
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);
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);
+ }
}
}
});
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);
}
}
});
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.