⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtab.java

📁 Java写的ERP系统
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
 * The contents of this file are subject to the   Compiere License  Version 1.1
 * ("License"); You may not use this file except in compliance with the License
 * You may obtain a copy of the License at http://www.compiere.org/license.html
 * Software distributed under the License is distributed on an  "AS IS"  basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * The Original Code is                  Compiere  ERP & CRM  Business Solution
 * The Initial Developer of the Original Code is Jorg Janke  and ComPiere, Inc.
 * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
 * created by ComPiere are Copyright (C) ComPiere, Inc.;   All Rights Reserved.
 * Contributor(s): ______________________________________.
 *****************************************************************************/
package org.compiere.model;

import java.sql.*;
import java.util.*;
import java.math.*;
import java.text.*;
import java.beans.*;
import java.io.*;

import org.compiere.util.ValueNamePair;
import org.compiere.util.*;

/**
 *	Tab Model.
 *  - a combination of AD_Tab (the display attributes) and AD_Table information.
 *  <p>
 *  The Tab owns also it's Table model
 *  and listens to data changes to update the Field values.
 *
 *  <p>
 *  The Tab maintains the bound property: CurrentRow
 *
 *  <pre>
 *  Event Hierarchies:
 *      - dataChanged (from MTable)
 *          - setCurrentRow
 *              - Update all Field Values
 *
 *      - setValue
 *          - Update Field Value
 *          - Callout
 *  </pre>
 *  @author 	Jorg Janke
 *  @version 	$Id: MTab.java,v 1.41 2003/04/30 06:24:22 jjanke Exp $
 */
