IDEMPIERE-3536 Dynamic validation not working correctly in Grid View

This commit is contained in:
Heng Sin Low 2017-11-16 10:19:20 +08:00
parent b689ad0495
commit e7540e1c70
6 changed files with 112 additions and 60 deletions

View File

@ -5,9 +5,12 @@ package org.adempiere.util;
import java.util.Collection; import java.util.Collection;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Vector;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.GridTab; import org.compiere.model.GridTab;
@ -31,30 +34,23 @@ implements Evaluatee
private final Properties ctx; private final Properties ctx;
private final GridTab gridTab; private final GridTab gridTab;
private final GridTable gridTable;
private final int windowNo; private final int windowNo;
private final int row; private final int row;
public GridRowCtx(Properties ctx, GridTab tab)
{
this(ctx, tab, -1);
}
public GridRowCtx(Properties ctx, GridTab tab, int row) public GridRowCtx(Properties ctx, GridTab tab, int row)
{ {
super(); super();
this.ctx = ctx; this.ctx = ctx;
this.gridTab = tab; this.gridTab = tab;
this.gridTable = tab.getTableModel();
this.windowNo = tab.getWindowNo(); this.windowNo = tab.getWindowNo();
this.row = row; this.row = row;
} }
public GridRowCtx(Properties ctx, GridTable table, int windowNo, int row)
{
super();
this.ctx = ctx;
this.gridTab = null;
this.gridTable = table;
this.windowNo = windowNo;
this.row = row;
}
private String getColumnName(Object key) private String getColumnName(Object key)
{ {
if (! (key instanceof String) ) if (! (key instanceof String) )
@ -82,12 +78,13 @@ implements Evaluatee
{ {
return ctx.get(key); return ctx.get(key);
} }
GridTable gridTable = gridTab.getTableModel();
int col = gridTable.findColumn(columnName); int col = gridTable.findColumn(columnName);
if (col == -1) if (col == -1)
{ {
return ctx.get(key); return ctx.get(key);
} }
Object value = gridTable.getValueAt(row, col); Object value = gridTable.getValueAt(getRow(), col);
if (value == null) if (value == null)
{ {
value = ""; value = "";
@ -107,6 +104,10 @@ implements Evaluatee
return value.toString(); return value.toString();
} }
private int getRow() {
return row >= 0 ? row : gridTab.getCurrentRow();
}
@Override @Override
public synchronized void clear() { public synchronized void clear() {
ctx.clear(); ctx.clear();
@ -115,22 +116,19 @@ implements Evaluatee
@Override @Override
public synchronized Object clone() { public synchronized Object clone() {
final GridRowCtx grc; final GridRowCtx grc;
if (this.gridTab != null) grc = new GridRowCtx((Properties)this.ctx.clone(), this.gridTab, this.row);
grc = new GridRowCtx((Properties)this.ctx.clone(), this.gridTab, this.row);
else
grc = new GridRowCtx((Properties)this.ctx.clone(), this.gridTable, this.windowNo, this.row);
return grc; return grc;
} }
@Override @Override
public synchronized boolean contains(Object value) { public synchronized boolean contains(Object value) {
// TODO: check if that value exists in one of our GridFields return this.containsValue(value);
return this.ctx.contains(value);
} }
@Override @Override
public synchronized boolean containsKey(Object key) public synchronized boolean containsKey(Object key)
{ {
GridTable gridTable = gridTab.getTableModel();
String columnName = getColumnName(key); String columnName = getColumnName(key);
if (columnName != null && gridTable.findColumn(columnName) != -1) if (columnName != null && gridTable.findColumn(columnName) != -1)
return true; return true;
@ -139,20 +137,42 @@ implements Evaluatee
@Override @Override
public boolean containsValue(Object value) { public boolean containsValue(Object value) {
// TODO: check if that value exists in one of our GridFields if (value != null) {
GridField[] fields = gridTab.getFields();
for(GridField field : fields) {
Object fieldValue = gridTab.getValue(getRow(), field.getColumnName());
if (fieldValue != null && fieldValue.equals(value)) {
return true;
}
}
}
return ctx.containsValue(value); return ctx.containsValue(value);
} }
@Override @Override
public synchronized Enumeration<Object> elements() { public synchronized Enumeration<Object> elements() {
// TODO: implement for GridField values too Vector<Object> list = new Vector<>(ctx.values());
return ctx.elements(); GridField[] fields = gridTab.getFields();
for(GridField field : fields) {
Object fieldValue = gridTab.getValue(getRow(), field.getColumnName());
if (fieldValue != null) {
list.add(fieldValue);
}
}
return list.elements();
} }
@Override @Override
public Set<java.util.Map.Entry<Object, Object>> entrySet() { public Set<java.util.Map.Entry<Object, Object>> entrySet() {
// TODO: implement for GridField values too Set<java.util.Map.Entry<Object, Object>> set = new HashSet<>(ctx.entrySet());
return ctx.entrySet(); GridField[] fields = gridTab.getFields();
Map<Object, Object> fieldMap = new LinkedHashMap<>();
for(GridField field : fields) {
Object fieldValue = gridTab.getValue(getRow(), field.getColumnName());
fieldMap.put(field.getColumnName(), fieldValue);
}
set.addAll(fieldMap.entrySet());
return set;
} }
@Override @Override
@ -162,38 +182,28 @@ implements Evaluatee
@Override @Override
public synchronized Enumeration<Object> keys() { public synchronized Enumeration<Object> keys() {
// TODO: implement for GridField values too Vector<Object> list = new Vector<Object>(ctx.keySet());
return ctx.keys(); GridField[] fields = gridTab.getFields();
for(GridField field : fields) {
list.add(field.getColumnName());
}
return list.elements();
} }
@Override @Override
public Set<Object> keySet() { public Set<Object> keySet() {
// TODO: implement for GridField values too Set<Object> set = new HashSet<>(ctx.keySet());
return ctx.keySet(); GridField[] fields = gridTab.getFields();
for(GridField field : fields) {
set.add(field.getColumnName());
}
return set;
} }
@Override @Override
public synchronized Object put(Object key, Object value) public synchronized Object put(Object key, Object value)
{ {
if (gridTab == null) return ctx.put(key, value);
throw new IllegalStateException("Method not supported (gridTab is null)");
if (gridTab.getCurrentRow() != row)
{
return ctx.put(key, value);
}
String columnName = getColumnName(key);
if (columnName == null)
{
return ctx.put(key, value);
}
GridField field = gridTab.getField(columnName);
if (field == null)
{
return ctx.put(key, value);
}
Object valueOld = field.getValue();
field.setValue(value, false);
return valueOld;
} }
@Override @Override
@ -204,20 +214,37 @@ implements Evaluatee
@Override @Override
public synchronized Object remove(Object key) { public synchronized Object remove(Object key) {
// TODO: implement for GridField values too
return ctx.remove(key); return ctx.remove(key);
} }
@Override @Override
public synchronized int size() { public synchronized int size() {
// TODO: implement for GridField values too return ctx.size() + gridTab.getFieldCount();
return ctx.size();
} }
@Override @Override
public synchronized String toString() { public synchronized String toString() {
// TODO: implement for GridField values too StringBuilder builder = new StringBuilder(ctx.toString());
return ctx.toString(); if (builder.length() > 0) {
builder.deleteCharAt(builder.length()-1);
if (builder.length() > 1) {
builder.append(", ");
}
} else {
builder.append("{");
}
GridField[] fields = gridTab.getFields();
for(int i = 0; i < fields.length; i++) {
builder.append(fields[i].getColumnName()).append("=");
Object value = gridTab.getValue(getRow(), fields[i].getColumnName());
builder.append(value==null ? "" : value.toString());
if (i == fields.length-1) {
builder.append("}");
} else {
builder.append(", ");
}
}
return builder.toString();
} }
@Override @Override

View File

@ -685,7 +685,7 @@ public class GridTabRowRenderer implements RowRenderer<Object[]>, RowRendererExt
} }
Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab, gridTab.getCurrentRow()) Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab)
: gridPanelFields[i].getVO().ctx; : gridPanelFields[i].getVO().ctx;
//check context //check context
if (!gridPanelFields[i].isDisplayed(ctx, true)){ if (!gridPanelFields[i].isDisplayed(ctx, true)){

View File

@ -1006,6 +1006,9 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace, IFi
GridField mField = comp.getGridField(); GridField mField = comp.getGridField();
if (mField != null) if (mField != null)
{ {
Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab)
: mField.getVO().ctx;
if (noData) if (noData)
{ {
comp.setReadWrite(false); comp.setReadWrite(false);
@ -1017,12 +1020,9 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace, IFi
mField.refreshLookup(); mField.refreshLookup();
comp.setReadWrite(rw); comp.setReadWrite(rw);
comp.setMandatory(mField.isMandatory(true)); // check context comp.setMandatory(mField.isMandatory(true)); // check context
comp.dynamicDisplay(); comp.dynamicDisplay(ctx);
} }
Properties ctx = isDetailPane() ? new GridRowCtx(Env.getCtx(), gridTab, gridTab.getCurrentRow())
: mField.getVO().ctx;
comp.setVisible((isHasCustomizeData || mField.isDisplayedGrid()) && mField.isDisplayed(ctx, true)); comp.setVisible((isHasCustomizeData || mField.isDisplayedGrid()) && mField.isDisplayed(ctx, true));
} }
} }

