3

I am looking for a Swing component that is an extension of a scrollpane/viewport allowing to open and navigate into an overview of the content being currently shown. I am sure that I have seen some blog posts in the past monthes (years?) showing such a component but cannot find the component anymore.

Here is a picture of what I am looking for:

scrollpane with overview

If you remember such a post or if you have some links in your bookmarks I would thank you to share the info.

Thanks for your help.

Matthieu BROUILLARD
  • 1,991
  • 1
  • 16
  • 25

3 Answers3

2

Here is a working example, but you will need java-image-scaling library (its LGPL) - it is used for smooth scaling of preview image, otherwise you get totally ruined image:

public static void main ( String[] args )
{
    final JFrame mainFrame = new JFrame ();

    JPanel content = new JPanel ( new GridLayout ( 20, 20 ) );
    for ( int i = 0; i < 20; i++ )
    {
        for ( int j = 0; j < 20; j++ )
        {
            content.add ( new JLabel ( "Test " + i + ":" + j )
            {
                {
                    setBorder ( BorderFactory.createEmptyBorder ( 20, 20, 20, 20 ) );
                }
            } );
        }
    }

    final JScrollPane pane = new JScrollPane ( content );
    pane.setCorner ( JScrollPane.LOWER_TRAILING_CORNER, new JButton ()
    {
        {
            final JButton button = this;
            addActionListener ( new ActionListener ()
            {
                public void actionPerformed ( ActionEvent e )
                {
                    JComponent comp = ( JComponent ) pane.getViewport ().getView ();
                    Dimension size = comp.getSize ();
                    Rectangle viewRect = comp.getVisibleRect ();

                    // Drawing preview
                    BufferedImage image = new BufferedImage ( size.width, size.height,
                            BufferedImage.TYPE_INT_RGB );
                    Graphics2D g2d = image.createGraphics ();
                    comp.print ( g2d );
                    g2d.dispose ();

                    // Rescaling preview
                    int width = 200;
                    int height = comp.getHeight () * width / comp.getHeight ();
                    BufferedImage rescaled =
                            new ResampleOp ( width, height ).filter ( image, null );

                    // Drawing view rect
                    float diff = (float)width / size.width;
                    g2d = rescaled.createGraphics ();
                    g2d.setPaint ( Color.RED );
                    g2d.drawRect ( Math.round ( viewRect.x * diff ),
                            Math.round ( viewRect.y * diff ),
                            Math.round ( viewRect.width * diff ),
                            Math.round ( viewRect.height * diff ) );
                    g2d.dispose ();

                    // Displaying preview
                    final JDialog preview = new JDialog ( mainFrame );
                    preview.setUndecorated ( true );
                    preview.add ( new JLabel ( new ImageIcon ( rescaled ) )
                    {
                        {
                            setBorder ( BorderFactory.createLineBorder ( Color.BLACK ) );
                            setFocusable ( true );
                        }
                    } );
                    Point los = button.getLocationOnScreen ();
                    preview.setSize ( width + 2, height + 2 );
                    preview.setLocation ( los.x - width - 2, los.y - height - 2 );
                    preview.setVisible ( true );

                    preview.requestFocus ();
                    preview.addFocusListener ( new FocusAdapter ()
                    {
                        public void focusLost ( FocusEvent e )
                        {
                            preview.dispose ();
                        }
                    } );
                }
            } );
        }
    } );
    mainFrame.add ( pane );

    mainFrame.setSize ( 600, 600 );
    mainFrame.setLocationRelativeTo ( null );
    mainFrame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
    mainFrame.setVisible ( true );
}

So basically i create a snapshot of the panel, rescale it and place into the small dialog that opens near the button and closes on focus loss. Snapshot creation might be time-wasting though, but i don't know any better way to create a rendered preview of the whole scrollpane container - you have to paint it onto something to display preview anyway and that means it will spend the same time.

Also you can easily modify the preview component so you can move the visible rect by dragging the RED rect on the preview dialog :)

Mikle Garin
  • 10,083
  • 37
  • 59
1

Is possible and with JComponent(s) to the

1) GlassPane

2) JLayer (Java7) based on JXLayer (Java6)

3) JViewport

4) positioning of Translucent JDialog

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thanks, but I would like to avoid to re-invent the wheel as I am sure I have seen such an existing contribution already done and published by someone else. – Matthieu BROUILLARD Apr 11 '12 at 09:57
  • Sorry no idea, never needed that, if i want to do, then by using [GlassPane](http://stackoverflow.com/a/10059295/714968) could be done this job per a few hours, notice my a.m. points blocking MouseEvents by default, but Keyboard events can take confortly only modal JDialog ... – mKorbel Apr 11 '12 at 10:03
1

There is CornerScroller in Jide-OSS.

http://java.net/projects/jide-oss/sources/svn/content/trunk/src/com/jidesoft/swing/CornerScroller.java

Walter Laan
  • 2,956
  • 17
  • 15