- implement virtual mode for high volume table for enhance scalability
This commit is contained in:
Heng Sin Low 2009-12-14 04:51:20 +00:00
parent 8d11fd5139
commit cfa4c6c050
4 changed files with 328 additions and 65 deletions

View File

@ -99,10 +99,11 @@ import org.compiere.util.ValueNamePair;
*/ */
public class GridTab implements DataStatusListener, Evaluatee, Serializable public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
/** /**
* *
*/ */
private static final long serialVersionUID = -5882167959482156252L; private static final long serialVersionUID = 7198494041906579986L;
public static final String DEFAULT_STATUS_MESSAGE = "NavigateOrUpdate"; public static final String DEFAULT_STATUS_MESSAGE = "NavigateOrUpdate";
@ -112,13 +113,28 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
* MTab provides a property listener for changed rows and a * MTab provides a property listener for changed rows and a
* DataStatusListener for communicating changes of the underlying data * DataStatusListener for communicating changes of the underlying data
* @param vo Value Object * @param vo Value Object
* @param w
*/ */
public GridTab(GridTabVO vo, GridWindow w) public GridTab(GridTabVO vo, GridWindow w)
{
this(vo, w, false);
}
/**
* 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
* @param w
* @param virtual
*/
public GridTab(GridTabVO vo, GridWindow w, boolean virtual)
{ {
m_window = w; m_window = w;
m_vo = vo; m_vo = vo;
// Create MTable // Create MTable
m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true); m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true, virtual);
m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView); m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView);
m_mTable.setDeleteable(m_vo.IsDeleteable); m_mTable.setDeleteable(m_vo.IsDeleteable);
// Load Tab // Load Tab
@ -637,7 +653,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), lc, true); value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), lc, true);
if (value == null || value.length() == 0) if (value == null || value.length() == 0)
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc, true); // back compatibility value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc, true); // back compatibility
} }
// Same link value? // Same link value?
if (refresh) if (refresh)
@ -3055,11 +3071,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
int parentLevel = currentLevel-1; int parentLevel = currentLevel-1;
if (parentLevel < 0) if (parentLevel < 0)
return tabNo; return tabNo;
while (parentLevel != currentLevel) while (parentLevel != currentLevel)
{ {
tabNo--; tabNo--;
currentLevel = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, tabNo, GridTab.CTX_TabLevel); currentLevel = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, tabNo, GridTab.CTX_TabLevel);
} }
return tabNo; return tabNo;
} }
} // GridTab } // GridTab

View File

