Process dialog enhancement:

* Fixed display issues for long process log
* Drop the use of server push to reduce resource usage and slight performance improvement
* Use custom progress window with adempiere localization support
* Fixed css of the button
Link to SF Tracker: http://sourceforge.net/support/tracker.php?aid=2979511
This commit is contained in:
Heng Sin Low 2010-03-30 17:24:58 +00:00
parent 37f28623cc
commit 6da5888e6a
3 changed files with 173 additions and 144 deletions

View File

@ -0,0 +1,47 @@
/******************************************************************************
* Copyright (C) 2010 Low Heng Sin *
* Copyright (C) 2010 Idalica Corporation *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.apps;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.Window;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Image;
/**
*
* @author hengsin
*
*/
public class BusyDialog extends Window {
private static final long serialVersionUID = -779475945298887887L;
public BusyDialog() {
super();
Hbox box = new Hbox();
box.setStyle("padding: 5px");
appendChild(box);
box.appendChild(new Label(Msg.getMsg(Env.getCtx(), "Processing")));
Image image = new Image();
box.appendChild(image);
image.setHeight("16px");
image.setWidth("16px");
image.setSrc("~./zk/img/progress3.gif");
setPosition("center");
setShadow(true);
}
}

View File

@ -13,7 +13,6 @@ import java.util.logging.Level;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.VerticalBox;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.process.WProcessInfo;
@ -30,12 +29,14 @@ import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.DesktopUnavailableException;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zkex.zul.Borderlayout;
import org.zkoss.zkex.zul.Center;
import org.zkoss.zkex.zul.North;
import org.zkoss.zkex.zul.South;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Html;
@ -76,9 +77,13 @@ import com.lowagie.text.pdf.PdfWriter;
public class ProcessDialog extends Window implements EventListener//, ASyncProcess
{
/**
*
* generate serial version ID
*/
private static final long serialVersionUID = 4940020114091318176L;
private static final long serialVersionUID = 5545731871518761455L;
private static final String MESSAGE_DIV_STYLE = "max-height: 150pt; overflow: auto";
private Div messageDiv;
private Center center;
private North north;
/**
@ -114,16 +119,29 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
} // ProcessDialog
private void initComponents() {
VerticalBox vbox = new VerticalBox();
vbox.setWidth("100%");
vbox.setSpacing("10px");
Div div = new Div();
this.setStyle("position: absolute; width: 100%; height: 100%");
Borderlayout layout = new Borderlayout();
layout.setStyle("position: absolute; width: 100%; height: 100%; border: none;");
messageDiv = new Div();
message = new Html();
div.appendChild(message);
vbox.appendChild(div);
messageDiv.appendChild(message);
messageDiv.setStyle(MESSAGE_DIV_STYLE);
north = new North();
north.appendChild(messageDiv);
layout.appendChild(north);
north.setAutoscroll(true);
north.setStyle("border: none;");
centerPanel = new Panel();
vbox.appendChild(centerPanel);
div = new Div();
center = new Center();
layout.appendChild(center);
center.appendChild(centerPanel);
center.setFlex(true);
center.setAutoscroll(true);
center.setStyle("border: none");
Div div = new Div();
div.setAlign("center");
Hbox hbox = new Hbox();
String label = Msg.getMsg(Env.getCtx(), "Start");
@ -131,6 +149,7 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
bOK.setImage("/images/Ok16.png");
bOK.setId("Ok");
bOK.addEventListener(Events.ON_CLICK, this);
bOK.setSclass("action-button");
hbox.appendChild(bOK);
label = Msg.getMsg(Env.getCtx(), "Cancel");
@ -138,11 +157,15 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
btn.setImage("/images/Cancel16.png");
btn.setId("Cancel");
btn.addEventListener(Events.ON_CLICK, this);
hbox.appendChild(btn);
btn.setSclass("action-button");
hbox.appendChild(btn);
div.appendChild(hbox);
vbox.appendChild(div);
this.appendChild(vbox);
div.setStyle("padding: 10px");
South south = new South();
layout.appendChild(south);
south.appendChild(div);
this.appendChild(layout);
}
private int m_WindowNo;
@ -168,8 +191,8 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
private ProcessInfo m_pi = null;
private boolean m_isLocked = false;
private boolean isResult;
private String initialMessage;
private BusyDialog progressWindow;
/**
@ -208,13 +231,16 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
+ "FROM AD_Process p, AD_Process_Trl t "
+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
+ " AND p.AD_Process_ID=? AND t.AD_Language=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
PreparedStatement pstmt = DB.prepareStatement(sql, null);
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, m_AD_Process_ID);
if (trl)
pstmt.setString(2, Env.getAD_Language(m_ctx));
ResultSet rs = pstmt.executeQuery();
rs = pstmt.executeQuery();
if (rs.next())
{
m_Name = rs.getString(1);
@ -233,15 +259,16 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
if (!rs.wasNull())
m_messageText.append("<p>").append(s).append("</p>");
}
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return false;
}
finally
{
DB.close(rs, pstmt);
}
if (m_Name == null)
return false;
@ -277,33 +304,18 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
{
m_pi.setPrintPreview(true);
if (!getDesktop().isServerPushEnabled())
getDesktop().enableServerPush(true);
this.lockUI(m_pi);
Runnable runnable = new Runnable() {
public void run() {
//get full control of desktop
org.zkoss.zk.ui.Desktop desktop = ProcessDialog.this.getDesktop();
try {
Executions.activate(desktop);
try {
ProcessCtl.process(null, m_WindowNo, parameterPanel, m_pi, null);
} finally{
unlockUI(m_pi);
//release full control of desktop
Executions.deactivate(desktop);
}
} catch (DesktopUnavailableException e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
} catch (InterruptedException e) {
log.log(Level.WARNING, e.getLocalizedMessage(), e);
}
}
};
new Thread(runnable).start();
Clients.response(new AuEcho(this, "runProcess", null));
}
public void runProcess() {
try {
ProcessCtl.process(null, m_WindowNo, parameterPanel, m_pi, null);
} finally {
unlockUI(m_pi);
}
}
public void onEvent(Event event) {
Component component = event.getTarget();
if (component instanceof Button) {
@ -325,54 +337,28 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
m_isLocked = true;
if (Executions.getCurrent() != null)
Clients.showBusy("Processing...", true);
else
{
try {
//get full control of desktop
Executions.activate(this.getDesktop());
try {
Clients.showBusy("Processing...", true);
} catch(Error ex){
throw ex;
} finally{
//release full control of desktop
Executions.deactivate(this.getDesktop());
}
} catch (Exception e) {
log.log(Level.WARNING, "Failed to lock UI.", e);
}
}
showBusyDialog();
}
private void showBusyDialog() {
progressWindow = new BusyDialog();
progressWindow.setPage(this.getPage());
progressWindow.doHighlighted();
}
public void unlockUI(ProcessInfo pi) {
if (!m_isLocked) return;
m_isLocked = false;
if (Executions.getCurrent() != null)
{
Clients.showBusy(null, false);
updateUI(pi);
hideBusyDialog();
updateUI(pi);
}
private void hideBusyDialog() {
if (progressWindow != null) {
progressWindow.dispose();
progressWindow = null;
}
else
{
try {
//get full control of desktop
Executions.activate(this.getDesktop());
try {
updateUI(pi);
Clients.showBusy(null, false);
} catch(Error ex){
throw ex;
} finally{
//release full control of desktop
Executions.deactivate(this.getDesktop());
}
} catch (Exception e) {
log.log(Level.WARNING, "Failed to update UI upon unloc.", e);
}
}
}
private void updateUI(ProcessInfo pi) {
@ -383,12 +369,15 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
m_messageText.append(pi.getLogInfo(true));
message.setContent(m_messageText.toString());
bOK.setLabel("");
bOK.setLabel("");
m_ids = pi.getIDs();
//no longer needed, hide to give more space to display log
//move message div to center to give more space to display potentially very long log info
centerPanel.detach();
messageDiv.detach();
messageDiv.setStyle("");
north.setVisible(false);
center.appendChild(messageDiv);
invalidate();
Clients.response(new AuEcho(this, "onAfterProcess", null));
@ -399,7 +388,7 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
//
afterProcessTask();
// Close automatically
// Close automatically
if (m_IsReport && !m_pi.isError())
this.dispose();
@ -438,7 +427,7 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
m_messageText.append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintShipments")).append("</p>");
message.setContent(m_messageText.toString());
Clients.showBusy("Processing...", true);
showBusyDialog();
Clients.response(new AuEcho(this, "onPrintShipments", null));
} // printInvoices
@ -479,14 +468,14 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
}
document.close();
Clients.showBusy(null, false);
hideBusyDialog();
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(outFile));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
} else if (pdfList.size() > 0) {
Clients.showBusy(null, false);
hideBusyDialog();
try {
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(pdfList.get(0)));
SessionManager.getAppDesktop().showWindow(win, "center");
@ -508,7 +497,7 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
return;
m_messageText.append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintInvoices")).append("</p>");
message.setContent(m_messageText.toString());
Clients.showBusy("Processing...", true);
showBusyDialog();
Clients.response(new AuEcho(this, "onPrintInvoices", null));
} // printInvoices
@ -547,7 +536,7 @@ public class ProcessDialog extends Window implements EventListener//, ASyncProce
}
document.close();
Clients.showBusy(null, false);
hideBusyDialog();
Window win = new SimplePDFViewer(this.getTitle(), new FileInputStream(outFile));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e) {

View File

@ -37,8 +37,6 @@ import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.DesktopUnavailableException;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
@ -61,9 +59,9 @@ import org.zkoss.zul.Html;
public class ProcessModalDialog extends Window implements EventListener
{
/**
*
* generated serial version ID
*/
private static final long serialVersionUID = 8828804363347622789L;
private static final long serialVersionUID = -7109707014309321369L;
private boolean m_autoStart;
/**
@ -133,7 +131,8 @@ public class ProcessModalDialog extends Window implements EventListener
Div div = new Div();
message = new Html();
div.appendChild(message);
vbox.appendChild(message);
div.setStyle("max-height: 150pt; overflow: auto;");
vbox.appendChild(div);
centerPanel = new Panel();
vbox.appendChild(centerPanel);
div = new Div();
@ -174,8 +173,7 @@ public class ProcessModalDialog extends Window implements EventListener
private ProcessParameterPanel parameterPanel = null;
private ProcessInfo m_pi = null;
private ProcessRunnable m_processRunnable;
private BusyDialog progressWindow;
/**
* Set Visible
@ -223,13 +221,16 @@ public class ProcessModalDialog extends Window implements EventListener
+ "FROM AD_Process p, AD_Process_Trl t "
+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
+ " AND p.AD_Process_ID=? AND t.AD_Language=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
PreparedStatement pstmt = DB.prepareStatement(sql, null);
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, m_pi.getAD_Process_ID());
if (trl)
pstmt.setString(2, Env.getAD_Language(m_ctx));
ResultSet rs = pstmt.executeQuery();
rs = pstmt.executeQuery();
if (rs.next())
{
m_Name = rs.getString(1);
@ -247,15 +248,16 @@ public class ProcessModalDialog extends Window implements EventListener
if (!rs.wasNull())
m_messageText.append("<p>").append(s).append("</p>");
}
rs.close();
pstmt.close();
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return false;
}
finally
{
DB.close(rs, pstmt);
}
if (m_Name == null)
return false;
@ -263,7 +265,6 @@ public class ProcessModalDialog extends Window implements EventListener
this.setTitle(m_Name);
message.setContent(m_messageText.toString());
// Move from APanel.actionButton
m_pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
m_pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
@ -301,51 +302,43 @@ public class ProcessModalDialog extends Window implements EventListener
if (m_ASyncProcess != null) {
m_ASyncProcess.lockUI(m_pi);
} else {
Clients.showBusy(null, true);
Clients.showBusy(null, false);
}
m_processRunnable = new ProcessRunnable(Executions.getCurrent().getDesktop());
showBusyDialog();
//use echo, otherwise lock ui wouldn't work
Clients.response(new AuEcho(this, "runASyncProcess", null));
Clients.response(new AuEcho(this, "runProcess", null));
}
private void showBusyDialog() {
progressWindow = new BusyDialog();
progressWindow.setPage(this.getPage());
progressWindow.doHighlighted();
}
/**
* internal use, don't call this directly
*/
public void runASyncProcess() {
new Thread(m_processRunnable).start();
}
private class ProcessRunnable implements Runnable {
private org.zkoss.zk.ui.Desktop desktop;
ProcessRunnable(org.zkoss.zk.ui.Desktop desktop) {
this.desktop = desktop;
}
public void run() {
//get full control of desktop
try {
Executions.activate(desktop);
try {
ProcessCtl.process(null, m_WindowNo, parameterPanel, m_pi, null);
} finally {
dispose();
if (m_ASyncProcess != null) {
m_ASyncProcess.unlockUI(m_pi);
} else {
Clients.showBusy(null, false);
}
//release full control of desktop
Executions.deactivate(desktop);
}
} catch (DesktopUnavailableException e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
} catch (InterruptedException e) {
log.log(Level.WARNING, e.getLocalizedMessage(), e);
}
public void runProcess() {
try {
ProcessCtl.process(null, m_WindowNo, parameterPanel, m_pi, null);
} finally {
dispose();
if (m_ASyncProcess != null) {
m_ASyncProcess.unlockUI(m_pi);
}
hideBusyDialog();
}
}
private void hideBusyDialog() {
if (progressWindow != null) {
progressWindow.dispose();
progressWindow = null;
}
}
/**
* handle events
*/