diff --git a/client/src/org/adempiere/apps/graph/BarGraph.java b/client/src/org/adempiere/apps/graph/BarGraph.java new file mode 100644 index 0000000000..74621f0e2c --- /dev/null +++ b/client/src/org/adempiere/apps/graph/BarGraph.java @@ -0,0 +1,523 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.util.*; +import java.util.logging.*; +import java.math.*; +import java.sql.*; + +import org.compiere.apps.*; +import org.compiere.model.*; +import org.compiere.swing.*; +import org.compiere.util.*; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartMouseEvent; +import org.jfree.chart.ChartMouseListener; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.entity.CategoryItemEntity; +import org.jfree.chart.entity.ChartEntity; +import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.category.BarRenderer; +import org.jfree.data.category.CategoryDataset; +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.DefaultValueDataset; + +/** + * Bar Graph + * + * @author Jorg Janke + * @version $Id: BarGraph.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ + */ +public class BarGraph extends CPanel implements ChartMouseListener //, ComponentListener //, ActionListener +{ + /** + * Constructor + */ + public BarGraph() + { + super(); + this.setLayout(new BorderLayout()); + } // BarGraph + + /** + * Constructor + * @param goal goal + */ + public BarGraph(MGoal goal) + { + this(); + m_goal = goal; + m_Y_AxisLabel = goal.getName(); + m_X_AxisLabel = goal.getXAxisText(); + loadData(); + //addComponentListener(this); + } // BarGraph + + /** The Goal */ + private MGoal m_goal = null; + /** Graph Size */ + //private Dimension m_size = null; + /** Zero/Zero Coordibate point */ + private Point m_point0_0 = null; + /** Layout */ + private BarGraphLayout m_layout = new BarGraphLayout(this); + + /** Logger */ + private static CLogger log = CLogger.getCLogger (BarGraph.class); + + /** X Axis Label */ + private String m_X_AxisLabel = "X Axis"; + /** Y Axis Label */ + private String m_Y_AxisLabel = "Y Axis"; + /** Y Axis Max */ + private double m_Y_Max = 0; + /** Y Axis Target Line */ + private double m_Y_Target = 0; + /** Y Axis Target Line Label */ + private String m_Y_TargetLabel = null; + private static Dimension paneldimension = new Dimension(180, 150); + + final DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + + /** + * Load Performance Data + */ + ArrayList list = new ArrayList(); + + private void loadData() + { + // Calculated + MMeasure measure = m_goal.getMeasure(); + if (measure == null) + { + log.warning("No Measure for " + m_goal); + return; + } + if (MMeasure.MEASURETYPE_Calculated.equals(measure.getMeasureType())) + { + MMeasureCalc mc = MMeasureCalc.get(Env.getCtx(), measure.getPA_MeasureCalc_ID()); + String sql = mc.getSqlBarChart(m_goal.getRestrictions(false), + m_goal.getMeasureDisplay(), null, + MRole.getDefault()); // logged in role + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + ResultSet rs = pstmt.executeQuery (); + ArrayList dataList = new ArrayList(); + while (rs.next ()) + { + BigDecimal data = rs.getBigDecimal(1); + Timestamp date = rs.getTimestamp(2); + BarGraphColumn bgc = new BarGraphColumn(mc, data); + bgc.setLabel(date, m_goal.getMeasureDisplay()); //TODO copy order-loop to other measures + int pos=0; + for (int i = 0; i < dataList.size(); i++) + if (dataList.get(i).before(date)) pos++; + dataList.add(date); // list of dates + list.add(pos, bgc); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + } + else if (MMeasure.MEASURETYPE_Achievements.equals(measure.getMeasureType())) + { + if (MMeasure.MEASUREDATATYPE_StatusQtyAmount.equals(measure.getMeasureDataType())) + { + MAchievement[] achievements = MAchievement.get(measure); + for (int i = 0; i < achievements.length; i++) + { + MAchievement achievement = achievements[i]; + BarGraphColumn bgc = new BarGraphColumn(achievement); + list.add(bgc); + } + } + else // MMeasure.MEASUREDATATYPE_QtyAmountInTime + { + String MeasureDisplay = m_goal.getMeasureDisplay(); + String trunc = "D"; + if (MGoal.MEASUREDISPLAY_Year.equals(MeasureDisplay)) + trunc = "Y"; + else if (MGoal.MEASUREDISPLAY_Quarter.equals(MeasureDisplay)) + trunc = "Q"; + else if (MGoal.MEASUREDISPLAY_Month.equals(MeasureDisplay)) + trunc = "MM"; + else if (MGoal.MEASUREDISPLAY_Week.equals(MeasureDisplay)) + trunc = "W"; + // else if (MGoal.MEASUREDISPLAY_Day.equals(MeasureDisplay)) + // trunc = "D"; + trunc = "TRUNC(DateDoc,'" + trunc + "')"; + StringBuffer sql = new StringBuffer ("SELECT SUM(ManualActual), ") + .append(trunc).append(" FROM PA_Achievement WHERE PA_Measure_ID=? AND IsAchieved='Y' ") + .append("GROUP BY ").append(trunc) + .append(" ORDER BY ").append(trunc); + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql.toString(), null); + pstmt.setInt(1, measure.getPA_Measure_ID()); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + BigDecimal data = rs.getBigDecimal(1); + Timestamp date = rs.getTimestamp(2); + BarGraphColumn bgc = new BarGraphColumn(m_goal, data); + bgc.setLabel(date, m_goal.getMeasureDisplay()); + list.add(bgc); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql.toString(), e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + } // Achievement in time + } // Achievement + + // Request + else if (MMeasure.MEASURETYPE_Request.equals(measure.getMeasureType())) + { + MRequestType rt = MRequestType.get(Env.getCtx(), measure.getR_RequestType_ID()); + String sql = rt.getSqlBarChart(m_goal.getRestrictions(false), + m_goal.getMeasureDisplay(), measure.getMeasureDataType(), + null, MRole.getDefault()); // logged in role + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + BigDecimal data = rs.getBigDecimal(1); + int R_Status_ID = rs.getInt(3); + BarGraphColumn bgc = new BarGraphColumn(rt, data, R_Status_ID); + if (R_Status_ID == 0) + { + Timestamp date = rs.getTimestamp(2); + bgc.setLabel(date, m_goal.getMeasureDisplay()); + } + else + { + MStatus status = MStatus.get(Env.getCtx(), R_Status_ID); + bgc.setLabel(status.getName()); + } + list.add(bgc); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + } // Request + + // Project + else if (MMeasure.MEASURETYPE_Project.equals(measure.getMeasureType())) + { + MProjectType pt = MProjectType.get(Env.getCtx(), measure.getC_ProjectType_ID()); + String sql = pt.getSqlBarChart(m_goal.getRestrictions(false), + m_goal.getMeasureDisplay(), measure.getMeasureDataType(), + null, MRole.getDefault()); // logged in role + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement (sql, null); + ResultSet rs = pstmt.executeQuery (); + while (rs.next ()) + { + BigDecimal data = rs.getBigDecimal(1); + Timestamp date = rs.getTimestamp(2); + int id = rs.getInt(3); + BarGraphColumn bgc = new BarGraphColumn(pt, data, id); + bgc.setLabel(date, m_goal.getMeasureDisplay()); + list.add(bgc); + } + rs.close (); + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + log.log (Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close (); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + } // Project + + // Add last 20 + int startValue = 0; + //if (list.size() > 20) //TODO CHECK + // startValue = list.size()-20; + /* + for (int i = startValue; i < list.size(); i++) + add (list.get(i)); + */ + for (int i = startValue; i < list.size(); i++){ + dataset.addValue(list.get(i).getValue(), list.get(i).getLabel(), list.get(i).getLabel()); + } + + // create the chart... + final JFreeChart chart = ChartFactory.createBarChart( + measure.getName(), // chart title + m_X_AxisLabel, // domain axis label + m_Y_AxisLabel, // range axis label + dataset, // data + PlotOrientation.VERTICAL, // orientation + false, // include legend + true, // tooltips? + true // URLs? + ); + + CategoryPlot plot = chart.getCategoryPlot(); + //plot.setBackgroundPaint(Color.lightGray); //GraphUtil.getForeground(getBackground()) + BarRenderer renderer = (BarRenderer) plot.getRenderer(); + chart.getCategoryPlot().setRenderer(renderer); + renderer.setSeriesPaint(0, new Color(92/255f, 178/255f, 232/255f)); + renderer.setSeriesPaint(1, new Color(56/255f, 97/255f, 119/255f)); + renderer.setSeriesPaint(2, new Color(242/255f, 70/255f, 78/255f)); + renderer.setSeriesPaint(3, Color.orange); + renderer.setSeriesPaint(4, new Color(147/255f, 196/255f, 51/255f)); + renderer.setSeriesPaint(5, new Color(210/255f, 247/255f, 91/255f)); + renderer.setSeriesPaint(6, new Color(129/255f, 235/255f, 249/255f)); + renderer.setSeriesPaint(7, new Color(60/255f, 84/255f, 8/255f)); + renderer.setSeriesPaint(8, new Color(0.8f, 0.8f, 0.8f)); + + chartPanel = new ChartPanel(chart); + chartPanel.setSize(getSize()); + chartPanel.addChartMouseListener(this); + add(chartPanel,BorderLayout.CENTER); + this.setMinimumSize(paneldimension); + } // loadData + private ChartPanel chartPanel; + /** + * Get Point 0_0 + * @return point + */ + public Point getPoint0_0() + { + return m_point0_0; + } // getPoint0_0 + + + /** + * @return Returns the x_AxisLabel. + */ + public String getX_AxisLabel () + { + return m_X_AxisLabel; + } // getX_AxisLabel + + /** + * @param axisLabel The x_AxisLabel to set. + */ + public void setX_AxisLabel (String axisLabel) + { + m_X_AxisLabel = axisLabel; + } // setX_AxisLabel + + /** + * @return Returns the y_AxisLabel. + */ + public String getY_AxisLabel () + { + return m_Y_AxisLabel; + } // getY_AxisLabel + + /** + * @param axisLabel The y_AxisLabel to set. + */ + public void setY_AxisLabel (String axisLabel) + { + m_Y_AxisLabel = axisLabel; + } // setY_AxisLabel + + /** + * @return Returns the y_TargetLabel. + */ + public String getY_TargetLabel () + { + return m_Y_TargetLabel; + } // getY_TargetLabel + + /** + * @param targetLabel The y_TargetLabel to set. + */ + public void setY_TargetLabel (String targetLabel, double target) + { + m_Y_TargetLabel = targetLabel; + m_Y_Target = target; + } // setY_TargetLabel + + + /** + * Add Column + * @param column column + */ + public void add (BarGraphColumn column) + { + super.add (column, "column"); + //column.addActionListener(this); + } // add + + + /************************************************************************** + * Paint Component + * @param g graphics + */ + + public void chartMouseClicked(ChartMouseEvent event){ + if ((event.getEntity()!=null) && (event.getTrigger().getClickCount() > 1)) { + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + BarGraphColumn bgc = null; + String eventUrl = event.getEntity().toString(); + for (int i = 0; i < list.size(); i++){ + if ( eventUrl.substring(eventUrl.length() - list.get(i).getLabel().length()).equals(list.get(i).getLabel())) + bgc = list.get(i); + } + if (null==bgc) return; + log.info(bgc.getName()); + MQuery query = null; + if (bgc.getAchievement() != null) // Single Achievement + { + MAchievement a = bgc.getAchievement(); + query = MQuery.getEqualQuery("PA_Measure_ID", a.getPA_Measure_ID()); + } + else if (bgc.getGoal() != null) // Multiple Achievements + { + MGoal goal = bgc.getGoal(); + query = MQuery.getEqualQuery("PA_Measure_ID", goal.getPA_Measure_ID()); + } + else if (bgc.getMeasureCalc() != null) // Document + { + MMeasureCalc mc = bgc.getMeasureCalc(); + query = mc.getQuery(m_goal.getRestrictions(false), + bgc.getMeasureDisplay(), bgc.getDate(), + MRole.getDefault()); // logged in role + } + else if (bgc.getProjectType() != null) // Document + { + MProjectType pt = bgc.getProjectType(); + query = pt.getQuery(m_goal.getRestrictions(false), + bgc.getMeasureDisplay(), bgc.getDate(), bgc.getID(), + MRole.getDefault()); // logged in role + } + else if (bgc.getRequestType() != null) // Document + { + MRequestType rt = bgc.getRequestType(); + query = rt.getQuery(m_goal.getRestrictions(false), + bgc.getMeasureDisplay(), bgc.getDate(), bgc.getID(), + MRole.getDefault()); // logged in role + } + if (query != null) + AEnv.zoom(query); + else + log.warning("Nothing to zoom to - " + bgc); + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + + public void chartMouseMoved(ChartMouseEvent event) {} + + public BarGraphColumn[] getBarGraphColumnList() { + BarGraphColumn[] array = new BarGraphColumn[list.size()]; + for (int i = 0; i < list.size(); i++){ + array[i] = list.get(i); + } + return array; + } + + /* + public void componentHidden(ComponentEvent e) { + // TODO Auto-generated method stub + + } + public void componentMoved(ComponentEvent e) { + // TODO Auto-generated method stub + + } + public void componentResized(ComponentEvent e) { + // TODO Auto-generated method stub + float aspectRatio = 1.6f; + Dimension size = getSize(); + if (size.width > size.height * aspectRatio) + chartPanel.setSize( new Dimension( + java.lang.Math.round(size.height*aspectRatio), + size.height)); + else + chartPanel.setSize(new Dimension( + size.width, + java.lang.Math.round(size.width / aspectRatio))); + } + public void componentShown(ComponentEvent e) { + // TODO Auto-generated method stub + } + */ +} // BarGraph diff --git a/client/src/org/adempiere/apps/graph/BarGraphColumn.java b/client/src/org/adempiere/apps/graph/BarGraphColumn.java new file mode 100644 index 0000000000..7a6bfd7be2 --- /dev/null +++ b/client/src/org/adempiere/apps/graph/BarGraphColumn.java @@ -0,0 +1,487 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import javax.swing.*; +import javax.swing.event.*; +import java.math.*; +import java.sql.*; +import java.text.*; + +import org.compiere.model.*; +import org.compiere.util.*; + +/** + * Bar Graph Column + * + * @author Jorg Janke + * @version $Id: BarGraphColumn.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ + */ +public class BarGraphColumn extends JComponent implements MouseListener +{ + /** + * Base Constructor + * @param label label + * @param value value + */ + public BarGraphColumn (String label, double value) + { + m_label = label; + setValue(value); + addMouseListener(this); + } // BarGraphColumn + + /** + * Single Achievement Constructor + * @param achievement achievement + */ + public BarGraphColumn (MAchievement achievement) + { + this (achievement.getName(), achievement.getManualActual().doubleValue()); + m_achievement = achievement; + } // BarGraphColumn + + /** + * Achievement Goal Constructor + * @param goal goal + * @param data count + */ + public BarGraphColumn (MGoal goal, BigDecimal data) + { + this ("", data == null ? 0 : data.doubleValue()); + m_goal = goal; + } // BarGraphColumn + + /** + * Measure Calc Constructor + * @param mc MeasureCalc + */ + public BarGraphColumn (MMeasureCalc mc, BigDecimal data) + { + this ("", data == null ? 0 : data.doubleValue()); + m_mc = mc; + } // BarGraphColumn + + /** + * Request Type Constructor + * @param rt Request Type + */ + public BarGraphColumn (MRequestType rt, BigDecimal data, int id) + { + this ("", data == null ? 0 : data.doubleValue()); + m_rt = rt; + m_id = id; + } // BarGraphColumn + + /** + * Project Type Constructor + * @param pt Procet Type + */ + public BarGraphColumn (MProjectType pt, BigDecimal data, int id) + { + this ("", data == null ? 0 : data.doubleValue()); + m_pt = pt; + m_id = id; + } // BarGraphColumn + + /** Optional Achievement */ + private MAchievement m_achievement = null; + /** Measure Calc */ + private MMeasureCalc m_mc = null; + /** Goal */ + private MGoal m_goal = null; + + private MRequestType m_rt = null; + private MProjectType m_pt = null; + private int m_id = 0; + + /** Display */ + private String m_measureDisplay = null; + private Timestamp m_date = null; + + /** Column Label */ + private String m_label = null; + /** Column Data Value */ + private double m_value = 0; + /** Column Label Value */ + private String m_labelValue = ""; + /** Column Data Target Value */ + private double m_targetValue = 0; + /** Column Width in pixles */ + private double m_width = 0; + /** Column Height in pixles */ + private double m_height = 0; + + /** Logger */ + private static CLogger log = CLogger.getCLogger (BarGraphColumn.class); + /** Integer Number Format */ + private static DecimalFormat s_format = DisplayType.getNumberFormat(DisplayType.Integer); + + /** + * Get Achievement Goal + * @return achievement or null + */ + public MGoal getGoal() + { + return m_goal; + } // getGoal + + + /** + * Get Single Achievement + * @return achievement or null + */ + public MAchievement getAchievement() + { + return m_achievement; + } // getAchievement + + /** + * Get MeasureCalc + * @return measure + */ + public MMeasureCalc getMeasureCalc() + { + return m_mc; + } // getMeasureCalc + + public MRequestType getRequestType() + { + return m_rt; + } + + public MProjectType getProjectType() + { + return m_pt; + } + + public String getMeasureDisplay() + { + return m_measureDisplay; + } // getMeasureDisplay + + public Timestamp getDate() + { + return m_date; + } // getDate + + public int getID() + { + return m_id; + } + + /** + * Set Background and matching Foreground + * @param bg background + */ + public void setBackground (Color bg) + { + super.setBackground (bg); + setForeground(GraphUtil.getForeground(bg)); + } // setBackground + + /** + * @return Returns the label. + */ + public String getLabel () + { + return m_label; + } // getLabel + + /** + * @param label The label to set. + */ + public void setLabel (String label) + { + m_label = label; + if (m_label != null) + m_labelValue = s_format.format(m_value) + " - " + m_label; + else + m_labelValue = s_format.format(m_value); + setToolTipText(m_labelValue); + setName(m_labelValue); + } // setLabel + + /** + * @param date for label. + * @param MeasureDisplay measure display + */ + public void setLabel (Timestamp date, String MeasureDisplay) + { + if (date == null) + return; + m_date = date; + m_measureDisplay = MeasureDisplay; + // + SimpleDateFormat format = DisplayType.getDateFormat(DisplayType.Date); + String text = format.format(date); + // Month only + if (MGoal.MEASUREDISPLAY_Month.equals(MeasureDisplay) + || MGoal.MEASUREDISPLAY_Quarter.equals(MeasureDisplay)) + { + String pattern = format.toPattern(); + String mmText = text; + int index = pattern.indexOf("dd"); + if (index == 0) // dd.MM.yyyy + mmText = text.substring(3); + else if (index > 0) // MM/dd/yyyy + { + mmText = text.substring(0, index-1); + if (text.length() > index+2) + mmText += text.substring(index+2); + } + setLabel(mmText); + } + else // Day + setLabel(text); + } // setLabel + + /** + * @return Returns the targetValue. + */ + public double getTargetValue () + { + return m_targetValue; + } // getTargetValue + + /** + * @param targetValue The targetValue to set. + */ + public void setTargetValue (double targetValue) + { + m_targetValue = targetValue; + } // setTargetValue + + /** + * @return Returns the data value. + */ + public double getValue () + { + return m_value; + } // getValue + + /** + * @param value The data value to set. + */ + public void setValue (double value) + { + m_value = value; + if (m_label != null) + m_labelValue = s_format.format(m_value) + " - " + m_label; + else + m_labelValue = s_format.format(m_value); + setToolTipText(m_labelValue); + setName(m_labelValue); + } // setValue + + /** + * @return Returns the column width in pixles. + */ + public double getColWidth () + { + return m_width; + } // getColWidth + + /** + * @param width The column width in pixles. + */ + public void setColWidth (double width) + { + m_width = width; + if (isPreferredSizeSet()) + setPreferredSize(null); + } // getColWidth + + /** + * @return Returns the height in pixles. + */ + public double getColHeight() + { + return m_height; + } // getHeight + + /** + * @param height The hight in pixles. + */ + public void setColHeight (double height) + { + m_height = height; + if (isPreferredSizeSet()) + setPreferredSize(null); + } // setHeight + + /** + * Get Maximum Size + * @return size + */ + public Dimension getMaximumSize () + { + return getPreferredSize(); + } // getMaximumSize + + /** + * Get Minimum Size + * @return size + */ + public Dimension getMinimumSize () + { + return getPreferredSize(); + } // getMinimumSize + + /** + * Get Preferred Size + * @return size + */ + public Dimension getPreferredSize () + { + if (!isPreferredSizeSet()) + { + Dimension size = new Dimension((int)m_width, (int)m_height); + setPreferredSize(size); + } + return super.getPreferredSize (); + } // getPreferredSize + + + /** + * Paint Component + * @param g graphics + */ + protected void paintComponent (Graphics g) + { + Graphics2D g2D = (Graphics2D)g; + Rectangle bounds = getBounds(); + // Background + g2D.setColor(getBackground()); + //Dimension size = getPreferredSize(); + Dimension size =getSize(); + System.out.println("bgc: " + size.width + " x " + size.height); + g2D.fill3DRect(0, 0, size.width, size.height, true); + + // Paint Label & Value + Color color = getForeground(); + g2D.setPaint(color); + // + Font font = getFont(); + FontMetrics fm = g2D.getFontMetrics(font); + int fontHeight = fm.getHeight(); + AffineTransform transform = AffineTransform.getRotateInstance(Math.PI*3/2); + font = font.deriveFont(transform); + g2D.setFont(font); + // + int x = (int)(size.width/2)+((fontHeight-2)/2); + if (x < fontHeight) + x = fontHeight-2; + int y = (int)(size.height-3); + g2D.drawString(m_labelValue, x, y); + log.finest("x=" + x + ",fontHeight=" + fontHeight + ", y=" + y + " - " + m_labelValue); + // Paint Target + if (m_targetValue != 0) + { + + } + } // paintComponent + + + /************************************************************************** + * Adds an ActionListener to the indicator. + * @param l the ActionListener to be added + */ + public void addActionListener(ActionListener l) + { + if (l != null) + listenerList.add(ActionListener.class, l); + } // addActionListener + + /** + * Removes an ActionListener from the indicator. + * @param l the listener to be removed + */ + public void removeActionListener(ActionListener l) + { + if (l != null) + listenerList.remove(ActionListener.class, l); + } // removeActionListener + + /** + * Returns an array of all the ActionListeners added + * to this indicator with addActionListener(). + * + * @return all of the ActionListeners added or an empty + * array if no listeners have been added + */ + public ActionListener[] getActionListeners() + { + return (ActionListener[])(listenerList.getListeners(ActionListener.class)); + } // getActionListeners + + /** + * Notifies all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created using the event + * parameter. + * + * @param event the ActionEvent object + * @see EventListenerList + */ + protected void fireActionPerformed(MouseEvent event) + { + // Guaranteed to return a non-null array + ActionListener[] listeners = getActionListeners(); + ActionEvent e = null; + // Process the listeners first to last + for (int i = 0; i < listeners.length; i++) + { + // Lazily create the event: + if (e == null) + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, + "column"+m_label, event.getWhen(), event.getModifiers()); + listeners[i].actionPerformed(e); + } + } // fireActionPerformed + + + /** + * Mouse Clicked + * @param e mouse event + */ + public void mouseClicked (MouseEvent e) + { + if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) + fireActionPerformed(e); + } // mouseClicked + + public void mousePressed (MouseEvent e) + { + } + + public void mouseReleased (MouseEvent e) + { + } + + public void mouseEntered (MouseEvent e) + { + } + + public void mouseExited (MouseEvent e) + { + } + +} // BarGraphColumn diff --git a/client/src/org/adempiere/apps/graph/BarGraphLayout.java b/client/src/org/adempiere/apps/graph/BarGraphLayout.java new file mode 100644 index 0000000000..922b8bfae5 --- /dev/null +++ b/client/src/org/adempiere/apps/graph/BarGraphLayout.java @@ -0,0 +1,156 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.*; +import java.util.*; + +import org.compiere.util.*; + +/** + * Bar Graph Layout + * + * @author Jorg Janke + * @version $Id: BarGraphLayout.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ + */ +public class BarGraphLayout + implements LayoutManager +{ + /** + * Bar Graph Layout + * @param parent parenr + */ + public BarGraphLayout (BarGraph parent) + { + m_parent = parent; + } // BarGraphLayout + + /** Parent Container */ + private BarGraph m_parent; + /** List of Components */ + private ArrayList m_list = new ArrayList(); + /** Layout Complete */ + private boolean m_layoutComplete = false; + /** Gap between columns */ + private static int XGAP = 2; + /** Gap to Axix */ + private static int YGAP = 1; + + /** Logger */ + private static CLogger log = CLogger.getCLogger (BarGraphLayout.class); + + /** + * Add Layout Component + * @param name name + * @param comp component + */ + public void addLayoutComponent (String name, Component comp) + { + if (comp instanceof BarGraphColumn) + m_list.add((BarGraphColumn)comp); + else + log.severe("Invalid Class: " + comp); + m_layoutComplete = false; + } // addLayoutComponent + + /** + * Remove Layout Component + * @param comp component + */ + public void removeLayoutComponent (Component comp) + { + m_list.remove(comp); + m_layoutComplete = false; + } // removeLayoutComponent + + /** + * Preferred Layout Size + * @param parent parent + * @return size + */ + public Dimension preferredLayoutSize (Container parent) + { + return parent.getPreferredSize(); + } // preferredLayoutSize + + /** + * Minimum Layout Size + * @param parent parent + * @return size + */ + public Dimension minimumLayoutSize (Container parent) + { + return parent.getMinimumSize(); + } // minimumLayoutSize + + + /** + * Layout Container + * @param parent + */ + public void layoutContainer (Container parent) + { + if (m_layoutComplete) + return; + + // Find Max + double maxValue = 0; + for (int i = 0; i < m_list.size(); i++) + { + BarGraphColumn column = m_list.get(i); + maxValue = Math.max(maxValue, column.getValue()); + } + // + //Dimension size = m_parent.getPreferredSize(); + Dimension size =m_parent.getSize(); + System.out.println("bgl: " +size.width + " x " + size.height); + + Point point0_0 = m_parent.getPoint0_0(); + + double graphHeight = size.height - (size.height-point0_0.y) - (2*YGAP); + double graphWidth = size.width - point0_0.x - XGAP; + double columnWidth = (graphWidth - (XGAP*m_list.size())) / m_list.size(); + columnWidth = Math.min(30, columnWidth); + FontMetrics fm = m_parent.getFontMetrics(m_parent.getFont()); + int fontHeight = fm.getHeight(); + columnWidth = Math.max(fontHeight, columnWidth); + + log.fine("Height=" + graphHeight + ", MaxValue=" + maxValue + + ", Width=" + graphWidth + ", ColumnWidth=" + columnWidth); + + int x = point0_0.x + (2*XGAP); + // Set Values + for (int i = 0; i < m_list.size(); i++) + { + BarGraphColumn column = m_list.get(i); + double multiplier = column.getValue() / maxValue; + double height = graphHeight * multiplier; + column.setColHeight(height); + column.setColWidth(columnWidth); + Dimension ps = column.getPreferredSize(); + column.setBackground(GraphUtil.getBackground(i)); + // + int y = point0_0.y - ps.height - YGAP; + column.setLocation(x, y); + column.setBounds(x, y, ps.width, ps.height); + x += ps.width + XGAP; + log.finer(i + " - " + ((int)(multiplier*100)) + "% - " + column.getBounds()); + } + m_layoutComplete = true; + } // layoutContainer + +} // BarGraphLayout diff --git a/client/src/org/adempiere/apps/graph/FCHtmlEditorKit.java b/client/src/org/adempiere/apps/graph/FCHtmlEditorKit.java new file mode 100644 index 0000000000..2e3a87db5b --- /dev/null +++ b/client/src/org/adempiere/apps/graph/FCHtmlEditorKit.java @@ -0,0 +1,90 @@ +package org.adempiere.apps.graph; + +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.text.html.*; +import java.awt.*; +import java.awt.image.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.SQLException; + +public class FCHtmlEditorKit extends HTMLEditorKit { + public ViewFactory getViewFactory() { + if (defaultFactory == null) { + defaultFactory = new FCHtmlFactory(super.getViewFactory()); + } + return defaultFactory; + } + + private static class FCHtmlFactory implements ViewFactory { + public FCHtmlFactory(ViewFactory factory) { + oldFactory = factory; + } + public View create(Element elem) { + View result; + result = oldFactory.create(elem); + if (result instanceof ImageView) { + String src = (String)elem.getAttributes(). + getAttribute(HTML.Attribute.SRC); + if ("res:".equals(src.substring(0, 4))) { + result = new NewImageView(elem); + } + } + return result; + } + private static class NewImageView extends ImageView { + Element elem; + public NewImageView(Element elem) { + super(elem); + this.elem=elem; + } + public Image getImage() { + //return smile image + //java.awt.Toolkit.getDefaultToolkit().getImage(getImageURL()).flush(); + //if (smileImage == null) { + String src = (String)elem.getAttributes(). + getAttribute(HTML.Attribute.SRC); + //System.out.println("img load: " + src.substring(4)); + URL url = getClass().getClassLoader(). + getResource(src.substring(4)); + //getResource("at/freecom/apps/images/freecom.gif"); + //getResource("javax/swing/text/html/icons/image-delayed.gif"); + if (url == null) return null; + smileImage = Toolkit.getDefaultToolkit().getImage(url); + if (smileImage==null) return null; + //forcing image to load synchronously + ImageIcon ii = new ImageIcon(); + ii.setImage(smileImage); + //} + return smileImage; + } + public URL getImageURL() { + // here we return url to some image. It might be any + // existing image. we need to move ImageView to the + // state where it thinks that image was loaded. + // ImageView is calling getImage to get image for + // measurement and painting when image was loaded + if (false) { + return getClass().getClassLoader(). + getResource("javax/swing/text/html/icons/image-delayed.gif"); + } else { + String src = (String)elem.getAttributes(). + getAttribute(HTML.Attribute.SRC); + //System.out.println("img load: " + src.substring(4)); + URL url = getClass().getClassLoader(). + getResource(src.substring(4)); + if (url != null) { + System.out.println("load image: " + url); + return url; + } + } + return null; + } + private static Image smileImage = null; + } + + private ViewFactory oldFactory; + } + private static ViewFactory defaultFactory = null; +} \ No newline at end of file diff --git a/client/src/org/adempiere/apps/graph/GraphUtil.java b/client/src/org/adempiere/apps/graph/GraphUtil.java new file mode 100644 index 0000000000..edb05d60f9 --- /dev/null +++ b/client/src/org/adempiere/apps/graph/GraphUtil.java @@ -0,0 +1,168 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.*; +import java.util.*; +import org.compiere.util.*; + +/** + * Graphic Utilities + * + * @author Jorg Janke + * @version $Id: GraphUtil.java,v 1.3 2006/07/30 00:51:28 jjanke Exp $ + */ +public class GraphUtil +{ + /** Logger */ + private static CLogger log = CLogger.getCLogger (GraphUtil.class); + + /** + * Get Foreground for back + * @param background back + * @return while or black + */ + public static Color getForeground (Color background) + { + if (background != null && isDark(background)) + return Color.white; + return Color.black; + } // getForeground + + /** + * Get Column Background + * @param index index + * @return random color + */ + public static Color getBackground (int index) + { + while (s_colors.size() <= index) + { + int rr = (index+1) * 47; + int gg = 100; + while (rr > 255) + { + rr -= 255; + gg += 50; + } + while (gg > 255) + gg -= 255; + s_colors.add(new Color(255-rr, gg, rr)); + } + return s_colors.get(index); + } // getBackGround + + /** List of Colors */ + private static ArrayList s_colors = new ArrayList(); + + + /** + * Is the Color dark? + * @param color color + * @return true if dark + */ + public static boolean isDark (Color color) + { + float r = color.getRed() / 255.0f; + float g = color.getGreen() / 255.0f; + float b = color.getBlue() / 255.0f; + double whiteDistance = colorDistance (r, g, b, 1.0, 1.0, 1.0); + double blackDistance = colorDistance (r, g, b, 0.0, 0.0, 0.0); + boolean dark = blackDistance < whiteDistance; + if (r+g+b == 1.0) + dark = false; + // log.info("r=" + r + ",g=" + g + ",b=" + b + " - black=" + blackDistance + // + (dark ? " ") + "white=" + whiteDistance + // + " - Alpha=" + color.getAlpha() + ", Trans=" + color.getTransparency()); + return dark; + } // isDark + + /** + * Is Color more white or black? + * @param r red + * @param g green + * @param b blue + * @return true if dark + */ + public static boolean isDark (double r, double g, double b) + { + double whiteDistance = colorDistance (r, g, b, 1.0, 1.0, 1.0); + double blackDistance = colorDistance (r, g, b, 0.0, 0.0, 0.0); + boolean dark = blackDistance < whiteDistance; + // log.finest("r=" + r + ",g=" + g + ",b=" + b + " - white=" + whiteDistance + ",black=" + blackDistance); + return dark; + } // isDark + + /** + * Simple Color Distance. + * (3d point distance) + * @param r1 first red + * @param g1 first green + * @param b1 first blue + * @param r2 second red + * @param g2 second green + * @param b2 second blue + * @return 3d distance for relative comparison + */ + public static double colorDistance (double r1, double g1, double b1, + double r2, double g2, double b2) + { + double a = (r2 - r1) + 0.1; + double b = (g2 - g1) + 0.1; + double c = (b2 - b1) + 0.1; + return Math.sqrt (a*a + b*b + c*c); + } // colorDistance + + + /** + * Get darker color + * @param color color + * @param factor factor 0..1 (AWT 0.7) the smaller, the darker + * @return darker color + */ + public static Color darker(Color color, double factor) + { + if (factor < 0.0) + factor = 0.7; + else if (factor > 1.0) + factor = 0.7; + return new Color( + Math.max((int)(color.getRed() * factor), 0), + Math.max((int)(color.getGreen() * factor), 0), + Math.max((int)(color.getBlue() * factor), 0)); + } // darker + + /** + * Get brighter color + * @param color color + * @param factor factor 0..1 (AWT 0.7) the smaller, the lighter + * @return brighter color + */ + public static Color brighter (Color color, double factor) + { + if (factor < 0.0) + factor = 0.7; + else if (factor > 1.0) + factor = 0.7; + + return new Color( + Math.min((int)(color.getRed() / factor), 255), + Math.min((int)(color.getGreen() / factor), 255), + Math.min((int)(color.getBlue() / factor), 255)); + } // brighter + +} // GraphUtil diff --git a/client/src/org/adempiere/apps/graph/HtmlDashboard.java b/client/src/org/adempiere/apps/graph/HtmlDashboard.java new file mode 100644 index 0000000000..3140ce0311 --- /dev/null +++ b/client/src/org/adempiere/apps/graph/HtmlDashboard.java @@ -0,0 +1,467 @@ +/** + * + */ +package org.adempiere.apps.graph; + +import javax.swing.JPanel; +import javax.swing.event.*; +import javax.swing.text.Document; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + +import javax.swing.JEditorPane; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +import org.compiere.model.MAchievement; +import org.compiere.model.MGoal; +import org.compiere.model.MMeasureCalc; +import org.compiere.model.MProjectType; +import org.compiere.model.MQuery; +import org.compiere.model.MRequestType; +import org.compiere.model.MRole; +import org.compiere.swing.CMenuItem; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Ini; +import org.compiere.util.Msg; + +import org.compiere.apps.AEnv; +import org.compiere.apps.AWindow; + +/** + * @author fcsku + * + */ +public class HtmlDashboard extends JPanel implements MouseListener, + ActionListener, HyperlinkListener { + + private static Dimension paneldimensionMin = new Dimension(80, 80); + private JEditorPane html; + private enum PAGE_TYPE {PAGE_HOME, PAGE_PERFORMANCE, PAGE_LOGO}; + private static CLogger log = CLogger.getCLogger (HtmlDashboard.class); + MGoal[] m_goals = null; + JPopupMenu popupMenu = new JPopupMenu(); + private CMenuItem mRefresh = new CMenuItem(Msg.getMsg(Env.getCtx(), "Refresh"), Env.getImageIcon("Refresh16.gif")); + URL lastUrl = null; + + + /** + * Constructor + */ + public HtmlDashboard(String url, MGoal[] m_goals, boolean scrolling) + { + super(); + //+param VTreePanel treePanel, + //this.treePanel = treePanel; + setName("test title"); + this.setLayout( new BorderLayout() ); + this.m_goals = m_goals; + // Create an HTML viewer + JEditorPane.registerEditorKitForContentType("text/html", "org.adempiere.apps.graph.FCHtmlEditorKit"); + html = new JEditorPane(); + html.setContentType("text/html"); + html.setEditable( false ); + htmlUpdate(url); + JScrollPane scrollPane = null; + if (scrolling) + scrollPane = new JScrollPane(); + else + scrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.getViewport().add( html, BorderLayout.CENTER ); + this.add( scrollPane, BorderLayout.CENTER ); + this.setMinimumSize(paneldimensionMin); + addMouseListener(this); + html.addHyperlinkListener( this ); + mRefresh.addActionListener(this); + popupMenu.add(mRefresh); + html.addMouseListener(this); + html.setBackground(getBackground()); + } + + public HtmlDashboard(String url) + { + new HtmlDashboard(url, null, true); + } + + private String createHTML(PAGE_TYPE requestPage){ + + String result = ""; + + // READ CSS + URL url = getClass().getClassLoader(). + getResource("org/compiere/images/PAPanel.css"); + InputStreamReader ins; + try { + ins = new InputStreamReader(url.openStream()); + BufferedReader bufferedReader = new BufferedReader( ins ); + String cssLine; + while ((cssLine = bufferedReader.readLine()) != null) + result += cssLine + "\n"; + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + //System.out.println(result); + switch (requestPage) { + case PAGE_LOGO: + result += "" + + "
" + + "" + + "" + //+ "" + + "
" + + ""; + break; + case PAGE_HOME: //************************************************************** + result += // "" + "
\n"; + queryZoom = null; + queryZoom = new ArrayList(); + String appendToHome = null; + String sql = " SELECT x.AD_CLIENT_ID, x.NAME, x.DESCRIPTION, x.AD_WINDOW_ID, x.PA_GOAL_ID, x.LINE, x.HTML, m.AD_MENU_ID" + + " FROM PA_DASHBOARDCONTENT x" + + " LEFT OUTER JOIN AD_MENU m ON x.ad_window_id=m.ad_window_id" + + " WHERE x.AD_Client_ID=0 OR x.AD_Client_ID=?" + + " ORDER BY LINE"; + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, Env.getAD_Client_ID(Env.getCtx())); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + appendToHome = rs.getString("HTML"); + if (appendToHome != null) { + if (rs.getString("DESCRIPTION") != null) + result += "

" + rs.getString("DESCRIPTION") + "

\n"; + result += stripHtml(appendToHome, false) + "
\n"; + } + + if (rs.getInt("AD_MENU_ID") > 0) { + result += "" + + rs.getString("DESCRIPTION") + + "
\n"); + } + result += "
\n"; + //result += "table id: " + rs.getInt("AD_TABLE_ID"); + if (rs.getInt("PA_GOAL_ID") > 0) + result += goalsDetail(rs.getInt("PA_GOAL_ID")); + //result += goalsDetail(rs.getInt("AD_TABLE_ID")); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + System.out.println("dashboard: " + e); //TODO catch-block + } + result += "


\n" + + "
\n\n\n"; + break; + default: //************************************************************** + System.out.println("error"); + } + //System.out.println(result); + return result; + } + + + ArrayList queryZoom = null; //new ArrayList(); + + private String goalsDetail(int AD_Table_ID) { //TODO link to goals + String output = ""; + if (m_goals==null) return output; + for (int i = 0; i < m_goals.length; i++) { + MMeasureCalc mc = MMeasureCalc.get(Env.getCtx(), m_goals[i].getMeasure().getPA_MeasureCalc_ID()); + if (AD_Table_ID == m_goals[i].getPA_Goal_ID()){// mc.getAD_Table_ID()) { + output += "\n\n"; + output += "\n"; + output += "\n"; + //if (mc.getTableName()!=null) output += "table: " + mc.getAD_Table_ID() + "
\n"; + BarGraph barPanel = new BarGraph(m_goals[i]); + BarGraphColumn[] bList = barPanel.getBarGraphColumnList(); + MQuery query = null; + output += "\n"; + for (int k=0; k0) output += ""; + if (bgc.getAchievement() != null) // Single Achievement + { + MAchievement a = bgc.getAchievement(); + query = MQuery.getEqualQuery("PA_Measure_ID", a.getPA_Measure_ID()); + } + else if (bgc.getGoal() != null) // Multiple Achievements + { + MGoal goal = bgc.getGoal(); + query = MQuery.getEqualQuery("PA_Measure_ID", goal.getPA_Measure_ID()); + } + else if (bgc.getMeasureCalc() != null) // Document + { + mc = bgc.getMeasureCalc(); + query = mc.getQuery(m_goals[i].getRestrictions(false), + bgc.getMeasureDisplay(), bgc.getDate(), + MRole.getDefault()); // logged in role + } + else if (bgc.getProjectType() != null) // Document + { + MProjectType pt = bgc.getProjectType(); + query = pt.getQuery(m_goals[i].getRestrictions(false), + bgc.getMeasureDisplay(), bgc.getDate(), bgc.getID(), + MRole.getDefault()); // logged in role + } + else if (bgc.getRequestType() != null) // Document + { + MRequestType rt = bgc.getRequestType(); + query = rt.getQuery(m_goals[i].getRestrictions(false), + bgc.getMeasureDisplay(), bgc.getDate(), bgc.getID(), + MRole.getDefault()); // logged in role + } + output += ""; + } + output += "" + + "" + + "
" + m_goals[i].getName() + "
Target" + m_goals[i].getMeasureTarget() + "
Actual" + m_goals[i].getMeasureActual() + "
" + m_goals[i].getXAxisText() + "
"+ bgc.getLabel() + ""; + if (query != null) { + output += "" + + bgc.getValue() + + "
\n"; + queryZoom.add(query); + } + else { + log.info("Nothing to zoom to - " + bgc); + output += bgc.getValue(); + } + output += "
" + + m_goals[i].getDescription() + + "
" + + stripHtml(m_goals[i].getColorSchema().getDescription(), true) + + "
\n"; + bList = null; + barPanel = null; + } + } + return output; + } + + private String stripHtml(String htmlString, boolean all) { + htmlString = htmlString + .replace("", "") + .replace("", "") + .replace("", "") + .replace("", "") + .replace("", "") + .replace("", ""); + + if (all) + htmlString = htmlString + .replace(">", ">") + .replace("<", "<"); + return htmlString; + } + private void htmlUpdate(String url) { + try { + htmlUpdate( new URL( url ) ); + } catch( MalformedURLException e ) { + System.out.println( "Malformed URL: " + e ); + } + } + + private void htmlUpdate(URL url) { + if ((url==null) || (url.getPath().equals("/local/home"))){ + html.setText(createHTML(PAGE_TYPE.PAGE_HOME)); + html.setCaretPosition(0); + lastUrl = url; + } + else if (url.getPath().equals("/local/logo")){ + html.setText(createHTML(PAGE_TYPE.PAGE_LOGO)); + html.setCaretPosition(0); + lastUrl = url; + } + else if (url.getPath().equals("/local/performance")){ + html.setText(createHTML(PAGE_TYPE.PAGE_PERFORMANCE)); + } + else if (url.getPath().equals("/window/node")){ + /* fcsku 3.7.07 + CButton button = new CButton(""); // Create the button + button.setActionCommand(String.valueOf(url.getRef())); //getNode_ID() + button.addActionListener(treePanel); //VTreePanel + //AEnv.zoom(130, 0); + html.setCursor(Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR )); + button.doClick(); + html.setCursor(Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR )); + */ + int AD_Window_ID=Integer.parseInt(url.getRef()); + AWindow frame = new AWindow(); + if (!frame.initWindow(AD_Window_ID, null))//MQuery.getEqualQuery(TableName + "_ID", Record_ID))) + return; + AEnv.addToWindowManager(frame); + if (Ini.isPropertyBool(Ini.P_OPEN_WINDOW_MAXIMIZED)) + { + AEnv.showMaximized(frame); + } + else + { + AEnv.showCenterScreen(frame); + } + frame = null; + html.setCursor(Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR )); + } + else if (url.getPath().equals("/window/zoom")){ + int index = Integer.parseInt(String.valueOf(url.getRef())); + if ((index >= 0) && (index < queryZoom.size())) { + html.setCursor(Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR )); + AEnv.zoom(queryZoom.get(index)); + html.setCursor(Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR )); + } + } + else if (url != null){ + // Load some cursors + Cursor cursor = html.getCursor(); + html.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) ); + SwingUtilities.invokeLater( new PageLoader( html, url, cursor ) ); + lastUrl = url; + } + } + + + public void hyperlinkUpdate( HyperlinkEvent event ) + { + if( event.getEventType() == HyperlinkEvent.EventType.ACTIVATED ) + { + //System.out.println("parsed url: " + event.getURL());// +" from: " +event.getDescription()); + htmlUpdate(event.getURL()); + } + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) + */ + public void mouseClicked(MouseEvent e) { + // TODO Auto-generated method stub + if (SwingUtilities.isRightMouseButton(e)) + popupMenu.show((Component)e.getSource(), e.getX(), e.getY()); + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) + */ + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) + */ + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) + */ + public void mousePressed(MouseEvent e) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) + */ + public void mouseReleased(MouseEvent e) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent e) { + // TODO Auto-generated method stub + if (e.getSource() == mRefresh) + { + if (m_goals != null) + for (int i=0; i < m_goals.length; i++) + m_goals[i].updateGoal(true); + htmlUpdate(lastUrl); + Container parent = getParent(); + if (parent != null) + parent.invalidate(); + invalidate(); + if (parent != null) + parent.repaint(); + else + repaint(); + } + } + + class PageLoader implements Runnable + { + private JEditorPane html; + private URL url; + private Cursor cursor; + + PageLoader( JEditorPane html, URL url, Cursor cursor ) + { + this.html = html; + this.url = url; + this.cursor = cursor; + } + + public void run() + { + if( url == null ) + { + // restore the original cursor + html.setCursor( cursor ); + + // PENDING(prinz) remove this hack when + // automatic validation is activated. + Container parent = html.getParent(); + parent.repaint(); + } + else + { + Document doc = html.getDocument(); + try { + html.setPage( url ); + } + catch( IOException ioe ) + { + html.setDocument( doc ); + } + finally + { + // schedule the cursor to revert after + // the paint has happended. + url = null; + SwingUtilities.invokeLater( this ); + } + } + } + } +} diff --git a/client/src/org/adempiere/apps/graph/PAPanel.java b/client/src/org/adempiere/apps/graph/PAPanel.java new file mode 100644 index 0000000000..29cacf20e7 --- /dev/null +++ b/client/src/org/adempiere/apps/graph/PAPanel.java @@ -0,0 +1,175 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.*; + +import javax.swing.*; + +import org.compiere.model.*; +import org.compiere.swing.*; +import org.compiere.util.*; + +/** + * Performance Analysis Panel. + * Key Performace Indicators + * + * @author Jorg Janke + * @version $Id: PAPanel.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ + */ +public class PAPanel extends CPanel implements ActionListener +{ + /** + * Get Panel if User has Perfpormance Goals + * @return panel pr null + */ + public static PAPanel get() + { + int AD_User_ID = Env.getAD_User_ID(Env.getCtx()); + MGoal[] goals = MGoal.getUserGoals(Env.getCtx(), AD_User_ID); + if (goals.length == 0) + return null; + return new PAPanel(goals); + } // get + + + /************************************************************************** + * Constructor + * @param goals + */ + private PAPanel (MGoal[] goals) + { + super (); + m_goals = goals; + init(); + } // PAPanel + + /** Goals */ + private MGoal[] m_goals = null; + + /** Logger */ + private static CLogger log = CLogger.getCLogger (PAPanel.class); + + /** + * Static/Dynamic Init + */ + private void init() + { + /* BOXES: + * + * boxV Header + * ******** + * boxH + * + * boxH * * * + * * boxV1 * boxV2 * + * * * * + * + * boxV1 dial1 + * ******** + * dial2 + * + * boxV2 HTML + * ******** + * boxH1 + * + * boxH1 * * * + * * bar1 * bar2 * + * * * * + * + * + * V1 + HTML in scrollpane + */ + + this.setLayout(new BorderLayout()); + + // HEADER + Box boxV = Box.createVerticalBox(); + // DIALS/HTML+Bars + Box boxH = Box.createHorizontalBox(); + // DIALS + Box boxV1 = Box.createVerticalBox(); + // HTML/Bars + Box boxV2 = Box.createVerticalBox(); + // barChart + Box boxH1 = Box.createHorizontalBox(); + //boxH_V.setPreferredSize(new Dimension(180, 1500)); + //boxH1.setPreferredSize(new Dimension(400, 180)); + boxV2.setPreferredSize(new Dimension(120, 120)); + + // DIALS below HEADER, LEFT + for (int i = 0; i < m_goals.length; i++) + { + PerformanceIndicator pi = new PerformanceIndicator(m_goals[i]); + pi.addActionListener(this); + boxV1.add (pi, BorderLayout.NORTH); + } + boxV1.add(Box.createVerticalGlue(), BorderLayout.CENTER); + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.getViewport().add(boxV1, BorderLayout.CENTER ); + scrollPane.setMinimumSize(new Dimension(190, 180)); + + // RIGHT, HTML + Bars + HtmlDashboard contentHtml = new HtmlDashboard("http:///local/home", m_goals, true); + boxV2.add(contentHtml, BorderLayout.CENTER); + + for (int i = 0; i < java.lang.Math.min(2, m_goals.length); i++) + { + if (m_goals[i].getMeasure() != null) //MGoal goal = pi.getGoal(); + boxH1.add ( new BarGraph(m_goals[i]), BorderLayout.SOUTH); + } + boxV2.add(boxH1, BorderLayout.SOUTH); + + // below HEADER + boxH.add(scrollPane, BorderLayout.WEST ); + boxH.add(Box.createHorizontalStrut(5)); //space + boxH.add(boxV2, BorderLayout.CENTER); + + // HEADER + below + HtmlDashboard t = new HtmlDashboard("http:///local/logo", null, false); + t.setMaximumSize(new Dimension(2000,80)); + //t.setPreferredSize(new Dimension(200,10)); + //t.setMaximumSize(new Dimension(2000,10)); + boxV.add(t, BorderLayout.NORTH); + boxV.add(Box.createVerticalStrut(5)); //space + boxV.add(boxH, BorderLayout.CENTER); + boxV.add(Box.createVerticalGlue()); + + // WINDOW + add(boxV, BorderLayout.CENTER); + } // init + + /** + * Action Listener for Drill Down + * @param e event + */ + public void actionPerformed (ActionEvent e) + { + if (e.getSource() instanceof PerformanceIndicator) + { + PerformanceIndicator pi = (PerformanceIndicator)e.getSource(); + log.info(pi.getName()); + MGoal goal = pi.getGoal(); + if (goal.getMeasure() != null) + new PerformanceDetail(goal); + } + } // actionPerformed + +} // PAPanel diff --git a/client/src/org/adempiere/apps/graph/PerformanceDetail.java b/client/src/org/adempiere/apps/graph/PerformanceDetail.java new file mode 100644 index 0000000000..da0e5e70b4 --- /dev/null +++ b/client/src/org/adempiere/apps/graph/PerformanceDetail.java @@ -0,0 +1,75 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.*; +import java.awt.event.*; + +import org.compiere.*; +import org.compiere.apps.*; +import org.compiere.swing.*; +import org.compiere.model.*; + + +/** + * Performance Detail Frame. + * BarPanel for Drill-Down + * + * @author Jorg Janke + * @version $Id: PerformanceDetail.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ + */ +public class PerformanceDetail extends CFrame + implements ActionListener +{ + /** + * Constructor. + * Called from PAPanel, ViewPI (Performance Indicator) + * @param goal goal + */ + public PerformanceDetail (MGoal goal) + { + super (goal.getName()); + setIconImage(Adempiere.getImage16()); + barPanel = new BarGraph(goal); + init(); + AEnv.showCenterScreen(this); + } // PerformanceDetail + + BarGraph barPanel = null; + ConfirmPanel confirmPanel = new ConfirmPanel(); + + /** + * Static init + */ + private void init() + { + getContentPane().add(barPanel, BorderLayout.CENTER); + getContentPane().add(confirmPanel, BorderLayout.SOUTH); + confirmPanel.addActionListener(this); + } // init + + /** + * Action Listener + * @param e event + */ + public void actionPerformed (ActionEvent e) + { + if (e.getActionCommand().equals(ConfirmPanel.A_OK)) + dispose(); + } // actionPerformed + +} // PerformanceDetail diff --git a/client/src/org/adempiere/apps/graph/PerformanceIndicator.java b/client/src/org/adempiere/apps/graph/PerformanceIndicator.java new file mode 100644 index 0000000000..76a321353a --- /dev/null +++ b/client/src/org/adempiere/apps/graph/PerformanceIndicator.java @@ -0,0 +1,358 @@ +/****************************************************************************** + * Product: Adempiere ERP & CRM Smart Business Solution * + * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program 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 General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + * For the text or an alternative of this public license, you may reach us * + * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * + * or via info@compiere.org or http://www.compiere.org/license.html * + *****************************************************************************/ +package org.adempiere.apps.graph; + +import java.awt.*; +import java.awt.event.*; +import java.awt.font.*; +import java.text.*; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; + +//vpj-cd e-evolution +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.Font; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +//import java.awt.R`; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.*; +import org.jfree.data.general.*; +import org.jfree.data.Range; +import org.jfree.ui.RectangleInsets; +//vpj-cd e-evolution + +import org.compiere.model.*; +import org.compiere.swing.*; +import org.compiere.util.*; +import org.compiere.apps.graph.*; +import java.net.*; +import java.io.*; +import org.jfree.chart.ChartUtilities; + +/** + * Performance Indicator + * + * @author Jorg Janke + * @version $Id: PerformanceIndicator.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ + */ +//vpj-cd e-evolution public class PerformanceIndicator extends JComponent +public class PerformanceIndicator extends JPanel + implements MouseListener, ActionListener +{ + /** + * Constructor + * @param goal goal model + */ + public PerformanceIndicator(MGoal goal) + { + super(); + m_goal = goal; + setName(m_goal.getName()); + //vpj-cd e-evolution getPreferredSize(); // calculate size + init(); + // + setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); + setOpaque(true); + //vpj-cd e-evolution updateDisplay(); + + // + mRefresh.addActionListener(this); + popupMenu.add(mRefresh); + // + addMouseListener(this); + } // PerformanceIndicator + + private MGoal m_goal = null; + /** The Performance Name */ + private String m_text = null; + /** Performance Line */ + private double m_line = 0; + + /** Height */ + private static double s_height = 45; + /** 100% width */ + private static double s_width100 = 150; + /** Max width */ + private static double s_widthMax = 250; + /** Integer Number Format */ + private static DecimalFormat s_format = DisplayType.getNumberFormat(DisplayType.Integer); + + JPopupMenu popupMenu = new JPopupMenu(); + private CMenuItem mRefresh = new CMenuItem(Msg.getMsg(Env.getCtx(), "Refresh"), Env.getImageIcon("Refresh16.gif")); + + //Insert Pie Graph Kinamo (pelgrim) + private static Color colorOK = Color.magenta; + private static Color colorNotOK = Color.lightGray; + private static Dimension indicatordimension = new Dimension(170,120); + private static Dimension paneldimension = new Dimension(180, 150); + ChartPanel chartPanel; + //private static Dimension + + /** + * Get Goal + * @return goal + */ + public MGoal getGoal() + { + return m_goal; + } // getGoal + + + private JFreeChart createChart(){ + JFreeChart chart = null; + + // Set Text + StringBuffer text = new StringBuffer(m_goal.getName()); + if (m_goal.isTarget()) + text.append(": ").append(m_goal.getPercent()).append("%"); + else + text.append(": ").append(s_format.format(m_goal.getMeasureActual())); + + m_text = text.toString(); + + // ToolTip + text = new StringBuffer(); + if (m_goal.getDescription() != null) + text.append(m_goal.getDescription()).append(": "); + text.append(s_format.format(m_goal.getMeasureActual())); + if (m_goal.isTarget()) + text.append(" ").append(Msg.getMsg(Env.getCtx(), "of")).append(" ") + .append(s_format.format(m_goal.getMeasureTarget())); + setToolTipText(text.toString()); + // + //setBackground(m_goal.getColor()); + setForeground(GraphUtil.getForeground(getBackground())); + // Performance Line + int percent = m_goal.getPercent(); + if (percent > 100) // draw 100% line + m_line = s_width100; + else // draw Performance Line + m_line = s_width100 * m_goal.getGoalPerformanceDouble(); + + + String title = m_text; + DefaultValueDataset data = new DefaultValueDataset((float)m_goal.getPercent()); + MeterPlot plot = new MeterPlot(data); + + MColorSchema colorSchema = m_goal.getColorSchema(); + int rangeLo = 0; int rangeHi=0; + for (int i=1; i<=4; i++){ + switch (i) { + case 1: rangeHi = colorSchema.getMark1Percent(); break; + case 2: rangeHi = colorSchema.getMark2Percent(); break; + case 3: rangeHi = colorSchema.getMark3Percent(); break; + case 4: rangeHi = colorSchema.getMark4Percent(); break; + } + if (rangeHi==9999) + rangeHi = (int) Math.floor(rangeLo*1.5); + if (rangeLo < rangeHi) { + plot.addInterval(new MeterInterval("Normal", //label + new Range(rangeLo, rangeHi), //range + colorSchema.getColor(rangeHi), + new BasicStroke(7.0f), + //Color.lightGray + new Color(-13091716) + //Color.gray + )); + rangeLo = rangeHi; + } + } + plot.setRange(new Range(0,rangeLo)); + + plot.setDialBackgroundPaint(new Color(-13091716));//Color.GRAY); + plot.setUnits(m_goal.getName()); + plot.setDialShape(DialShape.CHORD);//CIRCLE); + //plot.setDialBackgroundPaint(new GradientPaint(0, 0, m_goal.getColor(), 0, 1000, Color.black)); + plot.setNeedlePaint(Color.white); + plot.setTickSize(2000); + plot.setTickLabelFont(new Font("SansSerif", Font.BOLD, 12)); + plot.setTickLabelPaint(Color.white); + plot.setInsets(new RectangleInsets(1.0, 2.0, 3.0, 4.0)); + + chart = new JFreeChart( m_text, new Font("SansSerif", Font.BOLD, 15), plot,false); + + return chart; + } + /** + * Init Graph Display + * Kinamo (pelgrim) + */ + private void init() { + chartPanel = new ChartPanel(createChart(), //chart + false, //boolean properties + false, // boolean save + false, //boolean print + false, //boolean zoom + true //boolean tooltips + ); + chartPanel.setPreferredSize(indicatordimension); + + chartPanel.addChartMouseListener( new org.jfree.chart.ChartMouseListener() + { + public void chartMouseClicked(org.jfree.chart.ChartMouseEvent e) + { + //plot p = (MeterPlot) e.getSource(); + MouseEvent me = e.getTrigger(); + if (SwingUtilities.isLeftMouseButton(me) && me.getClickCount() > 1) + fireActionPerformed(me); + if (SwingUtilities.isRightMouseButton(me)) + popupMenu.show((Component)me.getSource(), me.getX(), me.getY()); + } + public void chartMouseMoved(org.jfree.chart.ChartMouseEvent e) + { + + } + }); + + this.add(chartPanel, BorderLayout.NORTH); + this.setMinimumSize(paneldimension); + this.setMaximumSize(paneldimension); + //--------------------------------------------- + + invalidate(); + } + + + /** + * Update Display Data + */ + protected void updateDisplay() + { + chartPanel.setChart(createChart()); + invalidate(); + + } // updateData + + /************************************************************************** + * Adds an ActionListener to the indicator. + * @param l the ActionListener to be added + */ + public void addActionListener(ActionListener l) + { + if (l != null) + listenerList.add(ActionListener.class, l); + } // addActionListener + + /** + * Removes an ActionListener from the indicator. + * @param l the listener to be removed + */ + public void removeActionListener(ActionListener l) + { + if (l != null) + listenerList.remove(ActionListener.class, l); + } // removeActionListener + + /** + * Returns an array of all the ActionListeners added + * to this indicator with addActionListener(). + * + * @return all of the ActionListeners added or an empty + * array if no listeners have been added + */ + public ActionListener[] getActionListeners() + { + return (ActionListener[])(listenerList.getListeners(ActionListener.class)); + } // getActionListeners + + /** + * Notifies all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created using the event + * parameter. + * + * @param event the ActionEvent object + * @see EventListenerList + */ + protected void fireActionPerformed(MouseEvent event) + { + // Guaranteed to return a non-null array + ActionListener[] listeners = getActionListeners(); + ActionEvent e = null; + // Process the listeners first to last + for (int i = 0; i < listeners.length; i++) + { + // Lazily create the event: + if (e == null) + e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, + "pi", event.getWhen(), event.getModifiers()); + listeners[i].actionPerformed(e); + } + } // fireActionPerformed + + + /************************************************************************** + * Mouse Clicked + * @param e mouse event + */ + public void mouseClicked (MouseEvent e) + { + if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) + fireActionPerformed(e); + if (SwingUtilities.isRightMouseButton(e)) + popupMenu.show((Component)e.getSource(), e.getX(), e.getY()); + } // mouseClicked + + public void mousePressed (MouseEvent e) + { + } + + public void mouseReleased (MouseEvent e) + { + } + + public void mouseEntered (MouseEvent e) + { + } + + public void mouseExited (MouseEvent e) + { + } + + /** + * Action Listener. + * Update Display + * @param e event + */ + public void actionPerformed (ActionEvent e) + { + if (e.getSource() == mRefresh) + { + m_goal.updateGoal(true); + updateDisplay(); + // + Container parent = getParent(); + if (parent != null) + parent.invalidate(); + invalidate(); + if (parent != null) + parent.repaint(); + else + repaint(); + } + } // actionPerformed + + + +} // PerformanceIndicator diff --git a/client/src/org/compiere/apps/AMenu.java b/client/src/org/compiere/apps/AMenu.java index 86347d4f6e..ac31206c69 100644 --- a/client/src/org/compiere/apps/AMenu.java +++ b/client/src/org/compiere/apps/AMenu.java @@ -29,7 +29,7 @@ import javax.swing.event.*; // import org.compiere.*; import org.compiere.apps.wf.*; -import org.compiere.apps.graph.*; +import org.adempiere.apps.graph.*; import org.compiere.db.*; import org.compiere.grid.tree.*; import org.compiere.model.*; diff --git a/client/src/org/compiere/images/PAPanel.css b/client/src/org/compiere/images/PAPanel.css new file mode 100644 index 0000000000..39d31a11ed --- /dev/null +++ b/client/src/org/compiere/images/PAPanel.css @@ -0,0 +1,53 @@ + \ No newline at end of file diff --git a/client/src/org/compiere/images/logo_ad.png b/client/src/org/compiere/images/logo_ad.png new file mode 100644 index 0000000000..a79ccb61ef Binary files /dev/null and b/client/src/org/compiere/images/logo_ad.png differ