@ -30,6 +30,9 @@ import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
@ -85,7 +88,7 @@ public class GridTable extends AbstractTableModel
/** /**
* *
*/ */
private static final long serialVersionUID = 4273775926021737068L; private static final long serialVersionUID = 6148998589248950598L;
/** /**
* JDBC Based Buffered Table * JDBC Based Buffered Table
@ -99,6 +102,23 @@ public class GridTable extends AbstractTableModel
*/ */
public GridTable(Properties ctx, int AD_Table_ID, String TableName, int WindowNo, int TabNo, public GridTable(Properties ctx, int AD_Table_ID, String TableName, int WindowNo, int TabNo,
boolean withAccessControl) boolean withAccessControl)
{
this(ctx, AD_Table_ID, TableName, WindowNo, TabNo, withAccessControl, false);
}
/**
* JDBC Based Buffered Table
*
* @param ctx Properties
* @param AD_Table_ID table id
* @param TableName table name
* @param WindowNo window no
* @param TabNo tab no
* @param withAccessControl if true adds AD_Client/Org restrictuins
* @param virtual use virtual table mode if table is mark as high volume
*/
public GridTable(Properties ctx, int AD_Table_ID, String TableName, int WindowNo, int TabNo,
boolean withAccessControl, boolean virtual)
{ {
super(); super();
log.info(TableName); log.info(TableName);
@ -108,6 +128,7 @@ public class GridTable extends AbstractTableModel
m_WindowNo = WindowNo; m_WindowNo = WindowNo;
m_TabNo = TabNo; m_TabNo = TabNo;
m_withAccessControl = withAccessControl; m_withAccessControl = withAccessControl;
m_virtual = virtual && MTable.get(ctx, AD_Table_ID).isHighVolume();
} // MTable } // MTable
private static CLogger log = CLogger.getCLogger(GridTable.class.getName()); private static CLogger log = CLogger.getCLogger(GridTable.class.getName());
@ -120,6 +141,11 @@ public class GridTable extends AbstractTableModel
private boolean m_withAccessControl; private boolean m_withAccessControl;
private boolean m_readOnly = true; private boolean m_readOnly = true;
private boolean m_deleteable = true; private boolean m_deleteable = true;
//virtual table state variables
private boolean m_virtual;
private int m_cacheStart;
private int m_cacheEnd;
public static final String CTX_KeyColumnName = "KeyColumnName";
// //
/** Rowcount */ /** Rowcount */
@ -296,7 +322,7 @@ public class GridTable extends AbstractTableModel
select.append(" FROM ").append(m_tableName); select.append(" FROM ").append(m_tableName);
m_SQL_Select = select.toString(); m_SQL_Select = select.toString();
m_SQL_Count = "SELECT COUNT(*) FROM " + m_tableName; m_SQL_Count = "SELECT COUNT(*) FROM " + m_tableName;
//BF [ 2910358 ] //BF [ 2910358 ]
//Restore the Original Value for Key Column Name based in Tab Context Value //Restore the Original Value for Key Column Name based in Tab Context Value
int parentTabNo = getParentTabNo(); int parentTabNo = getParentTabNo();
String parentKey = Env.getContext(m_ctx, m_WindowNo, parentTabNo, GridTab.CTX_KeyColumnName, true); String parentKey = Env.getContext(m_ctx, m_WindowNo, parentTabNo, GridTab.CTX_KeyColumnName, true);
@ -304,8 +330,8 @@ public class GridTable extends AbstractTableModel
String currKey = Env.getContext(m_ctx, m_WindowNo, parentKey); String currKey = Env.getContext(m_ctx, m_WindowNo, parentKey);
if (valueKey != null && valueKey.length() > 0 && parentKey != null && parentKey.length() > 0 && ! currKey.equals(valueKey)) if (valueKey != null && valueKey.length() > 0 && parentKey != null && parentKey.length() > 0 && ! currKey.equals(valueKey))
{ {
Env.setContext(m_ctx, m_WindowNo, parentKey, valueKey); Env.setContext(m_ctx, m_WindowNo, parentKey, valueKey);
} }
StringBuffer where = new StringBuffer(""); StringBuffer where = new StringBuffer("");
// WHERE // WHERE
@ -356,7 +382,9 @@ public class GridTable extends AbstractTableModel
// ORDER BY // ORDER BY
if (!m_orderClause.equals("")) if (!m_orderClause.equals(""))
{
m_SQL += " ORDER BY " + m_orderClause; m_SQL += " ORDER BY " + m_orderClause;
}
// //
log.fine(m_SQL_Count); log.fine(m_SQL_Count);
Env.setContext(m_ctx, m_WindowNo, m_TabNo, GridTab.CTX_SQL, m_SQL); Env.setContext(m_ctx, m_WindowNo, m_TabNo, GridTab.CTX_SQL, m_SQL);
@ -538,6 +566,11 @@ public class GridTable extends AbstractTableModel
return true; return true;
} }
if (m_virtual)
{
verifyVirtual();
}
// create m_SQL and m_countSQL // create m_SQL and m_countSQL
createSelectSql(); createSelectSql();
if (m_SQL == null || m_SQL.equals("")) if (m_SQL == null || m_SQL.equals(""))
@ -549,10 +582,19 @@ public class GridTable extends AbstractTableModel
// Start Loading // Start Loading
m_loader = new Loader(); m_loader = new Loader();
m_rowCount = m_loader.open(maxRows); m_rowCount = m_loader.open(maxRows);
m_buffer = new ArrayList<Object[]>(m_rowCount+10); if (m_virtual)
m_buffer = new ArrayList<Object[]>(210);
else
m_buffer = new ArrayList<Object[]>(m_rowCount+10);
m_sort = new ArrayList<MSort>(m_rowCount+10); m_sort = new ArrayList<MSort>(m_rowCount+10);
m_cacheStart = m_cacheEnd = -1;
if (m_rowCount > 0) if (m_rowCount > 0)
m_loader.start(); {
if (m_rowCount < 1000)
m_loader.run();
else
m_loader.start();
}
else else
m_loader.close(); m_loader.close();
m_open = true; m_open = true;
@ -563,6 +605,24 @@ public class GridTable extends AbstractTableModel
return true; return true;
} // open } // open
private void verifyVirtual()
{
if (m_indexKeyColumn == -1)
{
m_virtual = false;
return;
}
GridField[] fields = getFields();
for(int i = 0; i < fields.length; i++)
{
if (fields[i].isKey() && i != m_indexKeyColumn)
{
m_virtual = false;
return;
}
}
}
/** /**
* Wait until async loader of Table and Lookup Fields is complete * Wait until async loader of Table and Lookup Fields is complete
* Used for performance tests * Used for performance tests
@ -659,6 +719,8 @@ public class GridTable extends AbstractTableModel
m_sort.clear(); m_sort.clear();
m_sort = null; m_sort = null;
m_cacheStart = m_cacheEnd = -1;
if (finalCall) if (finalCall)
dispose(); dispose();
@ -778,7 +840,7 @@ public class GridTable extends AbstractTableModel
for (int i = 0; i < m_sort.size(); i++) for (int i = 0; i < m_sort.size(); i++)
{ {
MSort sort = (MSort)m_sort.get(i); MSort sort = (MSort)m_sort.get(i);
Object[] rowData = (Object[])m_buffer.get(sort.index); Object[] rowData = getDataAtRow(i);
if (rowData[col] == null) if (rowData[col] == null)
sort.data = null; sort.data = null;
else if (isLookup || isASI) else if (isLookup || isASI)
@ -792,6 +854,17 @@ public class GridTable extends AbstractTableModel
MSort sort = new MSort(0, null); MSort sort = new MSort(0, null);
sort.setSortAsc(ascending); sort.setSortAsc(ascending);
Collections.sort(m_sort, sort); Collections.sort(m_sort, sort);
if (m_virtual)
{
m_buffer.clear();
m_cacheStart = m_cacheEnd = -1;
//release sort memory
for (int i = 0; i < m_sort.size(); i++)
{
m_sort.get(i).data = null;
}
}
// update UI // update UI
fireTableDataChanged(); fireTableDataChanged();
// Info detected by MTab.dataStatusChanged and current row set to 0 // Info detected by MTab.dataStatusChanged and current row set to 0
@ -852,9 +925,9 @@ public class GridTable extends AbstractTableModel
// need to wait for data read into buffer // need to wait for data read into buffer
int loops = 0; int loops = 0;
while (row >= m_buffer.size() && m_loader.isAlive() && loops < 15) while (row >= m_sort.size() && m_loader.isAlive() && loops < 15)
{ {
log.fine("Waiting for loader row=" + row + ", size=" + m_buffer.size()); log.fine("Waiting for loader row=" + row + ", size=" + m_sort.size());
try try
{ {
Thread.sleep(500); // 1/2 second Thread.sleep(500); // 1/2 second
@ -865,15 +938,14 @@ public class GridTable extends AbstractTableModel
} }
// empty buffer // empty buffer
if (row >= m_buffer.size()) if (row >= m_sort.size())
{ {
// log.fine( "Empty buffer"); // log.fine( "Empty buffer");
return null; return null;
} }
// return Data item // return Data item
MSort sort = (MSort)m_sort.get(row); Object[] rowData = getDataAtRow(row);
Object[] rowData = (Object[])m_buffer.get(sort.index);
// out of bounds // out of bounds
if (rowData == null || col > rowData.length) if (rowData == null || col > rowData.length)
{ {
@ -883,6 +955,116 @@ public class GridTable extends AbstractTableModel
return rowData[col]; return rowData[col];
} // getValueAt } // getValueAt
private Object[] getDataAtRow(int row)
{
MSort sort = (MSort)m_sort.get(row);
Object[] rowData = null;
if (m_virtual)
{
int bufferrow = -1;
if (sort.index != -1 && (row < m_cacheStart || row > m_cacheEnd))
{
fillBuffer(row);
}
bufferrow = row - m_cacheStart;
rowData = (Object[])m_buffer.get(bufferrow);
}
else
{
rowData = (Object[])m_buffer.get(sort.index);
}
return rowData;
}
private void setDataAtRow(int row, Object[] rowData) {
MSort sort = m_sort.get(row);
if (m_virtual)
{
int bufferrow = -1;
if (sort.index != -1 && (row < m_cacheStart || row > m_cacheEnd))
{
fillBuffer(row);
}
bufferrow = row - m_cacheStart;
m_buffer.set(bufferrow, rowData);
}
else
{
m_buffer.set(sort.index, rowData);
}
}
private void fillBuffer(int start)
{
//adjust start if needed
if (start > 0)
{
if (start + 200 >= m_sort.size())
{
start = start - (200 - ( m_sort.size() - start ));
if (start < 0)
start = 0;
}
}
StringBuffer sql = new StringBuffer();
sql.append(m_SQL_Select)
.append(" WHERE ")
.append(getKeyColumnName())
.append(" IN (");
m_cacheStart = start;
m_cacheEnd = m_cacheStart - 1;
Map<Integer, Integer>rowmap = new LinkedHashMap<Integer, Integer>(200);
for(int i = start; i < start+200 && i < m_sort.size(); i++)
{
if(i > start)
sql.append(",");
sql.append(m_sort.get(i).index);
rowmap.put(m_sort.get(i).index, i);
}
sql.append(")");
m_buffer = new ArrayList<Object[]>(210);
for(int i = 0; i < 200; i++)
m_buffer.add(null);
PreparedStatement stmt = null;
ResultSet rs = null;
try
{
stmt = DB.prepareStatement(sql.toString(), null);
rs = stmt.executeQuery();
while(rs.next())
{
Object[] data = readData(rs);
int row = rowmap.remove(data[m_indexKeyColumn]);
m_buffer.set(row - m_cacheStart, data);
m_cacheEnd++;
}
if (!rowmap.isEmpty())
{
List<Integer> toremove = new ArrayList<Integer>();
for(Map.Entry<Integer, Integer> entry : rowmap.entrySet())
{
toremove.add(entry.getValue());
}
Collections.reverse(toremove);
for(Integer row : toremove)
{
m_sort.remove(row);
m_buffer.remove(row - m_cacheStart);
}
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
finally
{
DB.close(rs, stmt);
}
}
/** /**
* Indicate that there will be a change * Indicate that there will be a change
* @param changed changed * @param changed changed
@ -958,8 +1140,8 @@ public class GridTable extends AbstractTableModel
m_oldValue[2] = oldValue; m_oldValue[2] = oldValue;
// Set Data item // Set Data item
MSort sort = (MSort)m_sort.get(row);
Object[] rowData = (Object[])m_buffer.get(sort.index); Object[] rowData = getDataAtRow(row);
m_rowChanged = row; m_rowChanged = row;
/** Selection /** Selection
@ -981,7 +1163,7 @@ public class GridTable extends AbstractTableModel
// save & update // save & update
rowData[col] = value; rowData[col] = value;
m_buffer.set(sort.index, rowData); setDataAtRow(row, rowData);
// update Table // update Table
fireTableCellUpdated(row, col); fireTableCellUpdated(row, col);
// update MField // update MField
@ -1127,6 +1309,8 @@ public class GridTable extends AbstractTableModel
// Value not changed // Value not changed
if (m_rowData == null) if (m_rowData == null)
{ {
//reset out of sync variable
m_rowChanged = -1;
log.fine("No Changes"); log.fine("No Changes");
return SAVE_ERROR; return SAVE_ERROR;
} }
@ -1180,8 +1364,7 @@ public class GridTable extends AbstractTableModel
} }
// get updated row data // get updated row data
MSort sort = (MSort)m_sort.get(m_rowChanged); Object[] rowData = getDataAtRow(m_rowChanged);
Object[] rowData = (Object[])m_buffer.get(sort.index);
// Check Mandatory // Check Mandatory
String missingColumns = getMandatory(rowData); String missingColumns = getMandatory(rowData);
@ -1714,7 +1897,12 @@ public class GridTable extends AbstractTableModel
{ {
rowDataDB = readData(rs); rowDataDB = readData(rs);
// update buffer // update buffer
m_buffer.set(sort.index, rowDataDB); setDataAtRow(m_rowChanged, rowDataDB);
if (m_virtual)
{
MSort sort = m_sort.get(m_rowChanged);
sort.index = getKeyID(m_rowChanged);
}
fireTableRowsUpdated(m_rowChanged, m_rowChanged); fireTableRowsUpdated(m_rowChanged, m_rowChanged);
} }
else else
@ -1764,8 +1952,7 @@ public class GridTable extends AbstractTableModel
{ {
log.fine("ID=" + Record_ID); log.fine("ID=" + Record_ID);
// //
MSort sort = (MSort)m_sort.get(m_rowChanged); Object[] rowData = getDataAtRow(m_rowChanged);
Object[] rowData = (Object[])m_buffer.get(sort.index);
// //
MTable table = MTable.get (m_ctx, m_AD_Table_ID); MTable table = MTable.get (m_ctx, m_AD_Table_ID);
PO po = null; PO po = null;
@ -1874,7 +2061,12 @@ public class GridTable extends AbstractTableModel
{ {
Object[] rowDataDB = readData(rs); Object[] rowDataDB = readData(rs);
// update buffer // update buffer
m_buffer.set(sort.index, rowDataDB); setDataAtRow(m_rowChanged, rowDataDB);
if (m_virtual)
{
MSort sort = m_sort.get(m_rowChanged);
sort.index = getKeyID(m_rowChanged);
}
fireTableRowsUpdated(m_rowChanged, m_rowChanged); fireTableRowsUpdated(m_rowChanged, m_rowChanged);
} }
} }
@ -2167,12 +2359,21 @@ public class GridTable extends AbstractTableModel
m_compareDB = true; m_compareDB = true;
m_newRow = currentRow + 1; m_newRow = currentRow + 1;
// if there is no record, the current row could be 0 (and not -1) // if there is no record, the current row could be 0 (and not -1)
if (m_buffer.size() < m_newRow) if (m_sort.size() < m_newRow)
m_newRow = m_buffer.size(); m_newRow = m_sort.size();
// add Data at end of buffer // add Data at end of buffer
MSort newSort = new MSort(m_buffer.size(), null); // index MSort newSort = m_virtual
m_buffer.add(rowData); ? new MSort(-1, null)
: new MSort(m_sort.size(), null); // index
if (m_virtual)
{
m_buffer.add(m_newRow, rowData);
}
else
{
m_buffer.add(rowData);
}
// add Sort pointer // add Sort pointer
m_sort.add(m_newRow, newSort); m_sort.add(m_newRow, newSort);
m_rowCount++; m_rowCount++;
@ -2181,8 +2382,7 @@ public class GridTable extends AbstractTableModel
if (copyCurrent) if (copyCurrent)
{ {
boolean hasDocTypeTargetField = (getField("C_DocTypeTarget_ID") != null); boolean hasDocTypeTargetField = (getField("C_DocTypeTarget_ID") != null);
MSort sort = (MSort) m_sort.get(currentRow); Object[] origData = getDataAtRow(currentRow);
Object[] origData = (Object[])m_buffer.get(sort.index);
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
GridField field = (GridField)m_fields.get(i); GridField field = (GridField)m_fields.get(i);
@ -2280,7 +2480,7 @@ public class GridTable extends AbstractTableModel
// fireDataStatusEvent(Log.retrieveError()); // fireDataStatusEvent(Log.retrieveError());
MSort sort = (MSort)m_sort.get(row); MSort sort = (MSort)m_sort.get(row);
Object[] rowData = (Object[])m_buffer.get(sort.index); Object[] rowData = getDataAtRow(row);
// //
MTable table = MTable.get (m_ctx, m_AD_Table_ID); MTable table = MTable.get (m_ctx, m_AD_Table_ID);
PO po = null; PO po = null;
@ -2347,19 +2547,31 @@ public class GridTable extends AbstractTableModel
} }
// Get Sort // Get Sort
int bufferRow = sort.index; int bufferRow = m_virtual
? row - m_cacheStart
: sort.index;
// Delete row in Buffer and shifts all below up // Delete row in Buffer and shifts all below up
m_buffer.remove(bufferRow); m_buffer.remove(bufferRow);
m_rowCount--; m_rowCount--;
// Delete row in Sort // Delete row in Sort
m_sort.remove(row); m_sort.remove(row);
// Correct pointer in Sort if (!m_virtual)
for (int i = 0; i < m_sort.size(); i++)
{ {
MSort ptr = (MSort)m_sort.get(i); // Correct pointer in Sort
if (ptr.index > bufferRow) for (int i = 0; i < m_sort.size(); i++)
ptr.index--; // move up {
MSort ptr = (MSort)m_sort.get(i);
if (ptr.index > bufferRow)
ptr.index--; // move up
}
}
else
{
if (m_cacheStart == row)
m_cacheStart++;
else
m_cacheEnd--;
} }
// inform // inform
@ -2389,7 +2601,9 @@ public class GridTable extends AbstractTableModel
{ {
// Get Sort // Get Sort
MSort sort = (MSort)m_sort.get(m_newRow); MSort sort = (MSort)m_sort.get(m_newRow);
int bufferRow = sort.index; int bufferRow = m_virtual
? m_buffer.size() - 1
: sort.index;
// Delete row in Buffer and shifts all below up // Delete row in Buffer and shifts all below up
m_buffer.remove(bufferRow); m_buffer.remove(bufferRow);
m_rowCount--; m_rowCount--;
@ -2408,8 +2622,7 @@ public class GridTable extends AbstractTableModel
// update buffer // update buffer
if (m_rowData != null) if (m_rowData != null)
{ {
MSort sort = (MSort)m_sort.get(m_rowChanged); setDataAtRow(m_rowChanged, m_rowData);
m_buffer.set(sort.index, m_rowData);
} }
m_changed = false; m_changed = false;
m_rowData = null; m_rowData = null;
@ -2435,7 +2648,7 @@ public class GridTable extends AbstractTableModel
return; return;
MSort sort = (MSort)m_sort.get(row); MSort sort = (MSort)m_sort.get(row);
Object[] rowData = (Object[])m_buffer.get(sort.index); Object[] rowData = getDataAtRow(row);
// ignore // ignore
dataIgnore(); dataIgnore();
@ -2472,7 +2685,7 @@ public class GridTable extends AbstractTableModel
} }
// update buffer // update buffer
m_buffer.set(sort.index, rowDataDB); setDataAtRow(row, rowDataDB);
// info // info
m_rowData = null; m_rowData = null;
m_changed = false; m_changed = false;
@ -3045,14 +3258,24 @@ public class GridTable extends AbstractTableModel
return; return;
} }
// Get Data // Get Data
Object[] rowData = readData(m_rs); int recordId = 0;
Object[] rowData = null;
if (m_virtual)
recordId = m_rs.getInt(getKeyColumnName());
else
rowData = readData(m_rs);
// add Data // add Data
MSort sort = new MSort(m_buffer.size(), null); // index MSort sort = m_virtual
m_buffer.add(rowData); ? new MSort(recordId, null)
: new MSort(m_buffer.size(), null); // index
if (!m_virtual)
{
m_buffer.add(rowData);
}
m_sort.add(sort); m_sort.add(sort);
// Statement all 250 rows & sleep // Statement all 1000 rows & sleep
if (m_buffer.size() % 250 == 0) if (m_sort.size() % 1000 == 0)
{ {
// give the other processes a chance // give the other processes a chance
try try
@ -3067,7 +3290,7 @@ public class GridTable extends AbstractTableModel
return; return;
} }
DataStatusEvent evt = createDSE(); DataStatusEvent evt = createDSE();
evt.setLoading(m_buffer.size()); evt.setLoading(m_sort.size());
fireDataStatusChanged(evt); fireDataStatusChanged(evt);
} }
} // while(rs.next()) } // while(rs.next())
@ -3253,11 +3476,11 @@ public class GridTable extends AbstractTableModel
int parentLevel = currentLevel-1; int parentLevel = currentLevel-1;
if (parentLevel < 0) if (parentLevel < 0)
return tabNo; return tabNo;
while (parentLevel != currentLevel) while (parentLevel != currentLevel)
{ {
tabNo--; tabNo--;
currentLevel = Env.getContextAsInt(m_ctx, m_WindowNo, tabNo, GridTab.CTX_TabLevel); currentLevel = Env.getContextAsInt(m_ctx, m_WindowNo, tabNo, GridTab.CTX_TabLevel);
} }
return tabNo; return tabNo;
} }
} }

View File

@ -69,28 +69,53 @@ public class GridWindow implements Serializable
* @return window or null if not found * @return window or null if not found
*/ */
public static GridWindow get (Properties ctx, int WindowNo, int AD_Window_ID) public static GridWindow get (Properties ctx, int WindowNo, int AD_Window_ID)
{
return get(ctx, WindowNo, AD_Window_ID, false);
}
/**
* Get Grid Window
* @param ctx context
* @param WindowNo window no for ctx
* @param AD_Window_ID window id
* @param virtual
* @return window or null if not found
*/
public static GridWindow get (Properties ctx, int WindowNo, int AD_Window_ID, boolean virtual)
{ {
log.config("Window=" + WindowNo + ", AD_Window_ID=" + AD_Window_ID); log.config("Window=" + WindowNo + ", AD_Window_ID=" + AD_Window_ID);
GridWindowVO mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID); GridWindowVO mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID);
if (mWindowVO == null) if (mWindowVO == null)
return null; return null;
return new GridWindow(mWindowVO); return new GridWindow(mWindowVO, virtual);
} // get } // get
/************************************************************************** /**************************************************************************
* Constructor * Constructor
* @param vo value object * @param vo value object
*/ */
public GridWindow (GridWindowVO vo) public GridWindow (GridWindowVO vo)
{
this(vo, false);
}
/**************************************************************************
* Constructor
* @param vo value object
* @param virtual
*/
public GridWindow (GridWindowVO vo, boolean virtual)
{ {
m_vo = vo; m_vo = vo;
m_virtual = virtual;
if (loadTabData()) if (loadTabData())
enableEvents(); enableEvents();
} // MWindow } // MWindow
/** Value Object */ /** Value Object */
private GridWindowVO m_vo; private GridWindowVO m_vo;
/** use virtual table */
private boolean m_virtual;
/** Tabs */ /** Tabs */
private ArrayList<GridTab> m_tabs = new ArrayList<GridTab>(); private ArrayList<GridTab> m_tabs = new ArrayList<GridTab>();
/** Model last updated */ /** Model last updated */
@ -141,7 +166,7 @@ public class GridWindow implements Serializable
GridTabVO mTabVO = (GridTabVO)m_vo.Tabs.get(t); GridTabVO mTabVO = (GridTabVO)m_vo.Tabs.get(t);
if (mTabVO != null) if (mTabVO != null)
{ {
GridTab mTab = new GridTab(mTabVO, this); GridTab mTab = new GridTab(mTabVO, this, m_virtual);
m_tabs.add(mTab); m_tabs.add(mTab);
} }
} // for all tabs } // for all tabs

