/******************************************************************************
* Copyright (C) 2008 Low Heng Sin *
* 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. *
*****************************************************************************/
package org.adempiere.webui.apps.wf;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import org.compiere.apps.wf.WFLine;
import org.compiere.util.CLogger;
import org.compiere.wf.MWorkflow;
/**
*
* @author Low Heng Sin
*
*/
public class WFNodeContainer
{
/**
* WFContentPanel
*/
public WFNodeContainer ()
{
} // WFContentPanel
/** Logger */
private static CLogger log = CLogger.getCLogger(WFNodeContainer.class);
/** Node List */
private ArrayList<WFNode> m_nodes = new ArrayList<WFNode>();
/** Line List */
private ArrayList<WFLine> m_lines = new ArrayList<WFLine>();
/** The Workflow */
private MWorkflow m_wf = null;
/**
* Set Workflow
* @param wf workflow
*/
public void setWorkflow (MWorkflow wf)
{
m_wf = wf;
} // setWorkflow
/**
* Remove All and their listeners
*/
public void removeAll ()
{
m_nodes.clear();
m_lines.clear();
} // removeAll
/**
* Add Component and add Mouse Listener
* @param comp component
* @return component
*/
public void add (WFNode node)
{
m_nodes.add(node);
} // add
/**
*
* @param line
*/
public void add(WFLine line)
{
m_lines.add(line);
}
/**
* Create Lines.
* Called by WF Layout Manager
*/
protected void createLines()
{
log.fine("Lines #" + m_lines.size());
for (int i = 0; i < m_lines.size(); i++)
{
WFLine line = (WFLine)m_lines.get(i);
Rectangle from = findBounds (line.getAD_WF_Node_ID());
Rectangle to = findBounds (line.getAD_WF_Next_ID());
line.setFromTo(from, to);
// same bounds as parent
// line.setBounds(0,0, width, height);
} // for all lines
}
/**
* Get Bounds of WF Node Icon
* @param AD_WF_Node_ID node id
* @return bounds of node with ID or null
*/
private Rectangle findBounds (int AD_WF_Node_ID)
{
for (int i = 0; i < m_nodes.size(); i++)
{
WFNode node = (WFNode)m_nodes.get(i);
if (node.getAD_WF_Node_ID() == AD_WF_Node_ID)
return node.getBounds();
}
return null;
} // findBounds
public Dimension getDimension()
{
if (needLayout())
updateLayout();
int width = 0;
int height = 0;
// Go through all node
for (int i = 0; i < m_nodes.size(); i++)
{
WFNode node = m_nodes.get(i);
Rectangle rect = node.getBounds();
if (rect.x + rect.width > width)
width = rect.x + rect.width;
if (rect.y + rect.height > height)
height = rect.y + rect.height;
} // for all components
return new Dimension(width, height);
}
/**************************************************************************
* Paint Component.
* Paint Lines directly as not added.
* @param g graphics
*/
public void paint(Graphics2D g)
{
for (int i = 0; i < m_nodes.size(); i++)
{
WFNode node = m_nodes.get(i);
Rectangle rect = node.getBounds();
g.setColor(Color.BLACK);
g.drawRect(rect.x, rect.y, rect.width, rect.height);
Graphics2D t = (Graphics2D) g.create(rect.x, rect.y, rect.width, rect.height);
node.paint(t);
t.dispose();
} // for all components
createLines();
// Paint Lines
for (int i = 0; i < m_lines.size(); i++)
{
WFLine line = (WFLine)m_lines.get(i);
line.paint(g);
}
} // paint
private void updateLayout() {
int x = 5;
int y = 5;for (int i = 0; i < m_nodes.size(); i++)
{
WFNode node = m_nodes.get(i);
Rectangle rect = node.getBounds();
node.setBounds(x, y, rect.width, rect.height);
// next pos
if (x == 5)
x = 230;
else
{
x = 5;
y += 100;
}
}
}
/**
* Need Layout
* @param parent parent
* @return true if we need to layout
*/
private boolean needLayout ()
{
// Go through all components
for (int i = 0; i < m_nodes.size(); i++)
{
WFNode node = m_nodes.get(i);
Rectangle rect = node.getBounds();
if (rect.x == 0 && rect.y == 0)
{
return true;
}
}
return false;
} // needLayout
public ArrayList<WFNode> getNodes() {
return m_nodes;
}
} // WFContentPanel