[ 2656716 ] Focus management enhancement

https://sourceforge.net/tracker/index.php?func=detail&aid=2656716&group_id=176962&atid=955896
This commit is contained in:
Heng Sin Low 2009-03-03 09:41:37 +00:00
parent 33c2f1ee70
commit 8c8399bac3
9 changed files with 180 additions and 36 deletions

View File

@ -27,12 +27,14 @@ import java.util.logging.Level;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.event.ToolbarListener; import org.adempiere.webui.event.ToolbarListener;
import org.adempiere.webui.panel.IADTabpanel;
import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.session.SessionManager;
import org.compiere.model.MRole; import org.compiere.model.MRole;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
@ -93,6 +95,8 @@ public class CWindowToolbar extends FToolbar implements EventListener
private int windowNo = 0; private int windowNo = 0;
private IADTab adTab = null;
/** Last Modifier of Action Event */ /** Last Modifier of Action Event */
// public int lastModifiers; // public int lastModifiers;
// //
@ -159,12 +163,7 @@ public class CWindowToolbar extends FToolbar implements EventListener
// Help and Exit should always be enabled // Help and Exit should always be enabled
btnHelp.setDisabled(false); btnHelp.setDisabled(false);
// btnExit.setDisabled(false);
// Testing Purposes
btnGridToggle.setDisabled(false); btnGridToggle.setDisabled(false);
btnZoomAcross.setDisabled(false); btnZoomAcross.setDisabled(false);
btnActiveWorkflows.setDisabled(false); // Elaine 2008/07/17 btnActiveWorkflows.setDisabled(false); // Elaine 2008/07/17
@ -343,6 +342,12 @@ public class CWindowToolbar extends FToolbar implements EventListener
} }
} }
this.event = null; this.event = null;
if (adTab != null) {
IADTabpanel adTabPanel = adTab.getSelectedTabpanel();
if (adTabPanel != null && adTabPanel instanceof HtmlBasedComponent) {
((HtmlBasedComponent)adTabPanel).focus();
}
}
} }
public void enableHistoryRecords(boolean enabled) public void enableHistoryRecords(boolean enabled)
@ -520,6 +525,10 @@ public class CWindowToolbar extends FToolbar implements EventListener
return true; return true;
} }
/**
*
* @param visible
*/
public void setVisibleAll(boolean visible) public void setVisibleAll(boolean visible)
{ {
for (ToolBarButton btn : buttons.values()) for (ToolBarButton btn : buttons.values())
@ -528,6 +537,11 @@ public class CWindowToolbar extends FToolbar implements EventListener
} }
} }
/**
*
* @param buttonName
* @param visible
*/
public void setVisible(String buttonName, boolean visible) public void setVisible(String buttonName, boolean visible)
{ {
ToolBarButton btn = buttons.get(buttonName); ToolBarButton btn = buttons.get(buttonName);
@ -537,8 +551,20 @@ public class CWindowToolbar extends FToolbar implements EventListener
} }
} }
/**
*
* @param windowNo
*/
public void setWindowNo(int windowNo) { public void setWindowNo(int windowNo) {
this.windowNo = windowNo; this.windowNo = windowNo;
} }
/**
*
* @param adTab
*/
public void setADTab(IADTab adTab) {
this.adTab = adTab;
}
} }

View File

@ -18,6 +18,7 @@
package org.adempiere.webui.component; package org.adempiere.webui.component;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zul.RowRenderer;
/** /**
* *
@ -51,4 +52,14 @@ public class Grid extends org.zkoss.zul.Grid
} }
return b; return b;
} }
/**
* Don't call this directly, only use by GridTabRowRenderer to send post render event
*/
public void onPostGridRender() {
RowRenderer renderer = this.getRowRenderer();
if (renderer instanceof GridTabRowRenderer) {
((GridTabRowRenderer)renderer).setFocusToField();
}
}
} }

View File

@ -151,6 +151,7 @@ public class GridPanel extends Borderlayout implements EventListener
renderer.stopEditing(false); renderer.stopEditing(false);
listbox.setModel(listModel); listbox.setModel(listModel);
updateListIndex();
} }
} }
@ -162,8 +163,8 @@ public class GridPanel extends Borderlayout implements EventListener
if (pageSize > 0) { if (pageSize > 0) {
if (paging.getTotalSize() != gridTab.getRowCount()) if (paging.getTotalSize() != gridTab.getRowCount())
paging.setTotalSize(gridTab.getRowCount()); paging.setTotalSize(gridTab.getRowCount());
int pgIndex = rowIndex % pageSize; int pgIndex = rowIndex >= 0 ? rowIndex % pageSize : 0;
int pgNo = (rowIndex - pgIndex) / pageSize; int pgNo = rowIndex >= 0 ? (rowIndex - pgIndex) / pageSize : 0;
if (listModel.getPage() != pgNo) { if (listModel.getPage() != pgNo) {
listModel.setPage(pgNo); listModel.setPage(pgNo);
@ -172,10 +173,20 @@ public class GridPanel extends Borderlayout implements EventListener
paging.setActivePage(pgNo); paging.setActivePage(pgNo);
} }
renderer.stopEditing(false); renderer.stopEditing(false);
listModel.updateComponent(pgIndex); if (rowIndex >= 0 && pgIndex >= 0) {
listModel.updateComponent(pgIndex);
//this is needed to make focus and auto scroll work
org.zkoss.zul.Row row = (org.zkoss.zul.Row)listbox.getRows().getChildren().get(pgIndex);
listbox.renderRow(row);
}
} else { } else {
renderer.stopEditing(false); renderer.stopEditing(false);
listModel.updateComponent(rowIndex); if (rowIndex >= 0) {
listModel.updateComponent(rowIndex);
//this is needed to make focus and auto scroll work
org.zkoss.zul.Row row = (org.zkoss.zul.Row)listbox.getRows().getChildren().get(rowIndex);
listbox.renderRow(row);
}
} }
} }
@ -228,7 +239,7 @@ public class GridPanel extends Borderlayout implements EventListener
column.setSortDescending(new SortComparator(i, false, Env.getLanguage(Env.getCtx()))); column.setSortDescending(new SortComparator(i, false, Env.getLanguage(Env.getCtx())));
column.setLabel(gridField[i].getHeader()); column.setLabel(gridField[i].getHeader());
int l = DisplayType.isNumeric(gridField[i].getDisplayType()) int l = DisplayType.isNumeric(gridField[i].getDisplayType())
? 100 : gridField[i].getDisplayLength() * 9; ? 120 : gridField[i].getDisplayLength() * 9;
if (gridField[i].getHeader().length() * 9 > l) if (gridField[i].getHeader().length() * 9 > l)
l = gridField[i].getHeader().length() * 9; l = gridField[i].getHeader().length() * 9;
if (l > MAX_COLUMN_WIDTH) if (l > MAX_COLUMN_WIDTH)
@ -278,6 +289,7 @@ public class GridPanel extends Borderlayout implements EventListener
if (renderer != null) if (renderer != null)
renderer.stopEditing(false); renderer.stopEditing(false);
renderer = new GridTabRowRenderer(gridTab, windowNo); renderer = new GridTabRowRenderer(gridTab, windowNo);
renderer.setGridPanel(this);
listbox.setRowRenderer(renderer); listbox.setRowRenderer(renderer);
listbox.setModel(listModel); listbox.setModel(listModel);
@ -295,13 +307,15 @@ public class GridPanel extends Borderlayout implements EventListener
{ {
if (event == null) if (event == null)
return; return;
else if (event.getTarget() == listbox) else if (event.getTarget() == listbox && Events.ON_CLICK.equals(event.getName()))
{ {
Object data = event.getData(); Object data = event.getData();
if (data != null && data instanceof org.zkoss.zul.Row) if (data != null && data instanceof org.zkoss.zul.Row)
{ {
int index = listbox.getRows().getChildren().indexOf(data); int index = listbox.getRows().getChildren().indexOf(data);
onSelectedRowChange(index); if (index >= 0 ) {
onSelectedRowChange(index);
}
} }
} }
else if (event.getTarget() == paging) else if (event.getTarget() == paging)
@ -316,7 +330,7 @@ public class GridPanel extends Borderlayout implements EventListener
} }
private void onSelectedRowChange(int index) { private void onSelectedRowChange(int index) {
if (updateModelIndex(index)) { if (updateModelIndex(index)) {
listModel.updateComponent(index); listModel.updateComponent(index);
} else if (!renderer.isInitialize()) { } else if (!renderer.isInitialize()) {
listModel.updateComponent(index); listModel.updateComponent(index);
@ -386,4 +400,10 @@ public class GridPanel extends Borderlayout implements EventListener
public void setWindowNo(int windowNo) { public void setWindowNo(int windowNo) {
this.windowNo = windowNo; this.windowNo = windowNo;
} }
@Override
public void focus() {
if (renderer != null)
renderer.setFocusToField();
}
} }

View File

@ -16,6 +16,7 @@ import java.sql.Timestamp;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -33,11 +34,13 @@ import org.compiere.model.GridField;
import org.compiere.model.GridTab; import org.compiere.model.GridTab;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.NamePair; import org.compiere.util.NamePair;
import org.zkoss.zk.au.out.AuFocus;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Div; import org.zkoss.zul.Div;
import org.zkoss.zul.Grid; import org.zkoss.zul.Grid;
import org.zkoss.zul.Paging; import org.zkoss.zul.Paging;
@ -57,12 +60,15 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer
private GridTab gridTab; private GridTab gridTab;
private int windowNo; private int windowNo;
private GridTabDataBinder dataBinder; private GridTabDataBinder dataBinder;
private Map<GridField, WEditor> editors = new HashMap<GridField, WEditor>(); private Map<GridField, WEditor> editors = new LinkedHashMap<GridField, WEditor>();
private Paging paging; private Paging paging;
private Map<String, Map<Object, String>> lookupCache = null; private Map<String, Map<Object, String>> lookupCache = null;
private RowListener rowListener; private RowListener rowListener;
private Grid grid = null;
private GridPanel gridPanel = null;
/** /**
* *
* @param gridTab * @param gridTab
@ -285,10 +291,13 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer
*/ */
public void render(Row row, Object data) throws Exception { public void render(Row row, Object data) throws Exception {
//don't render if not visible //don't render if not visible
for(Component c = row.getParent(); c != null; c = c.getParent()) { if (gridPanel != null && !gridPanel.isVisible()) {
if (!c.isVisible()) return;
return;
} }
if (grid == null)
grid = (Grid) row.getParent().getParent();
if (rowListener == null) if (rowListener == null)
rowListener = new RowListener((Grid)row.getParent().getParent()); rowListener = new RowListener((Grid)row.getParent().getParent());
@ -382,6 +391,8 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer
*/ */
public void doFinally() { public void doFinally() {
lookupCache = null; lookupCache = null;
if (grid != null)
Events.echoEvent("onPostGridRender", grid, null);
} }
/** /**
@ -391,6 +402,35 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer
lookupCache = new HashMap<String, Map<Object,String>>(); lookupCache = new HashMap<String, Map<Object,String>>();
} }
/**
* set focus to first active editor
*/
public void setFocusToField() {
WEditor toFocus = null;
for (WEditor editor : getEditors()) {
if (editor.isHasFocus()) {
toFocus = editor;
break;
}
if (toFocus == null) {
if (editor.isVisible() && editor.isReadWrite()) {
toFocus = editor;
}
}
}
if (toFocus != null)
Clients.response(new AuFocus(toFocus.getComponent()));
}
/**
*
* @param gridPanel
*/
public void setGridPanel(GridPanel gridPanel) {
this.gridPanel = gridPanel;
}
class RowListener implements EventListener { class RowListener implements EventListener {
private Grid _grid; private Grid _grid;
@ -406,5 +446,5 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer
} }
} }
} }
} }

View File

@ -335,10 +335,11 @@ public class WListItemRenderer implements ListitemRenderer, EventListener, Listi
else if (field instanceof IDColumn) else if (field instanceof IDColumn)
{ {
listcell.setValue(((IDColumn) field).getRecord_ID()); listcell.setValue(((IDColumn) field).getRecord_ID());
if (!table.isCheckmark()) if (!table.isCheckmark()) {
table.setCheckmark(true); table.setCheckmark(true);
table.removeEventListener(Events.ON_SELECT, this); table.removeEventListener(Events.ON_SELECT, this);
table.addEventListener(Events.ON_SELECT, this); table.addEventListener(Events.ON_SELECT, this);
}
} }
else else
{ {

View File

@ -33,7 +33,9 @@ import org.compiere.model.GridTab;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Image; import org.zkoss.zul.Image;
/** /**
@ -70,6 +72,8 @@ public abstract class WEditor implements EventListener, PropertyChangeListener
private String columnName; private String columnName;
protected boolean hasFocus;
/** /**
* *
* @param comp * @param comp
@ -196,6 +200,18 @@ public abstract class WEditor implements EventListener, PropertyChangeListener
{ {
component.addEventListener(event, this); component.addEventListener(event, this);
} }
component.addEventListener(Events.ON_FOCUS, new EventListener() {
public void onEvent(Event event) throws Exception {
hasFocus = true;
}
});
component.addEventListener(Events.ON_BLUR, new EventListener() {
public void onEvent(Event event) throws Exception {
hasFocus = false;
}
});
} }
/** /**
@ -458,4 +474,8 @@ public abstract class WEditor implements EventListener, PropertyChangeListener
} }
} }
} }
public boolean isHasFocus() {
return hasFocus;
}
} }

View File

@ -709,7 +709,7 @@ DataStatusListener, IADTabpanel
} else { } else {
if (activate) { if (activate) {
formComponent.setVisible(activate); formComponent.setVisible(activate);
setInitialFocus(); setFocusToField();
} }
} }
@ -730,14 +730,22 @@ DataStatusListener, IADTabpanel
panel.tabPanel.activate(activate); panel.tabPanel.activate(activate);
} }
private void setInitialFocus() { private void setFocusToField() {
WEditor toFocus = null;
for (WEditor editor : editors) { for (WEditor editor : editors) {
if (editor.isVisible() && editor.isReadWrite()) { if (editor.isHasFocus()) {
Clients.response(new AuFocus(editor.getComponent())); toFocus = editor;
break; break;
} }
if (toFocus == null) {
if (editor.isVisible() && editor.isReadWrite()) {
toFocus = editor;
}
}
}
if (toFocus != null) {
Clients.response(new AuFocus(toFocus.getComponent()));
} }
} }
/** /**
@ -1028,5 +1036,13 @@ DataStatusListener, IADTabpanel
ep.windowPanel.getStatusBar().setZclass("z-group-foot"); ep.windowPanel.getStatusBar().setZclass("z-group-foot");
ep.windowPanel.initPanel(-1, null); ep.windowPanel.initPanel(-1, null);
} }
@Override
public void focus() {
if (formComponent.isVisible())
this.setFocusToField();
else
listPanel.focus();
}
} }

View File

@ -71,6 +71,7 @@ import org.compiere.util.Msg;
import org.compiere.util.WebDoc; import org.compiere.util.WebDoc;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
@ -183,6 +184,8 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
adTab = createADTab(); adTab = createADTab();
adTab.addSelectionEventListener(this); adTab.addSelectionEventListener(this);
toolbar.setADTab(adTab);
return super.createPart(parent); return super.createPart(parent);
} }
@ -473,7 +476,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
if (curInd > 0) if (curInd > 0)
{ {
setActiveTab(curInd - 1); setActiveTab(curInd - 1);
} }
} }
/** /**
@ -597,7 +600,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
+ ", MaxRows=" + maxRows); + ", MaxRows=" + maxRows);
curTab.query(m_onlyCurrentRows, onlyCurrentDays, maxRows); curTab.query(m_onlyCurrentRows, onlyCurrentDays, maxRows);
} }
/** /**
@ -620,6 +623,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
curTab.loadAttachments(); // reload curTab.loadAttachments(); // reload
toolbar.getButton("Attachment").setPressed(curTab.hasAttachment()); toolbar.getButton("Attachment").setPressed(curTab.hasAttachment());
} }
/** /**
@ -627,7 +631,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
*/ */
public void onToggle() public void onToggle()
{ {
curTabpanel.switchRowPresentation(); curTabpanel.switchRowPresentation();
} }
public boolean onExit() public boolean onExit()
@ -1038,6 +1042,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
FindWindow find = new FindWindow (curTab.getWindowNo(), curTab.getName(), FindWindow find = new FindWindow (curTab.getWindowNo(), curTab.getName(),
curTab.getAD_Table_ID(), curTab.getTableName(), curTab.getAD_Table_ID(), curTab.getTableName(),
curTab.getWhereExtended(), findFields, 1, curTab.getAD_Tab_ID()); curTab.getWhereExtended(), findFields, 1, curTab.getAD_Tab_ID());
find.setVisible(true);
AEnv.showWindow(find); AEnv.showWindow(find);
MQuery query = find.getQuery(); MQuery query = find.getQuery();
@ -1052,6 +1057,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To
} }
curTab.dataRefresh(); // Elaine 2008/07/25 curTab.dataRefresh(); // Elaine 2008/07/25
} }
/** /**

View File

@ -76,7 +76,6 @@ import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zk.ui.util.Clients; import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Comboitem; import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Hbox; import org.zkoss.zul.Hbox;
@ -90,7 +89,7 @@ import org.zkoss.zul.Vbox;
* @author Sendy Yagambrum * @author Sendy Yagambrum
* @date June 27, 2007 * @date June 27, 2007
*/ */
public class FindWindow extends Window implements EventListener,ValueChangeListener, AfterCompose public class FindWindow extends Window implements EventListener,ValueChangeListener
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** Main Window for the Lookup Panel */ /** Main Window for the Lookup Panel */
@ -1666,10 +1665,7 @@ public class FindWindow extends Window implements EventListener,ValueChangeListe
} }
} }
/** public void OnPostVisible() {
* @see AfterCompose#afterCompose()
*/
public void afterCompose() {
if (hasDocNo) if (hasDocNo)
Clients.response(new AuFocus(fieldDocumentNo)); Clients.response(new AuFocus(fieldDocumentNo));
else if (hasValue) else if (hasValue)
@ -1679,7 +1675,7 @@ public class FindWindow extends Window implements EventListener,ValueChangeListe
else if (m_sEditors.size() > 0 && m_sEditors.get(0) != null) else if (m_sEditors.size() > 0 && m_sEditors.get(0) != null)
Clients.response(new AuFocus(m_sEditors.get(0).getComponent())); Clients.response(new AuFocus(m_sEditors.get(0).getComponent()));
} }
/** /**
* *
* @return true if dialog cancel by user, false otherwise * @return true if dialog cancel by user, false otherwise
@ -1687,5 +1683,13 @@ public class FindWindow extends Window implements EventListener,ValueChangeListe
public boolean isCancel() { public boolean isCancel() {
return m_isCancel; return m_isCancel;
} }
@Override
public boolean setVisible(boolean visible) {
boolean ret = super.setVisible(visible);
if (ret && visible) {
Events.echoEvent("OnPostVisible", this, null);
}
return ret;
}
} // FindPanel } // FindPanel