create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / preset / ButtonColumn.java
1 package net.sf.openrocket.gui.preset;
2
3 import javax.swing.AbstractCellEditor;
4 import javax.swing.Action;
5 import javax.swing.Icon;
6 import javax.swing.JButton;
7 import javax.swing.JTable;
8 import javax.swing.UIManager;
9 import javax.swing.border.Border;
10 import javax.swing.border.LineBorder;
11 import javax.swing.table.TableCellEditor;
12 import javax.swing.table.TableCellRenderer;
13 import javax.swing.table.TableColumnModel;
14 import java.awt.Color;
15 import java.awt.Component;
16 import java.awt.event.ActionEvent;
17 import java.awt.event.ActionListener;
18 import java.awt.event.MouseEvent;
19 import java.awt.event.MouseListener;
20
21 /**
22  *  The ButtonColumn class provides a renderer and an editor that looks like a
23  *  JButton. The renderer and editor will then be used for a specified column
24  *  in the table. The TableModel will contain the String to be displayed on
25  *  the button.
26  *
27  *  The button can be invoked by a mouse click or by pressing the space bar
28  *  when the cell has focus. Optionaly a mnemonic can be set to invoke the
29  *  button. When the button is invoked the provided Action is invoked. The
30  *  source of the Action will be the table. The action command will contain
31  *  the model row number of the button that was clicked.
32  *
33  * Credits: A post by Rob Camick   http://tips4java.wordpress.com/2009/07/12/table-button-column/
34  */
35 public class ButtonColumn extends AbstractCellEditor
36         implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener
37 {
38         private JTable table;
39         private Action action;
40         private int mnemonic;
41         private Border originalBorder;
42         private Border focusBorder;
43
44         private JButton renderButton;
45         private JButton editButton;
46         private Object editorValue;
47         private boolean isButtonColumnEditor;
48
49         /**
50          *  Create the ButtonColumn to be used as a renderer and editor. The
51          *  renderer and editor will automatically be installed on the TableColumn
52          *  of the specified column.
53          *
54          *  @param table the table containing the button renderer/editor
55          *  @param action the Action to be invoked when the button is invoked
56          *  @param column the column to which the button renderer/editor is added
57          */
58         public ButtonColumn(JTable table, Action action, int column)
59         {
60                 this.table = table;
61                 this.action = action;
62
63                 renderButton = new JButton();
64                 editButton = new JButton();
65                 editButton.setFocusPainted( false );
66                 editButton.addActionListener( this );
67                 originalBorder = editButton.getBorder();
68                 setFocusBorder( new LineBorder(Color.BLUE) );
69
70                 TableColumnModel columnModel = table.getColumnModel();
71                 columnModel.getColumn(column).setCellRenderer( this );
72                 columnModel.getColumn(column).setCellEditor( this );
73                 table.addMouseListener( this );
74         }
75
76
77         /**
78          *  Get foreground color of the button when the cell has focus
79          *
80          *  @return the foreground color
81          */
82         public Border getFocusBorder()
83         {
84                 return focusBorder;
85         }
86
87         /**
88          *  The foreground color of the button when the cell has focus
89          *
90          *  @param focusBorder the foreground color
91          */
92         public void setFocusBorder(Border focusBorder)
93         {
94                 this.focusBorder = focusBorder;
95                 editButton.setBorder( focusBorder );
96         }
97
98         public int getMnemonic()
99         {
100                 return mnemonic;
101         }
102
103         /**
104          *  The mnemonic to activate the button when the cell has focus
105          *
106          *  @param mnemonic the mnemonic
107          */
108         public void setMnemonic(int mnemonic)
109         {
110                 this.mnemonic = mnemonic;
111                 renderButton.setMnemonic(mnemonic);
112                 editButton.setMnemonic(mnemonic);
113         }
114
115         @Override
116         public Component getTableCellEditorComponent(
117                 JTable table, Object value, boolean isSelected, int row, int column)
118         {
119                 if (value == null)
120                 {
121                         editButton.setText( "" );
122                         editButton.setIcon( null );
123                 }
124                 else if (value instanceof Icon)
125                 {
126                         editButton.setText( "" );
127                         editButton.setIcon( (Icon)value );
128                 }
129                 else
130                 {
131                         editButton.setText( value.toString() );
132                         editButton.setIcon( null );
133                 }
134
135                 this.editorValue = value;
136                 return editButton;
137         }
138
139         @Override
140         public Object getCellEditorValue()
141         {
142                 return editorValue;
143         }
144
145 //
146 //  Implement TableCellRenderer interface
147 //
148         public Component getTableCellRendererComponent(
149                 JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
150         {
151                 if (isSelected)
152                 {
153                         renderButton.setForeground(table.getSelectionForeground());
154                         renderButton.setBackground(table.getSelectionBackground());
155                 }
156                 else
157                 {
158                         renderButton.setForeground(table.getForeground());
159                         renderButton.setBackground(UIManager.getColor("Button.background"));
160                 }
161
162                 if (hasFocus)
163                 {
164                         renderButton.setBorder( focusBorder );
165                 }
166                 else
167                 {
168                         renderButton.setBorder( originalBorder );
169                 }
170
171 //              renderButton.setText( (value == null) ? "" : value.toString() );
172                 if (value == null)
173                 {
174                         renderButton.setText( "" );
175                         renderButton.setIcon( null );
176                 }
177                 else if (value instanceof Icon)
178                 {
179                         renderButton.setText( "" );
180                         renderButton.setIcon( (Icon)value );
181                 }
182                 else
183                 {
184                         renderButton.setText( value.toString() );
185                         renderButton.setIcon( null );
186                 }
187
188                 return renderButton;
189         }
190
191 //
192 //  Implement ActionListener interface
193 //
194         /*
195          *      The button has been pressed. Stop editing and invoke the custom Action
196          */
197         public void actionPerformed(ActionEvent e)
198         {
199                 int row = table.convertRowIndexToModel( table.getEditingRow() );
200                 fireEditingStopped();
201
202                 //  Invoke the Action
203
204                 ActionEvent event = new ActionEvent(
205                         table,
206                         ActionEvent.ACTION_PERFORMED,
207                         "" + row);
208                 action.actionPerformed(event);
209         }
210
211 //
212 //  Implement MouseListener interface
213 //
214         /*
215          *  When the mouse is pressed the editor is invoked. If you then drag
216          *  the mouse to another cell before releasing it, the editor is still
217          *  active. Make sure editing is stopped when the mouse is released.
218          */
219     public void mousePressed(MouseEvent e)
220     {
221         if (table.isEditing()
222                 &&  table.getCellEditor() == this)
223                         isButtonColumnEditor = true;
224     }
225
226     public void mouseReleased(MouseEvent e)
227     {
228         if (isButtonColumnEditor
229         &&  table.isEditing())
230                 table.getCellEditor().stopCellEditing();
231
232                 isButtonColumnEditor = false;
233     }
234
235     public void mouseClicked(MouseEvent e) {}
236         public void mouseEntered(MouseEvent e) {}
237     public void mouseExited(MouseEvent e) {}
238 }