001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.glm.execution.eg;
027:
028: import java.awt.BorderLayout;
029: import java.awt.Color;
030: import java.awt.Font;
031: import java.awt.Component;
032: import java.awt.Dimension;
033: import java.awt.event.ActionEvent;
034: import java.awt.event.ActionListener;
035: import java.text.NumberFormat;
036: import java.util.Date;
037: import javax.swing.Action;
038: import javax.swing.ListSelectionModel;
039: import javax.swing.JCheckBox;
040: import javax.swing.JComponent;
041: import javax.swing.JPanel;
042: import javax.swing.JButton;
043: import javax.swing.JScrollPane;
044: import javax.swing.JTable;
045: import javax.swing.JLabel;
046: import javax.swing.JToolBar;
047: import javax.swing.event.ListSelectionListener;
048: import javax.swing.event.ListSelectionEvent;
049: import javax.swing.event.TableModelEvent;
050: import javax.swing.table.DefaultTableCellRenderer;
051: import javax.swing.table.TableCellRenderer;
052: import javax.swing.table.TableModel;
053: import org.cougaar.util.TableSorter;
054:
055: /**
056: * This GUI displays information about the scheduled and actual
057: * reports. the display shows the actual or scheduled time for the
058: * report, the item identity, and amount (if actual).
059: **/
060: public class ReportManagerGUI extends JPanel {
061: public static final Color EDITED_COLOR = Color.red;
062: public static final Color NORMAL_COLOR = Color.black;
063: public static final Color ODD_ROW_BACKGROUND = Color.white;
064: public static final Color EVEN_ROW_BACKGROUND = new Color(240, 255,
065: 240);
066: public static final Color MARKED_CELL_BACKGROUND = new Color(150,
067: 200, 255);
068:
069: protected JToolBar toolBar = new JToolBar();
070: protected JCheckBox autoSend = new JCheckBox("Auto Send");
071: protected JCheckBox autoSendInvisible = new JCheckBox(
072: "Auto Send Invisible");
073: protected ManagerBase theManager;
074:
075: private static class MyTable extends JTable {
076: public MyTable(TableModel model) {
077: super (model);
078: DefaultTableCellRenderer numberRenderer = new DefaultTableCellRenderer() {
079: NumberFormat doubleFormatter = NumberFormat
080: .getInstance();
081: NumberFormat otherFormatter = NumberFormat
082: .getInstance();
083:
084: public void setValue(Object value) {
085: if (value instanceof Double) {
086: double d = ((Double) value).doubleValue();
087: setHorizontalAlignment(JLabel.RIGHT);
088: if (Math.floor(d) == d) {
089: doubleFormatter.setMinimumFractionDigits(0);
090: doubleFormatter.setMaximumFractionDigits(0);
091: setText(doubleFormatter.format(value)
092: + ". ");
093: } else {
094: doubleFormatter.setMinimumFractionDigits(3);
095: doubleFormatter.setMaximumFractionDigits(3);
096: setText(doubleFormatter.format(value));
097: }
098: } else if (value instanceof Number) {
099: setHorizontalAlignment(JLabel.RIGHT);
100: setText(otherFormatter.format(value));
101: } else if (value instanceof Date) {
102: setText((value == null) ? "" : EGDate
103: .format((Date) value));
104: } else {
105: setHorizontalAlignment(JLabel.LEFT);
106: setText((value == null ? "" : value.toString()));
107: }
108: }
109: };
110: numberRenderer.setHorizontalAlignment(JLabel.RIGHT);
111: setDefaultRenderer(Number.class, numberRenderer);
112: setDefaultRenderer(Object.class, numberRenderer);
113: setDefaultRenderer(String.class, numberRenderer);
114: setDefaultRenderer(Date.class, numberRenderer);
115: setDefaultRenderer(EGDate.class, numberRenderer);
116: }
117:
118: public void setDefaultRenderer(Class columnClass,
119: TableCellRenderer renderer) {
120: super .setDefaultRenderer(columnClass, new RendererWrapper(
121: renderer));
122: }
123: }
124:
125: private static Font defaultFont = null;
126: private static Font numberFont = null;
127: private static Font firstNumberFont = null;
128: private static Font firstFont = null;
129:
130: public static Font getDefaultFont() {
131: if (defaultFont == null)
132: defaultFont = new JTable().getFont();
133: return defaultFont;
134: }
135:
136: public static Font getFirstFont() {
137: if (firstFont == null) {
138: firstFont = new Font(getDefaultFont().getName(), Font.BOLD,
139: getDefaultFont().getSize());
140: }
141: return firstFont;
142: }
143:
144: public static Font getNumberFont() {
145: if (numberFont == null) {
146: numberFont = new Font("Monospaced", Font.PLAIN,
147: getDefaultFont().getSize());
148: }
149: return numberFont;
150: }
151:
152: public static Font getFirstNumberFont() {
153: if (firstNumberFont == null) {
154: firstNumberFont = new Font("Monospaced", Font.BOLD,
155: getDefaultFont().getSize());
156: }
157: return firstNumberFont;
158: }
159:
160: private static class RendererWrapper implements TableCellRenderer {
161: private TableCellRenderer renderer;
162:
163: public RendererWrapper(TableCellRenderer renderer) {
164: this .renderer = renderer;
165: }
166:
167: public Component getTableCellRendererComponent(JTable table,
168: Object value, boolean isSelected, boolean hasFocus,
169: int row, int column) {
170: JComponent result = (JComponent) renderer
171: .getTableCellRendererComponent(table, value,
172: isSelected, hasFocus, row, column);
173: EGTableModel model = (EGTableModel) table.getModel();
174: boolean isFirst = model.cellIsFirst(row, column);
175: if (value instanceof Number) {
176: if (isFirst) {
177: result.setFont(getFirstNumberFont());
178: } else {
179: result.setFont(getNumberFont());
180: }
181: } else {
182: if (isFirst) {
183: result.setFont(getFirstFont());
184: }
185: }
186: if (model.cellHasBeenEdited(row, column)) {
187: result.setForeground(EDITED_COLOR);
188: } else {
189: result.setForeground(NORMAL_COLOR);
190: }
191: if (model.cellIsMarked(row, column)) {
192: result.setBackground(MARKED_CELL_BACKGROUND);
193: } else if (((row / 5) & 1) == 0) {
194: result.setBackground(EVEN_ROW_BACKGROUND);
195: } else {
196: result.setBackground(ODD_ROW_BACKGROUND);
197: }
198: result.setToolTipText(model.getToolTipText(row, column));
199: return result;
200: }
201: }
202:
203: private static class MyTableSorter extends TableSorter implements
204: EGTableModel {
205: public MyTableSorter(EGTableModel model) {
206: super (model);
207: }
208:
209: public int getPreferredColumnWidth(int col) {
210: return ((EGTableModel) model).getPreferredColumnWidth(col);
211: }
212:
213: public int getMinColumnWidth(int col) {
214: return ((EGTableModel) model).getMinColumnWidth(col);
215: }
216:
217: public int getMaxColumnWidth(int col) {
218: return ((EGTableModel) model).getMaxColumnWidth(col);
219: }
220:
221: public String getToolTipText(int row, int col) {
222: return ((EGTableModel) model).getToolTipText(row, col);
223: }
224:
225: public boolean cellHasBeenEdited(int row, int col) {
226: return ((EGTableModel) model).cellHasBeenEdited(row, col);
227: }
228:
229: public boolean cellIsMarked(int row, int col) {
230: return ((EGTableModel) model).cellIsMarked(row, col);
231: }
232:
233: public boolean cellIsFirst(int row, int col) {
234: if (row == 0)
235: return true;
236: Object this Value = getValueAt(row, col);
237: if (this Value == null)
238: return true;
239: Object prevValue = getValueAt(row - 1, col);
240: if (prevValue == null)
241: return true;
242: return !this Value.equals(prevValue);
243: }
244:
245: public void fireTableDataChanged() {
246: ((EGTableModel) model).fireTableDataChanged();
247: }
248:
249: public void cellSelectionChanged(int row, int column) {
250: ((EGTableModel) model).cellSelectionChanged(row, column);
251: }
252:
253: public int compareRowsByColumn(int row1, int row2, int column) {
254: return ((EGTableModel) model).compareRowsByColumn(row1,
255: row2, column);
256: }
257:
258: public void tableChanged(TableModelEvent e) {
259: super .tableChanged(e);
260: sort(e.getSource());
261: }
262: }
263:
264: public ReportManagerGUI(final EGTableModel tableModel,
265: ManagerBase aManager) {
266: super (new BorderLayout());
267: theManager = aManager;
268: ActionListener autoSendListener = new ActionListener() {
269: public void actionPerformed(ActionEvent e) {
270: if (autoSendInvisible.isSelected()) {
271: new Thread("Deferred advanceTime") {
272: public void run() {
273: theManager.advanceTime();
274: }
275: }.start();
276: }
277: }
278: };
279:
280: autoSend
281: .setToolTipText("Automatically send reports when report time is due");
282: autoSend.addActionListener(autoSendListener);
283: addToToolBar(autoSend);
284:
285: autoSendInvisible
286: .setToolTipText("Send undisplayed (filtered out) reports when due");
287: autoSendInvisible.addActionListener(autoSendListener);
288: addToToolBar(autoSendInvisible);
289:
290: add(toolBar, BorderLayout.NORTH);
291: // final MyTableSorter tableSorter = new MyTableSorter(tableModel);
292: // final JTable table = new MyTable(tableSorter);
293: // tableSorter.addMouseListenerToHeaderInTable(table);
294: final JTable table = new MyTable(tableModel);
295: table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
296: table.setCellSelectionEnabled(true);
297: table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
298: ListSelectionListener l = new ListSelectionListener() {
299: public void valueChanged(ListSelectionEvent e) {
300: if (e.getValueIsAdjusting())
301: return;
302: int row = e.getFirstIndex();
303: if (row != -1) {
304: tableModel.cellSelectionChanged(row, table
305: .getSelectedColumn());
306: }
307: }
308: };
309: table.getSelectionModel().addListSelectionListener(l);
310: table.getColumnModel().getSelectionModel()
311: .addListSelectionListener(l);
312: int totalPreferredWidth = 0;
313: for (int col = 0, ncols = tableModel.getColumnCount(); col < ncols; col++) {
314: table.getColumnModel().getColumn(col).setMinWidth(
315: tableModel.getMinColumnWidth(col));
316: table.getColumnModel().getColumn(col).setMaxWidth(
317: tableModel.getMaxColumnWidth(col));
318: int preferredWidth = tableModel
319: .getPreferredColumnWidth(col);
320: table.getColumnModel().getColumn(col).setPreferredWidth(
321: preferredWidth);
322: totalPreferredWidth += preferredWidth;
323: }
324: table.setPreferredScrollableViewportSize(new Dimension(table
325: .getPreferredSize().width, table
326: .getPreferredScrollableViewportSize().height));
327: JScrollPane pane = new JScrollPane(table);
328: pane
329: .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
330: add(pane);
331: }
332:
333: public boolean isAutoSend() {
334: return autoSend.isSelected();
335: }
336:
337: public void setAutoSend(boolean newAutoSend) {
338: autoSend.setSelected(newAutoSend);
339: }
340:
341: public boolean isAutoSendInvisible() {
342: return autoSendInvisible.isSelected();
343: }
344:
345: public void setAutoSendInvisible(boolean newAutoSendInvisible) {
346: autoSendInvisible.setSelected(newAutoSendInvisible);
347: }
348:
349: public JButton addToToolBar(Action action) {
350: return toolBar.add(action);
351: }
352:
353: public void addToToolBar(Component component) {
354: toolBar.add(component);
355: }
356: }
|