001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc;
005:
006: import org.apache.commons.lang.StringUtils;
007:
008: import org.dijon.Button;
009: import org.dijon.CheckBox;
010: import org.dijon.Container;
011: import org.dijon.Label;
012: import org.dijon.jspring.Layout;
013:
014: import com.tc.admin.common.XAbstractAction;
015: import com.tc.admin.common.XCellEditor;
016: import com.tc.admin.common.XCheckBox;
017: import com.tc.admin.common.XComboBox;
018: import com.tc.admin.common.XObjectTable;
019: import com.tc.admin.common.XTableCellRenderer;
020: import com.terracottatech.config.Include;
021: import com.terracottatech.config.OnLoad;
022:
023: import java.awt.Color;
024: import java.awt.Insets;
025: import java.awt.event.ActionEvent;
026: import java.awt.event.ActionListener;
027: import java.awt.event.InputEvent;
028: import java.awt.event.KeyEvent;
029: import java.awt.event.MouseEvent;
030:
031: import javax.swing.ActionMap;
032: import javax.swing.DefaultComboBoxModel;
033: import javax.swing.InputMap;
034: import javax.swing.JComponent;
035: import javax.swing.JTable;
036: import javax.swing.KeyStroke;
037: import javax.swing.ListSelectionModel;
038: import javax.swing.SwingUtilities;
039: import javax.swing.UIManager;
040: import javax.swing.table.TableCellEditor;
041:
042: public class RuleTable extends XObjectTable {
043: private OnLoadDialog m_onLoadDialog;
044:
045: private static final String MOVE_UP_ACTION = "MoveUp";
046: private static final String MOVE_DOWN_ACTION = "MoveDown";
047:
048: private static final KeyStroke MOVE_UP_STROKE = KeyStroke
049: .getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_MASK);
050: private static final KeyStroke MOVE_DOWN_STROKE = KeyStroke
051: .getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_MASK);
052:
053: public RuleTable() {
054: super ();
055:
056: setDefaultRenderer(Integer.class, new RuleTypeRenderer());
057: setDefaultEditor(Integer.class, new RuleTypeEditor());
058:
059: setDefaultRenderer(RuleDetail.class, new RuleDetailRenderer());
060: setDefaultEditor(RuleDetail.class, new RuleDetailEditor(true));
061:
062: getSelectionModel().setSelectionMode(
063: ListSelectionModel.SINGLE_SELECTION);
064:
065: ActionMap actionMap = getActionMap();
066: actionMap.put(MOVE_UP_ACTION, new MoveUpAction());
067: actionMap.put(MOVE_DOWN_ACTION, new MoveDownAction());
068:
069: InputMap inputMap = getInputMap();
070: inputMap.put(MOVE_UP_STROKE, MOVE_UP_ACTION);
071: inputMap.put(MOVE_DOWN_STROKE, MOVE_DOWN_ACTION);
072: }
073:
074: public OnLoadDialog getOnLoadDialog() {
075: if (m_onLoadDialog == null) {
076: m_onLoadDialog = new OnLoadDialog();
077: }
078: return m_onLoadDialog;
079: }
080:
081: class RuleTypeRenderer extends XTableCellRenderer {
082: public java.awt.Component getTableCellRendererComponent(
083: JTable table, Object value, boolean isSelected,
084: boolean hasFocus, int row, int col) {
085: super .getTableCellRendererComponent(table, value,
086: isSelected, hasFocus, row, col);
087:
088: Rule rule = getRuleAt(row);
089: setText(rule.isExcludeRule() ? "Exclude" : "Include");
090:
091: return this ;
092: }
093: }
094:
095: class RuleTypeEditor extends XCellEditor {
096: private static final String INCLUDE_ITEM = "Include";
097: private static final String EXCLUDE_ITEM = "Exclude";
098:
099: private final String[] MODEL_ITEMS = new String[] {
100: INCLUDE_ITEM, EXCLUDE_ITEM };
101:
102: private int m_row;
103: private DefaultComboBoxModel m_model;
104:
105: RuleTypeEditor() {
106: super (new XComboBox());
107: m_model = new DefaultComboBoxModel(MODEL_ITEMS);
108: ((XComboBox) m_editorComponent).setModel(m_model);
109: }
110:
111: protected void fireEditingStopped() {
112: super .fireEditingStopped();
113: setRowSelectionInterval(m_row, m_row);
114: }
115:
116: public Object getCellEditorValue() {
117: Object value = super .getCellEditorValue();
118: return new Integer(
119: value.equals(INCLUDE_ITEM) ? Rule.INCLUDE_RULE
120: : Rule.EXCLUDE_RULE);
121: }
122:
123: public java.awt.Component getTableCellEditorComponent(
124: JTable table, Object value, boolean isSelected,
125: int row, int col) {
126: super .getTableCellEditorComponent(table, value, isSelected,
127: row, col);
128:
129: Rule rule = getRuleAt(row);
130: m_model.setSelectedItem(MODEL_ITEMS[rule.getType()]);
131: m_row = row;
132:
133: return (java.awt.Component) m_editorComponent;
134: }
135: }
136:
137: class RuleDetailRenderer extends XTableCellRenderer {
138: protected TableCellEditor m_editor;
139:
140: public RuleDetailRenderer() {
141: super ();
142: m_editor = createCellEditor();
143: }
144:
145: protected TableCellEditor createCellEditor() {
146: return new RuleDetailEditor(false);
147: }
148:
149: public java.awt.Component getTableCellRendererComponent(
150: JTable table, Object value, boolean isSelected,
151: boolean hasFocus, int row, int col) {
152: JComponent c = (JComponent) m_editor
153: .getTableCellEditorComponent(table, value,
154: isSelected, row, col);
155:
156: c
157: .setBorder(hasFocus ? UIManager
158: .getBorder("Table.focusCellHighlightBorder")
159: : null);
160:
161: return c;
162: }
163: }
164:
165: private static String buildToolTip(Include include) {
166: OnLoad onLoad = include.getOnLoad();
167: String tip = null;
168:
169: if (onLoad != null) {
170: if ((tip = onLoad.getMethod()) == null) {
171: if ((tip = onLoad.getExecute()) != null) {
172: StringBuffer sb = new StringBuffer();
173: String[] lines = StringUtils.split(onLoad
174: .getExecute(), System
175: .getProperty("line.separator"));
176:
177: sb.append("<html>");
178: for (int i = 0; i < lines.length; i++) {
179: sb.append("<p>");
180: sb.append(lines[i]);
181: }
182: sb.append("</html>");
183:
184: tip = sb.toString();
185: }
186: }
187: }
188:
189: return tip;
190: }
191:
192: class OnLoadButton extends Button {
193: int m_row, m_col;
194:
195: OnLoadButton(String text) {
196: super (text);
197: setMargin(new Insets(0, 2, 0, 2));
198: }
199:
200: void setCell(int row, int col) {
201: m_row = row;
202: m_col = col;
203: }
204:
205: int getRow() {
206: return m_row;
207: }
208:
209: int getCol() {
210: return m_col;
211: }
212: }
213:
214: class RuleDetailEditor extends XCellEditor {
215: OnLoadButton m_onLoadButton;
216: XCheckBox m_honorTransientToggle;
217: Label m_excludeRenderer;
218: boolean m_alwaysSelected;
219:
220: RuleDetailEditor(boolean alwaysSelected) {
221: super (new XCheckBox("Honor transient"));
222:
223: m_alwaysSelected = alwaysSelected;
224:
225: m_honorTransientToggle = (XCheckBox) m_editorComponent;
226: m_honorTransientToggle
227: .addActionListener(new ActionListener() {
228: public void actionPerformed(ActionEvent ae) {
229: boolean honor = m_honorTransientToggle
230: .isSelected();
231: int row = m_onLoadButton.getRow();
232: int col = m_onLoadButton.getCol();
233:
234: getIncludeRuleAt(row).setHonorTransient(
235: honor);
236: getRuleModel().fireTableCellUpdated(row,
237: col);
238: }
239: });
240: m_honorTransientToggle.setMargin(new Insets(0, 0, 0, 0));
241:
242: m_onLoadButton = new OnLoadButton("On load...");
243: m_onLoadButton.addActionListener(new ActionListener() {
244: public void actionPerformed(ActionEvent ae) {
245: getOnLoadDialog().edit(
246: getIncludeAt(m_onLoadButton.getRow()));
247: RuleTable.this .repaint();
248: }
249: });
250: m_editorComponent = new RuleDetailPanel(
251: m_honorTransientToggle, m_onLoadButton);
252: m_excludeRenderer = new Label("");
253:
254: m_clicksToStart = 1;
255: }
256:
257: public java.awt.Component getTableCellEditorComponent(
258: JTable table, Object value, boolean isSelected,
259: int row, int col) {
260: Rule rule = getRuleAt(row);
261:
262: if (m_alwaysSelected) {
263: isSelected = true;
264: }
265:
266: Color fg = isSelected ? table.getSelectionForeground()
267: : table.getForeground();
268: Color bg = isSelected ? table.getSelectionBackground()
269: : table.getBackground();
270:
271: if (rule.isIncludeRule()) {
272: Include include = getIncludeAt(row);
273:
274: m_onLoadButton.setCell(row, col);
275: m_onLoadButton.setForeground(table.getForeground());
276: m_onLoadButton.setBackground(table.getBackground());
277: m_onLoadButton.setFont(table.getFont());
278: m_onLoadButton.setToolTipText(buildToolTip(include));
279:
280: m_honorTransientToggle.setSelected(include
281: .getHonorTransient());
282: m_honorTransientToggle.setForeground(fg);
283: m_honorTransientToggle.setBackground(bg);
284: m_honorTransientToggle.setFont(table.getFont());
285: m_honorTransientToggle.setOpaque(true);
286:
287: m_editorComponent.setForeground(fg);
288: m_editorComponent.setBackground(bg);
289: m_editorComponent.setOpaque(true);
290:
291: m_editorComponent.setBorder(UIManager
292: .getBorder("Table.focusCellHighlightBorder"));
293:
294: return (java.awt.Component) m_editorComponent;
295: } else {
296: m_excludeRenderer.setForeground(fg);
297: m_excludeRenderer.setBackground(bg);
298: m_excludeRenderer.setOpaque(true);
299: m_excludeRenderer.setBorder(UIManager
300: .getBorder("Table.focusCellHighlightBorder"));
301:
302: return m_excludeRenderer;
303: }
304: }
305: }
306:
307: public RuleModel getRuleModel() {
308: return (RuleModel) getModel();
309: }
310:
311: public Include getIncludeAt(int row) {
312: return getIncludeRuleAt(row).getInclude();
313: }
314:
315: public IncludeRule getIncludeRuleAt(int row) {
316: return (IncludeRule) getRuleAt(row);
317: }
318:
319: public Rule getRuleAt(int row) {
320: return getRuleModel().getRuleAt(row);
321: }
322:
323: public void moveUp() {
324: int row = getSelectedRow();
325:
326: if (isEditing()) {
327: removeEditor();
328: }
329:
330: if (row > 0) {
331: getRuleModel().moveRuleUp(row--);
332: setRowSelectionInterval(row, row);
333: }
334: }
335:
336: class MoveUpAction extends XAbstractAction {
337: MoveUpAction() {
338: super ("Move up");
339: }
340:
341: public void actionPerformed(ActionEvent ae) {
342: moveUp();
343: }
344: }
345:
346: public void moveDown() {
347: int row = getSelectedRow();
348:
349: if (isEditing()) {
350: removeEditor();
351: }
352:
353: if (row != -1 && row < getRuleModel().getRowCount() - 1) {
354: getRuleModel().moveRuleDown(row++);
355: setRowSelectionInterval(row, row);
356: }
357: }
358:
359: class MoveDownAction extends XAbstractAction {
360: MoveDownAction() {
361: super ("Move down");
362: }
363:
364: public void actionPerformed(ActionEvent ae) {
365: moveDown();
366: }
367: }
368: }
369:
370: class RuleDetailPanel extends Container {
371: RuleDetailPanel(CheckBox checkBox, Button button) {
372: super ();
373:
374: String[] constraint1 = { "-1,left:ns", "-1,top:s", "1,left:n",
375: "-1,bottom:s", "n", "n" };
376: String[] constraint2 = { "0,right:n", "-1,top:s",
377: "-1,right:ns", "-1,bottom:s", "n", "n" };
378:
379: setLayout(new Layout());
380: add(checkBox, constraint1);
381: add(button, constraint2);
382:
383: setBorder(null);
384: }
385:
386: public String getToolTipText(MouseEvent event) {
387: setSize(-getX(), -getY());
388: setLocation(0, 0);
389: JComponent c = (JComponent) SwingUtilities
390: .getDeepestComponentAt(this , event.getX(), event.getY());
391: setLocation(-getWidth(), -getHeight());
392: setSize(0, 0);
393: return c != null ? c.getToolTipText() : null;
394: }
395: }
|