1

I have been trying to understand JViewports and tried to work with one. I have been using this gentleman's class, which just extends the JViewport class.

If I want to set the viewport in the middle of a 6480*4860 object implementing the JPanel Class, how come this code gives me a blank view, even if, upon debugging,I have confirmation that the class implementing JPanel I am using has been added to the view? Am I completely mixed up in my calls to the different methods or in my comprehension of the coordinates used and their meaning? And one more : Does calling

    v.setOpaque(true);

set only the viewport opaque or it will set all its children too? I guess I will quickly know the answer to this one if I figure out how to properly use viewports.

public myProgram(){ 
    ...

    myCustomJPanel = new MyCustonJPanel();
    myCustomJPanel.setBackground(Color.WHITE);
    GrabbableViewport v = new GrabbableViewport();
    v.setViewSize(new Dimension(720,540));
    v.setViewPosition(new Point(720,540));
    v.setView(myCustomJPanel);
    v.setViewPosition(new Point(720,540));
    v.setLocation(43, 5);
    appropriateParentPanel.add(v);
}

Here is the class I am trying to use. It takes much more space for this short question, but formatted text should please you more than plain text! If I am not mistaken, though, the problem should not come from here.

// Copyright (c) 2006 - 2008, Markus Strauch.
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 
// * Redistributions of source code must retain the above copyright notice, 
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, 
// this list of conditions and the following disclaimer in the documentation 
// and/or other materials provided with the distribution.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
// THE POSSIBILITY OF SUCH DAMAGE.

package net.sf.sdedit.ui.components;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JViewport;
import javax.swing.event.MouseInputListener;

/**
 * A <tt>GrabbableViewport</tt> is a <tt>JViewport</tt> that scrolls its
 * view when the mouse is dragged. While the mouse is being dragged, its cursor
 * is set to a &quot;grabbing hand&quot;, like in applications such as Acrobat
 * Reader.
 * 
 * @author Markus Strauch
 * 
 */
public class GrabbableViewport extends JViewport implements MouseInputListener {

    private static Cursor HAND = new Cursor(Cursor.MOVE_CURSOR);

    private static Cursor DFLT = new Cursor(Cursor.DEFAULT_CURSOR);

    public static void setHandCursorIcon(ImageIcon icon) {
        Image grabbingHand = icon.getImage();
        HAND = Toolkit.getDefaultToolkit().createCustomCursor(grabbingHand,
                new Point(0, 0), "hand cursor");
    }

    /**
     * Constructor.
     */
    public GrabbableViewport () {
        super ();
    }

    private Rectangle rect; 

    private Point point;    

    private JComponent view;    

    public void setView(Component view) {
        super.setView(view);
        if (this.view != view) {
            if (this.view != null) {
                this.view.removeMouseListener(this);
                this.view.removeMouseMotionListener(this);
            }
            if (view != null) {
                view.addMouseListener(this);
                view.addMouseMotionListener(this);
            }
            this.view = (JComponent) view;
        }
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        view.setCursor(HAND);
        //((Component) e.getSource()).setCursor(HAND);
        rect = getViewRect();
        point = screenLocation(e);
    }

    private Point screenLocation(MouseEvent e) {
        Point root = view.getLocationOnScreen();
        Point mouse = e.getPoint();
        if (rect != null && !rect.contains(mouse)) {
            return null;
        }
        Point screenPoint = new Point(root.x + mouse.x, root.y + mouse.y);
        return screenPoint;
    }

    public void mouseReleased(MouseEvent e) {
        view.setCursor(DFLT);
        scrollTo(screenLocation(e));
        clear();
    }

    public void mouseDragged(MouseEvent e) {
        scrollTo(screenLocation(e));
    }

    public void mouseMoved(MouseEvent e) {
    }

    private void scrollTo(Point newPoint) {
        if (point != null && newPoint != null && rect != null) {
            int deltaX = point.x - newPoint.x;
            int deltaY = point.y - newPoint.y;
            rect.x = rect.x + deltaX;
            rect.y = rect.y + deltaY;
            ((JComponent) getView()).scrollRectToVisible(rect);
                point = newPoint;
        }
    }

            private void clear() {
                rect = null;
            point = null;
        }
    }

I could give you a sscce but I think this should be simple enough, although I can piece together some example quickly if you ask.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 1. see answrer by @kleopatra [about similair issue](http://stackoverflow.com/a/15877630/714968), 2. otherwise post and [SSCCE](http://sscce.org/), short, runnable, compilable, just about a.m. issue 3. and without (I'd be remove) GrabbableViewport, because hasn't nothing to do with centering JPanel inside JScrollPane, or with JPanels coordinates 4. JViewport isn't JComponent or Container too, use todays JLayer (Java7) instead 5. mis there viewPort.setScrollMode, I'm don't to suggest to use JViewport as container [maybe will help you](http://stackoverflow.com/q/8614972/714968), use GlassPane – mKorbel Apr 18 '13 at 20:42
  • Thanks ummm... That answer is kind of hard to understand. I'll try trashgod's solution then come back to you if it doesn't work. –  Apr 20 '13 at 21:36
  • 1
    @mKorbel: gabarise reports success using `GrabbableViewport` as the `JViewport` in a `JScrollPane`. I think `JViewport` _is_ a `JComponent`, as well as a `Container`; sorry if I misunderstand. – trashgod Apr 23 '13 at 14:14
  • @trashgod agreed I love JViewport (delaying caused low battery on my wireless keyboard:-) – mKorbel Apr 23 '13 at 17:05

1 Answers1

2

Because GrabbableViewport extends JViewport, I'd guess that you're supposed to use it in a JScrollPane, as shown here. If not, the example may help you construct an sscce using ScrollPanePaint.MyPanel.

myCustomJPanel = new MyCustonJPanel();
GrabbableViewport v = new GrabbableViewport();
v.setView(myCustomJPanel);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewport(v);
enclosingContainer.add(scrollPane);

See also this related example the leverages the existing JScrollPane actions.

Using setOpaque(true) is a promise to paint every pixel, as discussed here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks for both replies, I'll try that out tomorrow and report on that! –  Apr 20 '13 at 21:32
  • Thanks, good to know; I usually handle this in `paintComponent()`, but `GrabbableViewport` may be worth closer study. – trashgod Apr 23 '13 at 13:54