View File

@ -277,7 +277,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
"AccessTableNoView") "AccessTableNoView")
+ "(No Window Model Info)"); + "(No Window Model Info)");
} }
gridWindow = new GridWindow(gWindowVO); gridWindow = new GridWindow(gWindowVO, true);
title = gridWindow.getName(); title = gridWindow.getName();
// Set SO/AutoNew for Window // Set SO/AutoNew for Window
@ -1519,7 +1519,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
if (!getComponent().getDesktop().isServerPushEnabled()) if (!getComponent().getDesktop().isServerPushEnabled())
getComponent().getDesktop().enableServerPush(true); getComponent().getDesktop().enableServerPush(true);
ProcessModalDialog dialog = new ProcessModalDialog(null,this.getTitle(),this,0, ProcessModalDialog dialog = new ProcessModalDialog(this,0,
AD_Process_ID,table_ID, record_ID, true); AD_Process_ID,table_ID, record_ID, true);
if (dialog.isValid()) { if (dialog.isValid()) {
dialog.setPosition("center"); dialog.setPosition("center");
@ -1905,8 +1905,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
} }
else else
{ {
ProcessModalDialog dialog = new ProcessModalDialog(null, ProcessModalDialog dialog = new ProcessModalDialog(this, curWindowNo,
Env.getHeader(ctx, curWindowNo), this, curWindowNo,
wButton.getProcess_ID(), table_ID, record_ID, startWOasking); wButton.getProcess_ID(), table_ID, record_ID, startWOasking);
if (dialog.isValid()) if (dialog.isValid())