📄 mtable.java
字号:
log.fine("already open");
dataRefreshAll();
return true;
}
// create m_SQL and m_countSQL
createSelectSql();
if (m_SQL == null || m_SQL.equals(""))
{
log.log(Level.SEVERE, "No SQL");
return false;
}
// Start Loading
m_loader = new Loader();
m_rowCount = m_loader.open();
m_buffer = new ArrayList<Object[]>(m_rowCount+10);
m_sort = new ArrayList<MSort>(m_rowCount+10);
if (m_rowCount > 0)
m_loader.start();
else
m_loader.close();
m_open = true;
//
m_changed = false;
m_rowChanged = -1;
return true;
} // open
/**
* Wait until async loader of Table and Lookup Fields is complete
* Used for performance tests
*/
public void loadComplete()
{
// Wait for loader
if (m_loader != null)
{
if (m_loader.isAlive())
{
try
{
m_loader.join();
}
catch (InterruptedException ie)
{
log.log(Level.SEVERE, "Join interrupted", ie);
}
}
}
// wait for field lookup loaders
for (int i = 0; i < m_fields.size(); i++)
{
MField field = (MField)m_fields.get(i);
field.lookupLoadComplete();
}
} // loadComplete
/**
* Is Loading
* @return true if loading
*/
public boolean isLoading()
{
if (m_loader != null && m_loader.isAlive())
return true;
return false;
} // isLoading
/**
* Is it open?
* @return true if opened
*/
public boolean isOpen()
{
return m_open;
} // isOpen
/**
* Close Resultset
* @param finalCall final call
*/
public void close (boolean finalCall)
{
if (!m_open)
return;
log.fine("final=" + finalCall);
// remove listeners
if (finalCall)
{
DataStatusListener evl[] = (DataStatusListener[])listenerList.getListeners(DataStatusListener.class);
for (int i = 0; i < evl.length; i++)
listenerList.remove(DataStatusListener.class, evl[i]);
TableModelListener ev2[] = (TableModelListener[])listenerList.getListeners(TableModelListener.class);
for (int i = 0; i < ev2.length; i++)
listenerList.remove(TableModelListener.class, ev2[i]);
VetoableChangeListener vcl[] = m_vetoableChangeSupport.getVetoableChangeListeners();
for (int i = 0; i < vcl.length; i++)
m_vetoableChangeSupport.removeVetoableChangeListener(vcl[i]);
}
// Stop loader
while (m_loader != null && m_loader.isAlive())
{
log.fine("Interrupting Loader ...");
m_loader.interrupt();
try
{
Thread.sleep(200); // .2 second
}
catch (InterruptedException ie)
{}
}
if (!m_inserting)
dataSave(false); // not manual
if (m_buffer != null)
m_buffer.clear();
m_buffer = null;
if (m_sort != null)
m_sort.clear();
m_sort = null;
if (finalCall)
dispose();
// Fields are disposed from MTab
log.fine("");
m_open = false;
} // close
/**
* Dispose MTable.
* Called by close-final
*/
private void dispose()
{
// MFields
for (int i = 0; i < m_fields.size(); i++)
((MField)m_fields.get(i)).dispose();
m_fields.clear();
m_fields = null;
//
m_vetoableChangeSupport = null;
//
m_parameterSELECT.clear();
m_parameterSELECT = null;
m_parameterWHERE.clear();
m_parameterWHERE = null;
// clear data arrays
m_buffer = null;
m_sort = null;
m_rowData = null;
m_oldValue = null;
m_loader = null;
} // dispose
/**
* Get total database column count (displayed and not displayed)
* @return column count
*/
public int getColumnCount()
{
return m_fields.size();
} // getColumnCount
/**
* Get (displayed) field count
* @return field count
*/
public int getFieldCount()
{
return m_fields.size();
} // getFieldCount
/**
* Return number of rows
* @return Number of rows or 0 if not opened
*/
public int getRowCount()
{
return m_rowCount;
} // getRowCount
/**
* Set the Column to determine the color of the row
* @param columnName column name
*/
public void setColorColumn (String columnName)
{
m_indexColorColumn = findColumn(columnName);
} // setColorColumn
/**
* Get ColorCode for Row.
* <pre>
* If numerical value in compare column is
* negative = -1,
* positive = 1,
* otherwise = 0
* </pre>
* @see #setColorColumn
* @param row row
* @return color code
*/
public int getColorCode (int row)
{
if (m_indexColorColumn == -1)
return 0;
Object data = getValueAt(row, m_indexColorColumn);
// We need to have a Number
if (data == null || !(data instanceof BigDecimal))
return 0;
BigDecimal bd = (BigDecimal)data;
return bd.signum();
} // getColorCode
/**
* Sort Entries by Column.
* actually the rows are not sorted, just the access pointer ArrayList
* with the same size as m_buffer with MSort entities
* @param col col
* @param ascending ascending
*/
@SuppressWarnings("unchecked")
public void sort (int col, boolean ascending)
{
log.info("#" + col + " " + ascending);
if (getRowCount() == 0)
return;
MField field = getField (col);
// RowIDs are not sorted
if (field.getDisplayType() == DisplayType.RowID)
return;
boolean isLookup = DisplayType.isLookup(field.getDisplayType());
boolean isASI = DisplayType.PAttribute == field.getDisplayType();
// fill MSort entities with data entity
for (int i = 0; i < m_sort.size(); i++)
{
MSort sort = (MSort)m_sort.get(i);
Object[] rowData = (Object[])m_buffer.get(sort.index);
if (rowData[col] == null)
sort.data = null;
else if (isLookup || isASI)
sort.data = field.getLookup().getDisplay(rowData[col]); // lookup
else
sort.data = rowData[col]; // data
}
log.info(field.toString() + " #" + m_sort.size());
// sort it
MSort sort = new MSort(0, null);
sort.setSortAsc(ascending);
Collections.sort(m_sort, sort);
// update UI
fireTableDataChanged();
// Info detected by MTab.dataStatusChanged and current row set to 0
fireDataStatusIEvent("Sorted", "#" + m_sort.size());
} // sort
/**
* Get Key ID or -1 of none
* @param row row
* @return ID or -1
*/
public int getKeyID (int row)
{
// Log.info("MTable.getKeyID - row=" + row + ", keyColIdx=" + m_indexKeyColumn);
if (m_indexKeyColumn != -1)
{
try
{
Integer ii = (Integer)getValueAt(row, m_indexKeyColumn);
if (ii == null)
return -1;
return ii.intValue();
}
catch (Exception e) // Alpha Key
{
return -1;
}
}
return -1;
} // getKeyID
/**
* Get Key ColumnName
* @return key column name
*/
public String getKeyColumnName()
{
if (m_indexKeyColumn != -1)
return getColumnName(m_indexKeyColumn);
return "";
} // getKeyColumnName
/**************************************************************************
* Get Value in Resultset
* @param row row
* @param col col
* @return Object of that row/column
*/
public Object getValueAt (int row, int col)
{
// log.config( "MTable.getValueAt r=" + row + " c=" + col);
if (!m_open || row < 0 || col < 0 || row >= m_rowCount)
{
// log.fine( "Out of bounds - Open=" + m_open + ", RowCount=" + m_rowCount);
return null;
}
// need to wait for data read into buffer
int loops = 0;
while (row >= m_buffer.size() && m_loader.isAlive() && loops < 15)
{
log.fine("Waiting for loader row=" + row + ", size=" + m_buffer.size());
try
{
Thread.sleep(500); // 1/2 second
}
catch (InterruptedException ie)
{}
loops++;
}
// empty buffer
if (row >= m_buffer.size())
{
// log.fine( "Empty buffer");
return null;
}
// return Data item
MSort sort = (MSort)m_sort.get(row);
Object[] rowData = (Object[])m_buffer.get(sort.index);
// out of bounds
if (rowData == null || col > rowData.length)
{
// log.fine( "No data or Column out of bounds");
return null;
}
return rowData[col];
} // getValueAt
/**
* Indicate that there will be a change
* @param changed changed
*/
public void setChanged (boolean changed)
{
// Can we edit?
if (!m_open || m_readOnly)
return;
// Indicate Change
m_changed = changed;
if (!changed)
m_rowChanged = -1;
if (changed)
fireDataStatusIEvent("", "");
} // setChanged
/**
* Set Value in data and update MField.
* (called directly or from JTable.editingStopped())
*
* @param value value to assign to cell
* @param row row index of cell
* @param col column index of cell
*/
public final void setValueAt (Object value, int row, int col)
{
setValueAt (value, row, col, false);
} // setValueAt
/**
* Set Value in data and update MField.
* (called directly or from JTable.editingStopped())
*
* @param value value to assign to cell
* @param row row index of cell
* @param col column index of cell
* @param force force setting new value
*/
public final void setValueAt (Object value, int row, int col, boolean force)
{
// Can we edit?
if (!m_open || m_readOnly // not accessible
|| row < 0 || col < 0 // invalid index
|| col == 0 // cannot change ID
|| m_rowCount == 0) // no rows
{
log.finest("r=" + row + " c=" + col + " - R/O=" + m_readOnly + ", Rows=" + m_rowCount + " - Ignored");
return;
}
dataSave(row, false);
// Has anything changed?
Object oldValue = getValueAt(row, col);
if (!force && (
(oldValue == null && value == null)
|| (oldValue != null && oldValue.equals(value))
|| (oldValue != null && value != null && oldValue.toString().equals(value.toString()))
))
{
log.finest("r=" + row + " c=" + col + " - New=" + value + "==Old=" + oldValue + " - Ignored");
return;
}
log.fine("r=" + row + " c=" + col + " = " + value + " (" + oldValue + ")");
// Save old value
m_oldValue = new Object[3];
m_oldValue[0] = new Integer(row);
m_oldValue[1] = new Integer(col);
m_oldValue[2] = oldValue;
// Set Data item
MSort sort = (MSort)m_sort.get(row);
Object[] rowData = (Object[])m_buffer.get(sort.index);
m_rowChanged = row;
// Selection
if (col == 0)
{
rowData[col] = value;
m_buffer.set(sort.index, rowData);
return;
}
// save original value - shallow copy
if (m_rowData == null)
{
int size = m_fields.size();
m_rowData = new Object[size];
for (int i = 0; i < size; i++)
m_rowData[i] = rowData[i];
}
// save & update
rowData[col] = value;
m_buffer.set(sort.index, rowData);
// update Table
fireTableCellUpdated(row, col);
// update MField
MField field = getField(col);
field.setValue(value, m_inserting);
// inform
DataStatusEvent evt = createDSE();
evt.setChangedColumn(col);
fireDataStatusChanged(evt);
} // setValueAt
/**
* Get Old Value
* @param row row
* @param col col
* @return old value
*/
public Object getOldValue (int row, int col)
{
if (m_oldValue == null)
return null;
if (((Integer)m_oldValue[0]).intValue() == row
&& ((Integer)m_oldValue[1]).intValue() == col)
return m_oldValue[2];
return null;
} // getOldValue
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -