From 0b06a75a3b9dc299b4f745b4f84dee6139814ea6 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 14 Nov 2012 10:14:14 +0800 Subject: [PATCH] IDEMPIERE-503 Zk: Implement image icon support for window --- .../src/org/compiere/model/GridWindow.java | 12 +++ .../src/org/compiere/model/MImage.java | 5 + .../adempiere/webui/adwindow/ADWindow.java | 36 ++++++- .../webui/adwindow/ADWindowContent.java | 4 +- .../adwindow/AbstractADWindowContent.java | 41 +++++--- .../src/org/adempiere/webui/apps/AEnv.java | 5 +- .../webui/desktop/TabbedDesktop.java | 96 +++++++++++++------ .../webui/util/WebUIResourceFinder.java | 11 +++ 8 files changed, 160 insertions(+), 50 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/GridWindow.java b/org.adempiere.base/src/org/compiere/model/GridWindow.java index 644aee2d3a..5a77b3e52b 100644 --- a/org.adempiere.base/src/org/compiere/model/GridWindow.java +++ b/org.adempiere.base/src/org/compiere/model/GridWindow.java @@ -250,6 +250,18 @@ public class GridWindow implements Serializable MImage mImage = MImage.get(Env.getCtx(), m_vo.AD_Image_ID); return mImage.getImage(); } // getImage + + /** + * @return MImage + */ + public MImage getMImage() + { + if (m_vo.AD_Image_ID == 0) + return null; + // + MImage mImage = MImage.get(Env.getCtx(), m_vo.AD_Image_ID); + return mImage; + } /** * Get Window Icon diff --git a/org.adempiere.base/src/org/compiere/model/MImage.java b/org.adempiere.base/src/org/compiere/model/MImage.java index 918e92a8d5..f88f14cc2b 100644 --- a/org.adempiere.base/src/org/compiere/model/MImage.java +++ b/org.adempiere.base/src/org/compiere/model/MImage.java @@ -31,6 +31,7 @@ import java.util.logging.Level; import javax.swing.Icon; import javax.swing.ImageIcon; +import org.adempiere.base.Core; import org.compiere.util.CCache; import org.compiere.util.Ini; @@ -257,6 +258,10 @@ public class MImage extends X_AD_Image } // Get from URL URL url = getURL(); + if (url == null) + { + url = Core.getResourceFinder().getResource(str); + } if (url == null) { log.config("No URL"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java index 37c0fe2cf9..9836a95a4f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java @@ -17,12 +17,16 @@ package org.adempiere.webui.adwindow; +import java.io.IOException; import java.util.Properties; import org.adempiere.webui.desktop.IDesktop; import org.adempiere.webui.part.AbstractUIPart; import org.adempiere.webui.session.SessionManager; +import org.compiere.model.MImage; import org.compiere.model.MQuery; +import org.compiere.util.CCache; +import org.zkoss.image.AImage; import org.zkoss.zk.ui.Component; /** @@ -42,6 +46,9 @@ public class ADWindow extends AbstractUIPart private MQuery query; private Component windowPanelComponent; + private MImage image; + + private static final CCache imageCache = new CCache("WindowImageCache", 5); public ADWindow(Properties ctx, int adWindowId) { @@ -62,7 +69,9 @@ public class ADWindow extends AbstractUIPart private void init() { - windowContent = new ADWindowContent(ctx, windowNo); + windowContent = new ADWindowContent(ctx, windowNo, adWindowId); + _title = windowContent.getTitle(); + image = windowContent.getImage(); } public String getTitle() @@ -70,14 +79,35 @@ public class ADWindow extends AbstractUIPart return _title; } + public MImage getMImage() + { + return image; + } + + public AImage getAImage() throws IOException { + MImage image = getMImage(); + AImage aImage = null; + if (image != null) { + synchronized (imageCache) { + aImage = imageCache.get(image.getAD_Image_ID()); + } + if (aImage == null) { + aImage = new AImage(image.getName(), image.getData()); + synchronized (imageCache) { + imageCache.put(image.getAD_Image_ID(), aImage); + } + } + } + return aImage; + } + protected Component doCreatePart(Component parent) { windowPanelComponent = windowContent.createPart(parent); windowPanelComponent.setAttribute("ADWindow", this); windowPanelComponent.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, windowNo); - if (windowContent.initPanel(adWindowId, query)) + if (windowContent.initPanel(query)) { - _title = windowContent.getTitle(); return windowPanelComponent; } else diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java index af6b33fe9f..85daf1752f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java @@ -67,9 +67,9 @@ public class ADWindowContent extends AbstractADWindowContent private Keylistener keyListener; - public ADWindowContent(Properties ctx, int windowNo) + public ADWindowContent(Properties ctx, int windowNo, int adWindowId) { - super(ctx, windowNo); + super(ctx, windowNo, adWindowId); } protected Component doCreatePart(Component parent) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index 0c1ab0256e..8432cf5518 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -77,6 +77,7 @@ import org.compiere.model.GridTable; import org.compiere.model.GridWindow; import org.compiere.model.GridWindowVO; import org.compiere.model.Lookup; +import org.compiere.model.MImage; import org.compiere.model.MProcess; import org.compiere.model.MQuery; import org.compiere.model.MRecentItem; @@ -175,15 +176,21 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements protected BreadCrumb breadCrumb; + private int adWindowId; + + private MImage image; + /** * Constructor * @param ctx * @param windowNo + * @param adWindowId */ - public AbstractADWindowContent(Properties ctx, int windowNo) + public AbstractADWindowContent(Properties ctx, int windowNo, int adWindowId) { this.ctx = ctx; this.curWindowNo = windowNo; + this.adWindowId = adWindowId; initComponents(); } @@ -224,7 +231,18 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements toolbar.addListener(this); statusBar = new StatusBar(); - } + + GridWindowVO gWindowVO = AEnv.getMWindowVO(curWindowNo, adWindowId, 0); + if (gWindowVO == null) + { + throw new ApplicationException(Msg.getMsg(ctx, + "AccessTableNoView") + + "(No Window Model Info)"); + } + gridWindow = new GridWindow(gWindowVO, true); + title = gridWindow.getName(); + image = gridWindow.getMImage(); + } /** * @return IADTab @@ -247,7 +265,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements * @param query * @return boolean */ - public boolean initPanel(int adWindowId, MQuery query) + public boolean initPanel(MQuery query) { // This temporary validation code is added to check the reported bug // [ adempiere-ZK Web Client-2832968 ] User context lost? @@ -276,15 +294,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements boolean autoNew = Env.isAutoNew(ctx); Env.setAutoNew(ctx, curWindowNo, autoNew); - GridWindowVO gWindowVO = AEnv.getMWindowVO(curWindowNo, adWindowId, 0); - if (gWindowVO == null) - { - throw new ApplicationException(Msg.getMsg(ctx, - "AccessTableNoView") - + "(No Window Model Info)"); - } - gridWindow = new GridWindow(gWindowVO, true); - title = gridWindow.getName(); + // Set SO/AutoNew for Window Env.setContext(ctx, curWindowNo, "IsSOTrx", gridWindow.isSOTrx()); @@ -518,8 +528,6 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements } }); - -// curTab = gTab; } if (gTab.isSortTab()) @@ -668,6 +676,11 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements { return title; } + + public MImage getImage() + { + return image; + } /** * @see ToolbarListener#onDetailRecord() diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java index 6f7ee8b654..3b51c94fc3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java @@ -269,7 +269,8 @@ public final class AEnv if (mWindowVO != null) { mWindowVO = mWindowVO.clone(WindowNo); - log.info("Cached=" + mWindowVO); + if (log.isLoggable(Level.INFO)) + log.info("Cached=" + mWindowVO); } } } @@ -280,7 +281,7 @@ public final class AEnv { log.config("create local"); mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID, AD_Menu_ID); - if (mWindowVO != null) + if (mWindowVO != null && Ini.isCacheWindow()) { synchronized (windowCache) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java index 8e09b54229..51ef74592e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/TabbedDesktop.java @@ -13,8 +13,11 @@ *****************************************************************************/ package org.adempiere.webui.desktop; +import java.io.IOException; import java.util.List; +import java.util.concurrent.TimeUnit; +import org.adempiere.util.ContextRunnable; import org.adempiere.webui.adwindow.ADWindow; import org.adempiere.webui.apps.ProcessDialog; import org.adempiere.webui.apps.wf.WFPanel; @@ -24,13 +27,16 @@ import org.adempiere.webui.component.Tabpanel; import org.adempiere.webui.component.Window; import org.adempiere.webui.panel.ADForm; import org.adempiere.webui.part.WindowContainer; -import org.adempiere.webui.session.SessionManager; +import org.adempiere.webui.util.IServerPushCallback; +import org.adempiere.webui.util.ServerPushTemplate; import org.adempiere.webui.window.WTask; +import org.compiere.Adempiere; import org.compiere.model.MQuery; import org.compiere.model.MTask; import org.compiere.util.Env; import org.compiere.util.WebDoc; import org.compiere.wf.MWorkflow; +import org.zkoss.image.AImage; import org.zkoss.util.media.AMedia; import org.zkoss.zk.ui.Component; import org.zkoss.zul.Iframe; @@ -44,6 +50,7 @@ import org.zkoss.zul.Tabpanels; */ public abstract class TabbedDesktop extends AbstractDesktop { + private static final String IN_PROGRESS_IMAGE = "~./zk/img/progress3.gif"; protected WindowContainer windowContainer; public TabbedDesktop() { @@ -109,21 +116,12 @@ public abstract class TabbedDesktop extends AbstractDesktop { /** * + * @param * @param windowId * @return ADWindow */ public ADWindow openWindow(int windowId) { - ADWindow adWindow = new ADWindow(Env.getCtx(), windowId); - - DesktopTabpanel tabPanel = new DesktopTabpanel(); - if (adWindow.createPart(tabPanel) != null) { - preOpenNewTab(); - windowContainer.addWindow(tabPanel, adWindow.getTitle(), true); - return adWindow; - } else { - //user cancel - return null; - } + return openWindow(windowId, null); } /** @@ -133,17 +131,16 @@ public abstract class TabbedDesktop extends AbstractDesktop { * @return ADWindow */ public ADWindow openWindow(int windowId, MQuery query) { - ADWindow adWindow = new ADWindow(Env.getCtx(), windowId, query); + final ADWindow adWindow = new ADWindow(Env.getCtx(), windowId, query); - DesktopTabpanel tabPanel = new DesktopTabpanel(); - if (adWindow.createPart(tabPanel) != null) { - preOpenNewTab(); - windowContainer.addWindow(tabPanel, adWindow.getTitle(), true); - return adWindow; - } else { - //user cancel - return null; - } + final DesktopTabpanel tabPanel = new DesktopTabpanel(); + final Tab tab = windowContainer.addWindow(tabPanel, adWindow.getTitle(), true); + tab.setImage(IN_PROGRESS_IMAGE); + tab.setClosable(false); + OpenWindowRunnable runnable = new OpenWindowRunnable(adWindow, tab, tabPanel); + Adempiere.getThreadPoolExecutor().schedule(runnable, 100, TimeUnit.MICROSECONDS); + + return adWindow; } /** @@ -220,14 +217,14 @@ public abstract class TabbedDesktop extends AbstractDesktop { */ public void showZoomWindow(int AD_Window_ID, MQuery query) { - ADWindow wnd = new ADWindow(Env.getCtx(), AD_Window_ID, query); + final ADWindow wnd = new ADWindow(Env.getCtx(), AD_Window_ID, query); - DesktopTabpanel tabPanel = new DesktopTabpanel(); - if (wnd.createPart(tabPanel) != null) - { - preOpenNewTab(); - windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true); - } + final DesktopTabpanel tabPanel = new DesktopTabpanel(); + final Tab tab = windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true); + tab.setImage(IN_PROGRESS_IMAGE); + tab.setClosable(false); + OpenWindowRunnable runnable = new OpenWindowRunnable(wnd, tab, tabPanel); + Adempiere.getThreadPoolExecutor().schedule(runnable, 100, TimeUnit.MICROSECONDS); } /** @@ -335,4 +332,45 @@ public abstract class TabbedDesktop extends AbstractDesktop { protected void preOpenNewTab() { } + + class OpenWindowRunnable extends ContextRunnable { + + private final ADWindow adWindow; + private final Tab tab; + private final DesktopTabpanel tabPanel; + + protected OpenWindowRunnable(ADWindow adWindow, Tab tab, DesktopTabpanel tabPanel) { + this.adWindow = adWindow; + this.tab = tab; + this.tabPanel = tabPanel; + } + + @Override + protected void doRun() { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + } + ServerPushTemplate template = new ServerPushTemplate(windowContainer.getComponent().getDesktop()); + template.executeAsync(new IServerPushCallback() { + @Override + public void updateUI() { + preOpenNewTab(); + if (adWindow.createPart(tabPanel) != null ) { + tab.setImage(null); + tab.setClosable(true); + if (adWindow.getMImage() != null) { + try { + AImage aImage = adWindow.getAImage(); + tab.setImageContent(aImage); + } catch (IOException e) { + } + } + } else { + tab.onClose(); + } + } + }); + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/WebUIResourceFinder.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/WebUIResourceFinder.java index d14f3c3b8f..744f094e9e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/WebUIResourceFinder.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/util/WebUIResourceFinder.java @@ -31,6 +31,17 @@ public class WebUIResourceFinder implements IResourceFinder { if (url == null && name.startsWith("org/compiere/images")) { String t = name.substring("org/compiere/".length()); url = WebUIActivator.getBundleContext().getBundle().getEntry(t); + if (url == null && t.endsWith(".gif")) { + t = t.replace(".gif", ".png"); + url = WebUIActivator.getBundleContext().getBundle().getEntry(t); + } + } else if (url == null && name.startsWith("/org/compiere/images")) { + String t = name.substring("/org/compiere/".length()); + url = WebUIActivator.getBundleContext().getBundle().getEntry(t); + if (url == null && t.endsWith(".gif")) { + t = t.replace(".gif", ".png"); + url = WebUIActivator.getBundleContext().getBundle().getEntry(t); + } } return url; }