View File

@ -21,6 +21,7 @@ import java.awt.Color;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Properties;
import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.AdempiereWebUI;
import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ClientInfo;
@ -542,10 +543,15 @@ public abstract class WEditor implements EventListener<Event>, PropertyChangeLis
return this.mandatory; return this.mandatory;
} }
public void dynamicDisplay()
{
dynamicDisplay(gridField != null ? gridField.getVO().ctx : Env.getCtx());
}
/** /**
* allow subclass to perform dynamic loading of data * allow subclass to perform dynamic loading of data
*/ */
public void dynamicDisplay() public void dynamicDisplay(Properties ctx)
{ {
if (gridField != null) if (gridField != null)
{ {

View File

@ -24,6 +24,7 @@ import java.beans.PropertyChangeEvent;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.webui.ClientInfo; import org.adempiere.webui.ClientInfo;
@ -931,6 +932,16 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
return null; return null;
} }
@Override
public void dynamicDisplay(Properties ctx) {
if (lookup instanceof MLookup) {
((MLookup) lookup).getLookupInfo().ctx = ctx;
}
super.dynamicDisplay(ctx);
}
static class CustomSearchBox extends Searchbox { static class CustomSearchBox extends Searchbox {
/** /**

View File

@ -20,6 +20,7 @@ package org.adempiere.webui.editor;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Properties;
import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener; import javax.swing.event.ListDataListener;
@ -40,6 +41,7 @@ import org.compiere.model.GridField;
import org.compiere.model.Lookup; import org.compiere.model.Lookup;
import org.compiere.model.MBPartnerLocation; import org.compiere.model.MBPartnerLocation;
import org.compiere.model.MLocation; import org.compiere.model.MLocation;
import org.compiere.model.MLookup;
import org.compiere.model.MTable; import org.compiere.model.MTable;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
@ -656,11 +658,17 @@ ContextMenuListener, IZoomableEditor
} }
@Override @Override
public void dynamicDisplay() public void dynamicDisplay(Properties ctx)
{ {
if (lookup instanceof MLookup)
{
((MLookup) lookup).getLookupInfo().ctx = ctx;
}
if ((lookup != null) && (!lookup.isValidated() || !lookup.isLoaded() if ((lookup != null) && (!lookup.isValidated() || !lookup.isLoaded()
|| (isReadWrite() && lookup.getSize() != getComponent().getItemCount()))) || (isReadWrite() && lookup.getSize() != getComponent().getItemCount())))
this.actionRefresh(); this.actionRefresh();
super.dynamicDisplay(ctx);
} }
private static class EditorCombobox extends Combobox { private static class EditorCombobox extends Combobox {