Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / October 2007

Tip: Looking for answers? Try searching our database.

JScrollPane resize / new location question

Thread view: 
lemmi - 10 Sep 2007 12:07 GMT
Hi there,

I have an application that uses a JScrollPane to display a component
that will be resized every once in a while. At the same time of the
resize I also want to set a new position for the resized component.
E.g. I am doubling the size of the  component and want to change its
location within the viewport so that the component stays centered.
What is the best way to accomplish this without seeing a flickering
behaviour?

Dirk
Roedy Green - 10 Sep 2007 13:10 GMT
>What is the best way to accomplish this without seeing a flickering
>behaviour?

You can't avoid a flicker. Swing is going to have to totally repaint
the window.

to avoid seeing intermediates, you might experiment with setVisible(
false ) and setVisible( true );
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

lemmi - 12 Sep 2007 11:05 GMT
On Sep 10, 2:10 pm, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:

> You can't avoid a flicker. Swing is going to have to totally repaint
> the window.

It is not really a flickering because of Swing repaints. The
flickering
is caused by the fact that the wrong region of the scrolled component
will
be shown first before the new region will be shown. Imagine having an
image
label inside a scrollpane. The user wants to zoom into the center of
the
image. Then the size of the label needs to be doubled (if that is the
scaling factor) and the location of the label needs to be adjusted so
that
the center of the image is shown in the center of the scrollpane.

Dirk
Andrew Thompson - 12 Sep 2007 12:23 GMT
>On Sep 10, 2:10 pm, Roedy Green <see_webs...@mindprod.com.invalid>
>wrote:
[quoted text clipped - 7 lines]
>will
>be shown first before the new region will be shown. Imagine ..

..posting an SSCCE, that allows others to see
an actual *example* of the behaviour on-screen.
<http://www.physci.org/codes/sscce.html>

I might have helped when I originally saw your post,
but without code, I could not be bothered speculating.

Signature

Andrew Thompson
http://www.athompson.info/andrew/

lemmi - 13 Sep 2007 12:06 GMT
> .posting an SSCCE, that allows others to see
> an actual *example* of the behaviour on-screen.
> <http://www.physci.org/codes/sscce.html>

Yes, yes, yes, I know an SSCCE helps in many situations but this
seemed to be "answerable" without one. Especially since it appears
to be someting that many UI developers have run into before. Anyway,
I will try to put one together.

Dirk

P.S.: Andrew, your homepage URL doesn't seem to work.

> --
> Andrew Thompsonhttp://www.athompson.info/andrew/
>
> Message posted via JavaKB.comhttp://www.javakb.com/Uwe/Forums.aspx/java-gui/200709/1
Andrew Thompson - 13 Sep 2007 12:22 GMT
...
>P.S.: Andrew, your homepage URL doesn't seem to work.

Yeah.. ongoing problems with the server.  (shrugs) Sh*t happens.

Signature

Andrew Thompson
http://www.athompson.info/andrew/

lemmi - 18 Oct 2007 15:27 GMT
So, I finally managed to write an SSCCE for this problem. Actually two
of them, which are almost identical. The first one creates a frame
with a scrollpane in its center and two zoom buttons at the bottom.
The user can zoom in and out, which causes the panel that is the
content of the scrollpane to be resized (double size or half size).
Both SSCCEs try to center the content after the user performed a zoom
in or a zoom out. The first SSCCE completely fails, because the call
to the center() method comes to early. The revalidation of the resized
panel happens asynchronously, so the center() method works on old
values. The second SSCCE uses a component listener so that the
centering can happen AFTER the panel has actually been resized. What
you will notice is that the revalidation causes a repaint and
scrollbar adjustment and then the centering causes another repaint and
scrollbar adjustment. This results in flickering behaviour. I was
wondering whether there is any better way, so that the resizing and
the repositioning can happen in one step. Any help is much
appreciated.

Dirk

1. SSCCE ------------------------------------------

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;

public class ScrollPaneTest {

    /**
    * Constructs the frame with the scrollpane in its center and a
button
    * panel, which contains the zoom buttons, in its bottom location.
    */
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        final TestPanel testPanel = new TestPanel();
        JScrollPane pane = new JScrollPane(testPanel);
        frame.add(pane);

