0

Can't get Panel real size when it is maximized

asked 2010-08-24 21:50:14 +0800

javich gravatar image javich
45 2

updated 2010-08-24 22:13:28 +0800

Hi all,

I am struggling to get the size of a panel when it is maximized.

Let's focus on secondPanel.

-When I resize the browser window I use onClinetInfo event to set panel size and then I can use redrawChart() to get the new size of secondPanel
-When I use the maximize button in secondPanel also I am able to get the size of secondPanel but,

-When I maximize secondPanel and then resize the browser window then the size of secondPanel will never change.

For example in the log below, the first line shows the value after the panel was maximized, second line shows the new value of the desktop after resizing and then the third line shows that the panel is reporting same old size no matter the desktop is smaller, forth and fifth line show the same problem when resizing the browser window again. Visually the panel border is changed accordingly though.

12:54:06,567 DEBUG  company.ui.TestController.redrawChart(110): secondPanel dimensions 800px x 371px
12:54:19,052 DEBUG  company.ui.TestController.onClientInfo$window(57): Desktop size is 745 x 481
12:54:19,052 DEBUG  company.ui.TestController.redrawChart(110): secondPanel dimensions 800px x 371px
12:54:30,239 DEBUG  company.ui.TestController.onClientInfo$window(57): Desktop size is 730 x 483
12:54:30,239 DEBUG  company.ui.TestController.redrawChart(110): secondPanel dimensions 800px x 371px


I tried to use the onSize event but that will only work when resizing the panel directly dragging a corner, it will not notify anything on browser window resize.

Is this a bug or I am missing an event or property that will notify accurately the size of the panel?

The reason I want to have the panel size is that the Chart component does not update at all when its parent container changes its size so I have to change it manually. On this regard I am pretty sure this is a bug of the chart component and I hope I don't receive an RTFM but how should I proceed to lodge a bug for that? I think all the code below will help for that.


I am using ZK EE 5.0.3, code below for your reference and assistance.

Thanks,
Javier.

<?page id="index" title="XXX"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>

<window xmlns:h="http://www.w3.org/1999/xhtml" id="window" apply="${testController}">
	<h:div id="XXX">
		<h:div id="Content">
			<h:div id="portal">
				<portallayout style="padding: 5px" maximizedMode="whole" >
					<portalchildren id="leftColumn" hflex="5">
						<panel id="mainPanel" style="margin:5px" title=" " border="none" maximizable="true">
							<panelchildren>
								<tabbox height="100%">
									<tabs>
										<tab id="googlePanel" label="Google" />
										<tab label="Yahoo" />
									</tabs>
									<tabpanels>
										<tabpanel>
											<iframe height="100%" width="100%"
												src="http://www.google.com" />
										</tabpanel>
										<tabpanel>
											<iframe height="100%" width="100%"
												src="http://www.yahoo.com" />
										</tabpanel>
									</tabpanels>
								</tabbox>
							</panelchildren>
						</panel>
					</portalchildren>
					<portalchildren id="rightColumn" hflex="5">
						<panel id="secondPanel" style="margin:5px 5px 10px 5px" title="Second Panel"
							border="normal" collapsible="true" maximizable="true" movable="true" sizable="true">
							<panelchildren>
								<chart id="chart" type="time_series" dateFormat="dd MMM" period="minute"  />
							</panelchildren>
						</panel>
						<panel id="thirdPanel" style="margin:5px" title="Rainfall (mm)" border="normal"
							collapsible="true">
							<panelchildren>3rd Panel goes here!</panelchildren>
						</panel>
					</portalchildren>
				</portallayout>
			</h:div>
		</h:div>
	</h:div>
</window>

package company.ui;

import java.io.Serializable;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.zk.ui.Path;
import org.zkoss.zk.ui.event.ClientInfoEvent;
import org.zkoss.zk.ui.event.MaximizeEvent;
import org.zkoss.zk.ui.event.SizeEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Chart;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Window;

public class TestController extends GenericForwardComposer
{
    private static final long serialVersionUID = 7585891004513212483L;

    private static final Logger logger = LoggerFactory.getLogger(TestController.class);
    
    private Panel secondPanel;

    private Panel mainPanel;

    private Panel thirdPanel;

    private Chart chart;

    private Window window;

    private IndexModel model;

    private boolean isMaximized = false;

    public TestController()
    {
        model = new IndexModel();
    }

    /**
     * Records the desktop dimensions in the session.
     * 
     * @param event
     *            the <code>ClientInfoEvent</code> containing the desktop dimensions
     */
    public void onClientInfo$window(ClientInfoEvent event)
    {
        int newDesktopWidth = event.getDesktopWidth();
        int newDesktopHeight = event.getDesktopHeight();

        if (newDesktopWidth != model.getDesktopWidth() || newDesktopHeight != model.getDesktopHeight())
        {
            model.setDesktopWidth(newDesktopWidth);
            model.setDesktopHeight(newDesktopHeight);
            logger.debug("Desktop size is {} x {}", newDesktopWidth, newDesktopHeight);
            redraw();
        }
    }

    public void onSize$secondPanel(SizeEvent event)
    {
        logger.trace("resized to {} x {}", event.getWidth(), event.getHeight());
    }

    public void onMaximize$secondPanel(MaximizeEvent event)
    {
        isMaximized = event.isMaximized();
        redrawChart();
    }

    public void onCreate$window()
    {
        logger.trace("Window path {}", Path.getPath(window));
        if (!model.isNewSession()) // onClientInfo won't be called so let's ensure all elements are properly updated on
                                   // screen
        {
            redraw();
        }
        model.setNewSession(false); // In any case this won't be a new session anymore
    }

    /**
     * 
     */
    private void redraw()
    {
        updatePanelsSize();
        redrawChart();
    }

    private void updatePanelsSize()
    {
        mainPanel.setHeight(model.getMapHeight());
        mainPanel.setWidth(model.getMapWidth());
        if (!isMaximized)
        {
            secondPanel.setHeight(model.getPanelHeight() + "px");
            secondPanel.setWidth(model.getPanelWidth() + "px"); // Set width or face exceptions later
        }
        thirdPanel.setHeight(model.getPanelHeight() + "px");
        thirdPanel.setWidth(model.getPanelWidth() + "px");
    }

    private void redrawChart()
    {
        chart.setDateFormat(isMaximized ? "dd MMM hh:mm" : "dd MMM");

        logger.debug("secondPanel dimensions {} x {}", secondPanel.getWidth(), secondPanel.getHeight());
        chart.setWidth(secondPanel.getWidth());
        int height = Integer.parseInt(StringUtils.stripEnd(secondPanel.getHeight(), "px")) - 30;
        chart.setHeight(height + "px");

        secondPanel.setDraggable("true");
    }
    
    class IndexModel implements Serializable
    {
        private static final long serialVersionUID = 3814336512152238891L;

        private boolean newSession = true;

        private int desktopHeight;

        private int desktopWidth;

        private int panelHeight;

        private int panelWidth;

        public String getChartHeight()
        {
            return (getPanelHeight() - 30) + "px";
        }

        public String getChartWidth()
        {
            return getPanelWidth() + "px";
        }

        public int getDesktopHeight()
        {
            return desktopHeight;
        }

        public int getDesktopWidth()
        {
            return desktopWidth;
        }

        public String getMapHeight()
        {
            return (getPortalHeight() - 40) + "px";
        }

        public String getMapWidth()
        {
            return (getPortalWidth() / 2 - 25) + "px";
        }

        public int getPanelHeight()
        {
            return panelHeight;
        }

        public int getPanelWidth()
        {
            return panelWidth;
        }

        public int getPortalHeight()
        {
            return desktopHeight - 120;
        }

        public int getPortalWidth()
        {
            return desktopWidth - 25;
        }

        private int pixelsToInt(String str)
        {
            int i = str.lastIndexOf("px");
            if (i > 0)
            {
                return Integer.valueOf(str.substring(0, i));
            }
            return Integer.valueOf(str);
        }

        public void resetPanelHeight()
        {
            panelHeight = getPortalHeight() / 2 - 25;
        }

        public void resetPanelWidth()
        {
            panelWidth = getPortalWidth() / 2 - 25;
        }

        public void setDesktopHeight(int height)
        {
            desktopHeight = height;
            resetPanelHeight();
        }

        public void setDesktopWidth(int width)
        {
            desktopWidth = width;
            resetPanelWidth();
        }

        public void setPanelHeight(String height)
        {
            panelHeight = pixelsToInt(height);
        }

        public void setPanelWidth(String width)
        {
            panelWidth = pixelsToInt(width);
        }

        public boolean isNewSession()
        {
            return newSession;
        }

        public void setNewSession(boolean newSession)
        {
            this.newSession = newSession;
        }
    }
}

delete flag offensive retag edit

3 Replies

Sort by ยป oldest newest

answered 2010-08-26 21:28:36 +0800

PeterKuo gravatar image PeterKuo
481 2

In order to reduce the network communication,
while you resize the browser, zk components will calculate the new width, height,
but it won't send back the changed size back to the server.

If you want to get the size, you may refer to client side programming:
http://docs.zkoss.org/wiki/Client_Side_Programming

listen to the onSize event, and send the info back to the server.

link publish delete flag offensive edit

answered 2010-08-30 02:03:40 +0800

javich gravatar image javich
45 2

Hi Peter,
Thanks for your reply.

I think your suggestion definitely will work but it come to my mind two things.

1. Doing client side programming to do this doesn't negate the purpose of ZK itself? I would think instead on a property to enable receiving these events that could be configured per component or per application.

2. Getting back to the basic scenario, I wouldn't be concerned to receive the onSize event on the server at all if the chart redrew correctly in the browser, isn't the chart supposed to resize as its parent container resizes? Am I missing some configuration for the chart?

Thanks,
Javier

link publish delete flag offensive edit

answered 2010-08-30 20:08:57 +0800

PeterKuo gravatar image PeterKuo
481 2

1. good idea. Please post to feature request.
2. Because chart is a generated jpg from server. Therefore it won't resize with browser automatically.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-08-24 21:50:14 +0800

Seen: 863 times

Last updated: Aug 30 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More