Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Canvas.showPrintPreview does not print Labels with absolute position correctly

    I have a Canvas with a child image in the background and some child Labels in the foreground (differnt ZIndex). The positions of the children are set with setTop(), setLeft(), setWidth() and setHeight(). When I print the Canvas with Canvas.showPrintPreview the print preview and print looks weird (see attachements). The problem occurs in IE, firefox and chrome (I have not tested Safari so far). The developer console says that I am using
    version SC_SNAPSHOT-2011-10-03/PowerEdition Deployment (built 2011-10-03)

    How can I print the Canvas correctly?

    Here is the code

    Code:
    public class PrintBug implements EntryPoint
    {
        private Canvas m_MainCanvas;
    
        /**
         * This is the entry point method.
         */
        public void onModuleLoad()
        {
    
            int width = 640;
            int height = 480;
    
            m_MainCanvas = new Canvas();
            m_MainCanvas.setWidth(width);
            m_MainCanvas.setHeight(height);
    
            int imageWidth = 400;
            int imageHeight = 300;
    
            Img image = new Img("IMG_20111028_133201.jpg");
            image.setLeft((width - imageWidth) / 2);
            image.setTop((height - imageHeight) / 2);
            image.setWidth(imageWidth);
            image.setHeight(imageHeight);
            image.setZIndex(1);
    
            m_MainCanvas.addChild(image);
    
            for(int x = 0; x < 640; x += 80)
            {
                for(int y = 0; y < 480; y += 80)
                {
                    Label label = new Label(x + "," + y);
                    label.setMargin(1);
                    label.setBorder("1px solid black");
                    label.setLeft(x);
                    label.setTop(y);
                    label.setWidth(80);
                    label.setHeight(80);
                    label.setZIndex(2);
                    m_MainCanvas.addChild(label);
                }
            }
    
            HLayout layout = new HLayout();
    
            layout.addMember(createButtons());
            layout.addMember(m_MainCanvas);
    
            RootPanel.get().add(layout);
    
            layout.draw();
    
        }
    
        private VLayout createButtons()
        {
            Button button = new Button("Print");
    
            button.addClickHandler(new ClickHandler()
            {
                @SuppressWarnings("synthetic-access")
                public void onClick(final ClickEvent event)
                {
                    Canvas.showPrintPreview(m_MainCanvas);
                }
            });
    
    
            VLayout ret = new VLayout();
            ret.setMargin(5);
            ret.addMember(button);
            return ret;
        }
    }
    Attached Files

    #2
    Hi Rhierlmeier,
    Absolute positioning like this is not supported in the print view.
    There are a couple of reasons for this but in short the actual positioning and sizing of components in printed does not behave as expected - components typically would not be sized and positioned to fit within a (printed) page view leading to odd truncations etc.
    We therefore print components in a "logical summary" type view rather than attempting to replicate specified absolute positioning.

    A couple of options that may resolve this for you would be to use nested layouts to position your labels (these are rendered as native HTML tables within the output which handles formatting them to fit the printed page), or an existing component such as the TileGrid.
    You may also be able to use the backgroundImage attribute to render an image behind the 'tiles', though browser preferences can be set to avoid printing background images.

    If you can't come up with a way to achieve the printing appearance you need, let us know and we'll take a look.

    Comment


      #3
      In the documentation of the Canvas print methods I can not find any hint that printing of absolutely positioned widgets is not supported.

      In many cases it is not possible to find any documentation about restrictions of smartclient functionality.

      Comment


        #4
        It's a general limitation of HTML printing, not specific to SmartClient. It's one of the reasons so many sites have a special printable view.

        Comment


          #5
          I have modified my sample project accordingly. I use now combinations of VLayout and HLayout to position the labels. But even with this approach the print out looks strange. In the HTML view the labels are on the correct position but not in the print out. It seems that the width and height of the labels are not considered.

          Code:
          public class PrintBug implements EntryPoint
          {
              private VLayout m_MainCanvas;
          
              public void onModuleLoad()
              {
                  int width = 640;
                  int height = 480;
          
                  m_MainCanvas = new VLayout();
                  m_MainCanvas.setWidth(width);
                  m_MainCanvas.setHeight(height);
          
                  for(int y = 0; y < height; y += 80)
                  {
                      HLayout hl = new HLayout();
                      for(int x = 0; x < width; x += 80)
                      {
                          Label label = new Label(x + "," + y);
                          label.setMargin(1);
                          label.setBorder("1px solid black");
                          label.setWidth(80);
                          label.setHeight(80);
                          hl.addMember(label);
                      }
                      m_MainCanvas.addMember(hl);
                  }
          
                  HLayout layout = new HLayout();
          
                  layout.addMember(createButtons());
                  layout.addMember(m_MainCanvas);
          
                  RootPanel.get().add(layout);
          
                  layout.draw();
          
              }
          
              private VLayout createButtons()
              {
                  Button button = new Button("Print");
          
                  button.addClickHandler(new ClickHandler()
                  {
                      @SuppressWarnings("synthetic-access")
                      public void onClick(final ClickEvent event)
                      {
                          Canvas.showPrintPreview(m_MainCanvas);
                      }
                  });
          
                  Button consoleButton = new Button("Console");
                  consoleButton.addClickHandler(new ClickHandler()
                  {
          
                      public void onClick(final ClickEvent event)
                      {
                          SC.showConsole();
                      }
                  });
          
                  VLayout ret = new VLayout();
                  ret.setMargin(5);
                  ret.addMember(button);
                  ret.addMember(consoleButton);
                  return ret;
              }
          }
          As I you can see in the original post I have to display an image behind the labels. You proposed to display it as background image. For my use case I have to scale and center the image to the size of the m_MainCanvas respecting the aspect ratio of the image. Is this possible with a background image? If it is possible please provide me a short example.

          If it is not possible please tell me an alternative.


          Thank you in advance

          Richard

          Comment


            #6
            In general, you cannot get much precision out of browser printing. In effect, to render the page for printing, the HTML is put into an internal pseudo-page of unknown size, and with layout behaviors that are not the same as a normal page.

            We haven't seen the image and text positioning you're trying to achieve, but if it's an absolute requirement, the best approach might be to experiment directly with direct HTML use rather than Labels, then provide HTML that to the printing system by placing it inside an HTMLFlow.

            Comment


              #7
              I do not agree. When implementing the same view with plain html/css the printout looks quite good (at least with IE and and Chrome). It must be a problem of the Canvas.printComponents function.

              Comment


                #8
                We're not sure what you're disagreeing with - we still haven't seen the target appearance you're going for, just examples of the wrong appearance, so this has forced us to give general advice rather than a specific approach.

                As a general tip for working with support (actually with any support organization), you should make your questions as specific as possible, otherwise you will force support to respond with general advice, as happened here.

                Happily, our recommendation provided a solution anyway - since you now have a straight HTML representation of what you want, you can just put it in an HTMLFlow as previously recommended.

                Comment


                  #9
                  However, for this solution I do no longer need smartclient.

                  Comment


                    #10
                    If this is the only thing you need to print, yes. Otherwise you will want to combine your HTML with the SmartClient-generated HTML by placing your custom HTML into an HTMLFlow and printing the combined set of components.

                    Comment

                    Working...
                    X