/* =========================================================== * TradeManager : a application to trade strategies for the Java(tm) platform * =========================================================== * * (C) Copyright 2011-2011, by Simon Allen and Contributors. * * Project Info: org.trade * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Oracle, Inc. * in the United States and other countries.] * * (C) Copyright 2011-2011, by Simon Allen and Contributors. * * Original Author: Simon Allen; * Contributor(s): -; * * Changes * ------- * */ package org.trade.ui.base; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.awt.print.PrinterException; import java.io.File; import java.io.IOException; import java.util.Calendar; import javax.imageio.ImageIO; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import org.trade.core.util.TradingCalendar; import org.trade.core.valuetype.Date; import org.trade.core.valuetype.Decimal; import org.trade.core.valuetype.Decode; import org.trade.core.valuetype.Money; import org.trade.core.valuetype.Percent; import org.trade.core.valuetype.Quantity; import org.trade.core.valuetype.ValueTypeException; import org.trade.core.valuetype.YesNo; import org.trade.ui.widget.ColorEditor; import org.trade.ui.widget.ColorRenderer; import org.trade.ui.widget.DateEditor; import org.trade.ui.widget.DateField; import org.trade.ui.widget.DateRenderer; import org.trade.ui.widget.DecimalEditor; import org.trade.ui.widget.DecimalField; import org.trade.ui.widget.DecimalRenderer; import org.trade.ui.widget.DecodeTableRenderer; import org.trade.ui.widget.IntegerEditor; import org.trade.ui.widget.IntegerField; import org.trade.ui.widget.IntegerRenderer; import org.trade.ui.widget.MoneyEditor; import org.trade.ui.widget.MoneyField; import org.trade.ui.widget.MoneyRenderer; import org.trade.ui.widget.PercentEditor; import org.trade.ui.widget.PercentField; import org.trade.ui.widget.PercentRenderer; import org.trade.ui.widget.QuantityEditor; import org.trade.ui.widget.QuantityField; import org.trade.ui.widget.QuantityRenderer; import org.trade.ui.widget.StringEditor; import org.trade.ui.widget.StringField; import org.trade.ui.widget.StringRenderer; import org.trade.ui.widget.YesNoTableEditor; import org.trade.ui.widget.YesNoTableRenderer; /** * * @version $Id: ConfigProperties.java 1.0 2000/08/08 00:36:40Z Simon.Allen dev * $ * @author Simon Allen */ public class Table extends JTable implements MouseListener, ActionListener { private static final long serialVersionUID = -6753202830151175785L; private static final String DATEFORMAT = "MM/dd/yyyy"; private JPopupMenu popup = null; private boolean popupMenu = true; private String m_pngDefaultDir = null; /** * Constructor for Table. * * @param tableModel * TableModel * @throws ValueTypeException */ public Table(TableModel tableModel) throws ValueTypeException { super(tableModel); this.setAutoCreateRowSorter(true); int columns = this.getTableHeader().getColumnModel().getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn thc = this.getTableHeader().getColumnModel().getColumn(i); thc.setMinWidth((thc.getHeaderValue().toString().length() * 6) + 10); } DateRenderer rDate = new DateRenderer(DATEFORMAT); rDate.setHorizontalAlignment(SwingConstants.CENTER); DateEditor eDate = new DateEditor(new DateField(DATEFORMAT), new Date(TradingCalendar.getDateTimeNowMarketTimeZone()), DATEFORMAT, Calendar.DAY_OF_MONTH); MoneyRenderer rMoney = new MoneyRenderer(); MoneyEditor eMoney = new MoneyEditor(new MoneyField()); DecimalRenderer rDecimal = new DecimalRenderer(); DecimalEditor eDecimal = new DecimalEditor(new DecimalField(2)); PercentRenderer rPercent = new PercentRenderer(); PercentEditor ePercent = new PercentEditor(new PercentField()); StringEditor eString = new StringEditor(new StringField()); StringRenderer rString = new StringRenderer(); IntegerRenderer rInteger = new IntegerRenderer(); IntegerEditor eInteger = new IntegerEditor(new IntegerField()); QuantityRenderer rQuantity = new QuantityRenderer(); QuantityEditor eQuantity = new QuantityEditor(new QuantityField()); DecodeTableRenderer decodeRenderer = new DecodeTableRenderer(); YesNoTableEditor eYesNoEditor = new YesNoTableEditor(); YesNoTableRenderer rYesNoRenderer = new YesNoTableRenderer(); this.setDefaultRenderer(Color.class, new ColorRenderer(true)); this.setDefaultEditor(Color.class, new ColorEditor()); this.setDefaultRenderer(Date.class, rDate); this.setDefaultEditor(Date.class, eDate); this.setDefaultRenderer(Money.class, rMoney); this.setDefaultEditor(Money.class, eMoney); this.setDefaultRenderer(Decimal.class, rDecimal); this.setDefaultEditor(Decimal.class, eDecimal); this.setDefaultRenderer(Percent.class, rPercent); this.setDefaultEditor(Percent.class, ePercent); this.setDefaultRenderer(Integer.class, rInteger); this.setDefaultEditor(Integer.class, eInteger); this.setDefaultRenderer(Quantity.class, rQuantity); this.setDefaultEditor(Quantity.class, eQuantity); this.setDefaultRenderer(String.class, rString); this.setDefaultEditor(String.class, eString); this.setDefaultRenderer(Decode.class, decodeRenderer); this.setDefaultRenderer(YesNo.class, rYesNoRenderer); this.setDefaultEditor(YesNo.class, eYesNoEditor); this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); this.getTableHeader().setUpdateTableInRealTime(false); this.setRowSelectionAllowed(true); this.setColumnSelectionAllowed(false); this.addMouseListener(this); } /** * Enable popup menus to add/delete rows. * * * @param popupMenu * true or false. * */ public void enablePopupMenu(boolean popupMenu) { this.popupMenu = popupMenu; } /** * mousePressed() - * * @param evt * MouseEvent * @exception * * @see */ public void mousePressed(MouseEvent evt) { if (evt.isPopupTrigger()) { createPopup(evt.getPoint()); } } /** * mouseReleased() - * * @param evt * MouseEvent * @exception * * @see */ public void mouseReleased(MouseEvent evt) { if (evt.isPopupTrigger()) { createPopup(evt.getPoint()); } } /** * mouseClicked() - * * @param evt * MouseEvent * @exception * * @see */ public void mouseClicked(MouseEvent evt) { if (evt.isPopupTrigger()) { createPopup(evt.getPoint()); } } /** * mouseEntered() - * * @param evt * MouseEvent * @exception * * @see */ public void mouseEntered(MouseEvent evt) { } /** * mouseExited() - * * @param evt * MouseEvent * @exception * * @see */ public void mouseExited(MouseEvent evt) { } /** * Method createDefaultTableHeader. * * @return JTableHeader */ protected JTableHeader createDefaultTableHeader() { return new JTableHeader(columnModel) { private static final long serialVersionUID = -2667248411137081167L; public String getToolTipText(MouseEvent e) { java.awt.Point p = e.getPoint(); int index = columnModel.getColumnIndexAtX(p.x); if (index > -1) { int realIndex = columnModel.getColumn(index).getModelIndex(); return ((TableModel) this.getTable().getModel()).getColumnHeaderToolTip(realIndex); } return null; } }; } /** * createPopup() - * * @param point * Point * @exception * * @see */ public void createPopup(Point point) { popup = new JPopupMenu(); if (popupMenu) { JMenuItem addMenuItem = popup.add(new JMenuItem("Add")); addMenuItem.addActionListener(this); JMenuItem deleteMenuItem = popup.add(new JMenuItem("Delete")); deleteMenuItem.addActionListener(this); JMenuItem clearAllMenuItem = popup.add(new JMenuItem("ClearAll")); clearAllMenuItem.addActionListener(this); } JMenuItem printMenuItem = popup.add(new JMenuItem("Print")); printMenuItem.addActionListener(this); JMenuItem saveAsMenuItem = popup.add(new JMenuItem("Save As")); saveAsMenuItem.addActionListener(this); // Try to make the popup lightweight point = getSuitableLocation(point, popup.getPreferredSize(), this); popup.show(this, point.x, point.y); } /** * actionPerformed() - * * @param evt * ActionEvent * @exception * * @see */ public void actionPerformed(ActionEvent evt) { JMenuItem mi = (JMenuItem) evt.getSource(); if (mi.getActionCommand().equals("Delete")) { delete(); } else if (mi.getActionCommand().equals("Add")) { add(); } else if (mi.getActionCommand().equals("ClearAll")) { clearAll(); } else if (mi.getActionCommand().equals("Print")) { try { print(); } catch (PrinterException e) { // Do nothing ... } } else if (mi.getActionCommand().equals("Save As")) { try { saveAs(); } catch (IOException e) { // Do nothing ... } } } /** * getSuitableLocation() - * * @param point * Point * @param d * Dimension * @param c * Component * @return Point * @exception * @see */ protected Point getSuitableLocation(Point point, Dimension d, Component c) { // First locate the parent JFrame or JDialog Component topLevel = getComponentContainer(c); if (topLevel != null) { int newX; // New proposed x co-ordinate int newY; // New proposed y co-ordinate // We have a top-level parent Rectangle parentBounds = topLevel.getBounds(); // Parent bounds, // screen-relative // Get proposed location, relative to the screen SwingUtilities.convertPointToScreen(point, c); if ((point.x + d.width) > (parentBounds.x + parentBounds.width)) { // Popup overhangs to the right newX = (parentBounds.x + parentBounds.width) - d.width; } else { newX = point.x; } if ((point.y + d.height) > (parentBounds.y + parentBounds.height)) { // Popup ends below frame newY = (parentBounds.y + parentBounds.height) - d.height; } else { newY = point.y; } // Change location only if necessary AND if // we can make the popup fit inside the frame if ((newX >= 0) && (newY >= 0)) { point.x = newX; point.y = newY; } // Convert back to relative co-ordinates SwingUtilities.convertPointFromScreen(point, c); } return point; } /** * getComponentContainer() - * * @param c * Component * @return Component * @exception * @see */ private Component getComponentContainer(Component c) { Component topLevel = c; while ((topLevel != null) && !(topLevel instanceof JFrame) && !(topLevel instanceof JDialog)) { topLevel = topLevel.getParent(); } return topLevel; } /** * delete a row() - * * @exception * * @see */ public void delete() { if (this.getSelectedRow() > -1) { ((TableModel) this.getModel()).deleteRow(this.convertRowIndexToModel((this.getSelectedRow()))); } } /** * clear all rows() - * * @exception * * @see */ public void clearAll() { int rowCount = this.getRowCount(); for (int i = 0; i < rowCount; i++) { ((TableModel) this.getModel()).deleteRow(0); } } /** * print all rows() - * * @exception * * @see */ /** * add a row() - * * @param <B> * Component c </B> Returns the container of the component * @return Component * @exception @see */ public void add() { ((TableModel) this.getModel()).addRow(); } /** * saveAs - Save the image as a PNG * * @param <B> * Component c </B> Returns the container of the component * @return Component * @throws IOException * @exception @see */ private void saveAs() throws IOException { int width = Math.max(this.getWidth(), this.getTableHeader().getWidth()); int height = this.getHeight() + this.getTableHeader().getHeight(); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = bi.createGraphics(); this.getTableHeader().paint(g2); g2.translate(0, this.getTableHeader().getHeight()); this.paint(g2); g2.dispose(); ImageIO.write(bi, "png", new File(openFileChooser())); } /** * Method openFileChooser. * * @return String */ private String openFileChooser() { String fileName = null; ExampleFileFilter filter = new ExampleFileFilter(new String[] { "png" }, "PNG Files"); // Start in the curr dir if (null == m_pngDefaultDir) { m_pngDefaultDir = System.getProperty("user.dir"); } JFileChooser filer1 = new JFileChooser(m_pngDefaultDir); ExampleFileChooser fileView = new ExampleFileChooser(); filer1.setFileView(fileView); filer1.addChoosableFileFilter(filter); filer1.setFileFilter(filter); filer1.setAccessory(new FilePreviewer(filer1)); int returnVal = 0; returnVal = filer1.showSaveDialog(this); // Upon return, getFile() will be null if user cancelled the dialog. if (returnVal == JFileChooser.APPROVE_OPTION) { // Non-null file property after return implies user // selected a file to open. // Call openFile to attempt to load the text from file into TextArea if (filer1.getSelectedFile().exists()) { int result = JOptionPane.showConfirmDialog(getComponentContainer(this), "File Exists. Do you want to over write ?", "Warning", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { fileName = filer1.getSelectedFile().getPath(); } else { // cancel return null; } } else { fileName = filer1.getSelectedFile().getPath(); } if (!fileName.toUpperCase().endsWith(".PNG")) { return fileName + ".png"; } return fileName; } return null; } }