public final class MTab implements DataStatusListener, Serializable
{
	/**
	 *	Create Tab (Model) from Value Object.
	 *  <p>
	 *  MTab provides a property listener for changed rows and a
	 *  DataStatusListener for communicating changes of the underlying data
	 *  @param vo Value Object
	 */
	public MTab(MTabVO vo)
	{
		m_vo = vo;
		//  Create MTable
		m_mTable = new MTable (m_vo.ctx, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true);
		m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView);
		m_mTable.setDeleteable(m_vo.IsDeleteable);
		//  Load Tab
	//	if (vo.TabNo == 0)
			initTab(false);
	//	else
	//	{
	//		m_loader = new Loader();
	//		m_loader.setPriority(Thread.MIN_PRIORITY);
	//		m_loader.start();
	//	}
	//	waitLoadCompete();
	}	//	M_Tab

	/** Value Object                    */
	private MTabVO          m_vo;

	/** The Table Model for Query   */
	private MTable          m_mTable = null;

	private String 			m_keyColumnName = "";
	private String 			m_linkColumnName = "";
	private String			m_extendedWhere;
	/** Attachments         */
	private HashMap 		m_Attachment = null;

	/** Current Row         */
	private int             m_currentRow = -1;

	/** Property Change     */
	private PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(this);
	/** Property Change Type    */
	public static final String  PROPERTY = "CurrentRow";

	private Vector          m_dataStatusListeners = null;
	private DataStatusEvent m_DataStatusEvent = null;
	//
	private MQuery 			m_query = new MQuery();
	private String 			m_oldQuery = "0=9";
	private String 			m_linkValue = "999999";

	/** Order By Array if SortNo 1..2   */
	private String[]	    m_OrderBys = new String[2];
	/** List of Key Parents     */
	private ArrayList	    m_parents = new ArrayList(2);

	/** Map of ColumnName of source field (key) and the dependent field (value) */
	private MultiMap            m_depOnField = new MultiMap();

	/** Async Loader            */
	private Loader              m_loader = null;
	/** Async Loading complete  */
	private volatile boolean    m_loadComplete = false;

	/*************************************************************************/

	/**
	 *  Tab loader for Tabs > 0
	 */
	class Loader extends Thread
	{
		/**
		 *  Async Loading of Tab > 0
		 */
		public void run()
		{
			initTab (true);
		}   //  run
	}   //  Loader

	/**
	 *  Wait until load is complete
	 */
	private void waitLoadCompete()
	{
		if (m_loadComplete)
			return;
		//
		m_loader.setPriority(Thread.NORM_PRIORITY);
		Log.trace(Log.l1_User, "MTab.waitLoadComplete");
		while (m_loader.isAlive())
		{
			try
			{
				Thread.sleep(100);     //  1/10 sec
			}
			catch (Exception e)
			{
				Log.error("MTab.waitLoadComplete", e);
			}
		}
		Log.trace(Log.l1_User, "MTab.waitLoadComplete - fini");
	}   //  waitLoadComplete

	/**
	 *	Initialize Tab with record from AD_Tab_v
	 *  @param async async
	 *	@return true, if correctly initialized (ignored)
	 */
	private boolean initTab (boolean async)
	{
		Log.trace(Log.l3_Util, "MTab.initTab #" + m_vo.TabNo + " - Async=" + async);

		m_extendedWhere = m_vo.WhereClause;


		//	Get Field Data
		if (!loadFields())
		{
			m_loadComplete = true;
			return false;
		}

		//  Order By
		m_mTable.setOrderClause(getOrderByClause(m_vo.onlyCurrentRows));

		if (async)
			Log.trace(Log.l3_Util, "MTab.initTab #" + m_vo.TabNo + " - Async=" + async, "fini");
		m_loadComplete = true;
		return true;
	}	//	initTab

	/**
	 *	Dispose - clean up resources
	 */
	protected void dispose()
	{
		Log.trace(Log.l3_Util, "MTab.dispose #" + m_vo.TabNo);
		m_OrderBys = null;
		//
		m_parents.clear();
		m_parents = null;
		//
		m_mTable.close (true);  //  also disposes Fields
		m_mTable = null;
		//
		m_depOnField.clear();
		m_depOnField = null;
		if (m_Attachment != null)
			m_Attachment.clear();
		m_Attachment = null;
		//
		m_vo.Fields.clear();
		m_vo.Fields = null;
		m_vo = null;
	}	//	dispose


	/**
	 *	Get Field data and add to MTable, if it's required or displayed.
	 *  Reqiored fields are keys, parents, or standard Columns
	 *  @return true if fields loaded
	 */
	private boolean loadFields()
	{
		Log.trace(Log.l3_Util, "MTab.loadFields #" + m_vo.TabNo);

		if (m_vo.Fields == null)
			return false;

		//  Add RowID if this is not a view
		if (!m_vo.IsView)
		{
			MField rowID = new MField (MFieldVO.createRowID (m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID));
			m_mTable.addField(rowID);
		}

		//  Add Fields
		for (int f = 0; f < m_vo.Fields.size(); f++)
		{
			MFieldVO voF = (MFieldVO)m_vo.Fields.get(f);
			//	Add Fields to Table
			if (voF != null)
			{
				MField field = new MField (voF);
				String columnName = field.getColumnName();
				//	Record Info
				if (field.isKey())
				{
					if (m_vo.IsView)     //  make it a RowID for selection & update
						voF.initRowID();
					m_keyColumnName = columnName;
				}
				//	Parent Column(s)
				if (field.isParent())
					m_parents.add(columnName);
				//	Order By
				if (field.getSortNo() == 1)
					m_OrderBys[0] = columnName;
				else if (field.getSortNo() == 2)
					m_OrderBys[1] = columnName;
					//  Add field
				m_mTable.addField(field);

				//  List of ColumnNames, this field is dependent on
				ArrayList list = field.getDependentOn();
				for (int i = 0; i < list.size(); i++)
					m_depOnField.put(list.get(i), field);   //  ColumnName, Field
				//  Add fields all fields are dependent on
				if (columnName.equals("IsActive") || columnName.equals("Processed"))
					m_depOnField.put(columnName, null);
			}
		}   //  for all fields

		//  Add Standard Fields
		if (m_mTable.getField("Created") == null)
		{
			MField created = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, true, true));
			m_mTable.addField(created);
		}
		if (m_mTable.getField("CreatedBy") == null)
		{
			MField createdBy = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, true, false));
			m_mTable.addField(createdBy);
		}
		if (m_mTable.getField("Updated") == null)
		{
			MField updated = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, false, true));
			m_mTable.addField(updated);
		}
		if (m_mTable.getField("UpdatedBy") == null)
		{
			MField updatedBy = new MField (MFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, false, false, false));
			m_mTable.addField(updatedBy);
		}
		return true;
	}	//	loadFields

	/**
	 *  Get TableModel.
	 *  <B>Do not directly communicate with the table model,
	 *  but through the methods of this class</B>
	 *  @return Table Model
	 */
	public MTable getTableModel()
	{
		return m_mTable;
	}   //  getTableModel

	/**
	 *  Get Tab Icon
	 *  @return Icon
	 */
	public javax.swing.Icon getIcon()
	{
		if (m_vo.AD_Image_ID == 0)
			return null;
		//
		/** @todo Load Image */
		return null;
	}   //  getIcon

	/*************************************************************************/

	/**
	 *  Has this field dependents ?
	 *  @param columnName column name
	 *  @return true if column has dependent
	 */
	public boolean isDependentOn (String columnName)
	{
	//	m_depOnField.printToLog();
		return m_depOnField.containsKey(columnName);
	}   //  isDependentOn

	/**
	 *  Get dependent fields of columnName
	 *  @param columnName column name
	 *  @return ArrayList with MFields dependent on columnName
	 */
	public ArrayList getDependentFieldList (String columnName)
	{
		return m_depOnField.getValues(columnName);
	}   //  getDependentFieldList

	/*************************************************************************/

	/**
	 *	Set Query
	 *  @param query query
	 */
	public void setQuery(MQuery query)
	{
		if (query == null)
			m_query = new MQuery();
		else
			m_query = query;
	}	//	setQuery

	/**
	 *	Get Query
	 *  @return query
	 */
	public MQuery getQuery()
	{
		return m_query;
	}	//	getQuery

	/**
	 *	Is Query Active
	 *  @return true if query active
	 */
	public boolean isQueryActive()
	{
		return m_query.isActive();
	}	//	isQueryActive

	/**
	 *  Enable Events - enable data events of tabs (add listeners)
	 */
	public void enableEvents()
	{
		//  Setup Events
		m_mTable.addDataStatusListener(this);
	//	m_mTable.addTableModelListener(this);
	}   //  enableEvents

	/**
	 *	Assemble whereClause and query MTable and position to row 0.
	 *  <pre>
	 *		Scenarios:
	 *		- Never opened 					(full query)
	 *		- query changed 				(full query)
	 *		- Detail link value changed		(full query)
	 *		- otherwise 					(refreshAll)
	 *  </pre>
	 *  @param onlyCurrentRows only current rows (1 day)
	 */
	public void query (boolean onlyCurrentRows)
	{
		query (onlyCurrentRows, 1);
	}	//	query

	/**
	 *	Assemble whereClause and query MTable and position to row 0.
	 *  <pre>
	 *		Scenarios:
	 *		- Never opened 					(full query)
	 *		- query changed 				(full query)
	 *		- Detail link value changed		(full query)
	 *		- otherwise 					(refreshAll)
	 *  </pre>
	 *  @param onlyCurrentRows only current rows
	 *  @param onlyCurrentDays if only current row, how many days back
	 */
	public void query (boolean onlyCurrentRows, int onlyCurrentDays)
	{
		Log.trace(Log.l3_Util, "MTab.query #" + m_vo.TabNo);
		//	is it same query?
		boolean refresh = m_oldQuery.equals(m_query.getWhereClause())
			&& m_vo.onlyCurrentRows == onlyCurrentRows && m_vo.onlyCurrentDays == onlyCurrentDays;
		m_oldQuery = m_query.getWhereClause();
		m_vo.onlyCurrentRows = onlyCurrentRows;
		m_vo.onlyCurrentDays = onlyCurrentDays;

		/**
		 *	Set Where Clause
		 */
		//	Tab Where Clause
		StringBuffer where = new StringBuffer(m_vo.WhereClause);
		//	Detail Query
		if (isDetail())
		{
			String lc = getLinkColumnName();
			if (lc.equals(""))
				Log.error("MTab.query - no link column");
			else
			{
				String value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc);
				//	Same link value?
				if (refresh)
					refresh = m_linkValue.equals(value);
				m_linkValue = value;
				//	Check validity
				if (value.length() == 0)
					Log.error("MTab.query - no value for link column " + lc);
				else
				{
					//	we have column and value
					if (where.length() != 0)
						where.append(" AND ");
					where.append(lc).append("=");
					if (lc.endsWith("_ID"))
						where.append(value);
					else
						where.append("'").append(value).append("'");
				}
			}
		}	//	isDetail

		m_extendedWhere = where.toString();

		//	Final Query
		if (m_query.isActive())
		{
			String q = validateQuery(m_query);
			if (q != null)
			{
				if (where.length() > 0 )
					where.append(" AND ");
				where.append(q);
			}
		}

		/**
		 *	Query
		 */
		if (m_mTable.isOpen())
		{
			if (refresh)
				m_mTable.dataRefreshAll();
			else
				m_mTable.dataRequery(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays);
		}
		else
		{
			m_mTable.setWhereClause(where.toString(), m_vo.onlyCurrentRows && !isDetail(), onlyCurrentDays);
			m_mTable.open();
		}
		//  Go to Record 0
		setCurrentRow(0, true);
	}	//	query

	/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -