/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.eas.client.forms.components.model.grid.models; import com.eas.client.forms.components.model.ModelWidget; import com.eas.client.forms.components.model.grid.columns.ModelColumn; import com.eas.script.Scripts; import java.awt.EventQueue; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.table.TableColumnModel; import jdk.nashorn.api.scripting.AbstractJSObject; import jdk.nashorn.api.scripting.JSObject; /** * * @author mg */ public abstract class ArrayModel { public static final String BAD_COLUMN_MSG = "Bad column configuration detected at column index %d"; public static final String COLUMN_BINDING_MISSING_MSG = "Column rowset missing"; public static final String COLUMN_MISSING_MSG = "Model column missing"; protected TableColumnModel columns; protected JSObject generalOnRender; protected JSObject data; protected JSObject boundToData; protected JSObject boundToDataElements; public ArrayModel(TableColumnModel aColumns, JSObject aData, JSObject aGeneralOnRender) { super(); columns = aColumns; data = aData; generalOnRender = aGeneralOnRender; } protected Runnable elementsChangedEnqueued; protected void enqueueElementsChanged() { if (boundToDataElements != null) { Scripts.unlisten(boundToDataElements); boundToDataElements = null; } elementsChangedEnqueued = () -> { if (elementsChangedEnqueued == this) { elementsChangedEnqueued = null; if (data != null && Scripts.isInitialized()) { boundToDataElements = Scripts.getSpace().listenElements(data, new AbstractJSObject() { @Override public Object call(Object thiz, Object... args) { enqueueElementsDataChanged(); return null; } }); } fireElementsChanged(); } }; EventQueue.invokeLater(elementsChangedEnqueued); } protected Runnable elementsDataChangedEnqueued; protected void enqueueElementsDataChanged() { elementsDataChangedEnqueued = () -> { if (elementsDataChangedEnqueued == this) { elementsDataChangedEnqueued = null; fireElementsDataChanged(); } }; EventQueue.invokeLater(elementsDataChangedEnqueued); } protected void bind() { if (data != null && Scripts.isInitialized()) { boundToData = Scripts.getSpace().listen(data, "length", new AbstractJSObject() { @Override public Object call(Object thiz, Object... args) { enqueueElementsChanged(); return null; } }); } } protected void unbind() { if (boundToData != null) { Scripts.unlisten(boundToData); boundToData = null; } if (boundToDataElements != null) { Scripts.unlisten(boundToDataElements); boundToDataElements = null; } } public JSObject getData() { return data; } public void setData(JSObject aValue) { if (data != null ? !data.equals(aValue) : aValue != null) { unbind(); data = aValue; bind(); enqueueElementsChanged(); } } public int getColumnCount() { return columns.getColumnCount(); } public String getColumnName(int columnIndex) { return ""; } public Class<?> getColumnClass(int columnIndex) { return Object.class; } public Object getValue(JSObject anElement, int columnIndex) { if (columnIndex >= 0 && columnIndex < columns.getColumnCount()) { try { ModelColumn column = (ModelColumn) columns.getColumn(columnIndex); return ModelWidget.getPathData(anElement, column.getField()); } catch (Exception ex) { Logger.getLogger(ArrayTableModel.class.getName()).log(Level.SEVERE, ex.getMessage()); return null; } } return null; } public void setValue(JSObject anElement, int columnIndex, Object aValue) { if (columnIndex >= 0 && columnIndex < columns.getColumnCount()) { try { ModelColumn column = (ModelColumn) columns.getColumn(columnIndex); ModelWidget.setPathData(anElement, column.getField(), aValue); } catch (Exception ex) { Logger.getLogger(ArrayTableModel.class.getName()).log(Level.SEVERE, ex.getMessage()); } } } /** * Fires an event, occuring when data or rowset structure of column's rowset * is changed. It takes place when column's rowset and elements rowset are * not the same. * * @param aColumn ModelColumn instance, the change is related to. * @see ModelColumn */ public abstract void fireColumnFieldChanged(ModelColumn aColumn); /** * Fires an event, that tells all listeners that elements structure has been * changed. */ public abstract void fireElementsChanged(); /** * Fires an event, that tells all listeners that data in all elements have * been changed, but elements structure havn't been changed. */ public abstract void fireElementsDataChanged(); /* private CellData complementCellData(final CellData aCellData, final JSObject anElement, final ModelColumn aColumn) throws Exception { JSObject lOnRender = aColumn.getOnRender(); if (lOnRender == null) { lOnRender = generalOnRender; } if (lOnRender != null) { CellRenderEvent event = new CellRenderEvent(aColumn, aColumn, aCellData, anElement); lOnRender.call(aColumn.getPublished(), new Object[]{event.getPublished()}); } return aCellData; } */ public JSObject getGeneralOnRender() { return generalOnRender; } public void setGeneralOnRender(JSObject aValue) { generalOnRender = aValue; } }