        JPanel buttonPanel = new JPanel();
        JButton zoomIn = new JButton("Zoom In");
        JButton zoomOut = new JButton("Zoom Out");
        buttonPanel.add(zoomIn);
        buttonPanel.add(zoomOut);
        zoomIn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                testPanel.zoomIn();
            }
        });
        zoomOut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                testPanel.zoomOut();
            }
        });

        buttonPanel.add(zoomIn);
        buttonPanel.add(zoomOut);
        frame.add(BorderLayout.SOUTH, buttonPanel);

        frame.pack();
        frame.setVisible(true);
    }
}

/**
* This panel is the content of the scrollpane.
*/
class TestPanel extends JPanel {
    private Dimension ps = new Dimension(300, 300);

    @Override
    protected void paintComponent(Graphics g) {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        super.paintComponent(g);
        g.drawLine(0, 0, getWidth() - 1, getHeight() - 1);
        g.drawLine(0, getHeight() - 1, getWidth() - 1, 0);
    }

    @Override
    public Dimension getPreferredSize() {
        return ps;
    }

    public void zoomIn() {
        ps.setSize(ps.getWidth() * 2, ps.getHeight() * 2);
        revalidate();
        center();
    }

    public void zoomOut() {
        ps.setSize(ps.getWidth() / 2, ps.getHeight() / 2);
        revalidate();
        center();
    }

    private void center() {
        JViewport viewPort = (JViewport) getParent();
        viewPort.setViewPosition(new Point(ps.width -
viewPort.getSize().width, ps.height - viewPort.getSize().height));
    }
}

2. SSCCE ------------------------------------------

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;

public class ScrollPaneTestWithListener {

    /**
    * Constructs the frame with the scrollpane in its center and a
button
    * panel, which contains the zoom buttons, in its bottom location.
    */
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        final TestPanelWithListener testPanel = new TestPanelWithListener();
        JScrollPane pane = new JScrollPane(testPanel);
        frame.add(pane);

        JPanel buttonPanel = new JPanel();
        JButton zoomIn = new JButton("Zoom In");
        JButton zoomOut = new JButton("Zoom Out");
        buttonPanel.add(zoomIn);
        buttonPanel.add(zoomOut);
        zoomIn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                testPanel.zoomIn();
            }
        });
        zoomOut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                testPanel.zoomOut();
            }
        });

        buttonPanel.add(zoomIn);
        buttonPanel.add(zoomOut);
        frame.add(BorderLayout.SOUTH, buttonPanel);

        frame.pack();
        frame.setVisible(true);
    }
}

/**
* This panel is the content of the scrollpane. It implements a
component
* listener. It will cause a change of the viewport position when it
receives an
* event letting it know that its own size has changed.
*/
class TestPanelWithListener extends JPanel implements
ComponentListener {
    private Dimension ps = new Dimension(300, 300);

    public TestPanelWithListener() {
        // listens for changes to itself
        addComponentListener(this);
    }

    @Override
    protected void paintComponent(Graphics g) {
        try {
            // Artifically decrease repaint performance to simulate
            // real world application behaviour.
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        super.paintComponent(g);
        g.drawLine(0, 0, getWidth() - 1, getHeight() - 1);
        g.drawLine(0, getHeight() - 1, getWidth() - 1, 0);
    }

    @Override
    public Dimension getPreferredSize() {
        return ps;
    }

    public void zoomIn() {
        ps.setSize(ps.getWidth() * 2, ps.getHeight() * 2);
        revalidate();
    }

    public void zoomOut() {
        ps.setSize(ps.getWidth() / 2, ps.getHeight() / 2);
        revalidate();
    }

    private void center() {
        JViewport viewPort = (JViewport) getParent();
        viewPort.setViewPosition(new Point(
                (ps.width - viewPort.getSize().width) / 2,
                (ps.height - viewPort.getSize().height) / 2));
    }

    public void componentHidden(ComponentEvent e) {
    }

    public void componentMoved(ComponentEvent e) {
    }

    public void componentResized(ComponentEvent e) {
        center();
    }

    public void componentShown(ComponentEvent e) {
    }
}


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.