2

This seems like a newbie question except that I've been trying to wrap my head around the Swing framework for loong time.

Provided you provide an image, dog.jpg, at least 500 px square, the following code should display the image in a scrollpane. If it displayed anything, I probably wouldn't throw my hands up in despair. What am I missing?

import java.awt.BorderLayout;
import javax.swing.*;

public class ScrollSample {
  public static void main(String args[]) {
    String title = (args.length == 0 ? "JScrollPane Sample" : args[0]);
    new ScrollSample( title ) ;
    }

  public ScrollSample ( String title) {
    JFrame frame = new JFrame(title);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Icon icon = new ImageIcon("dog.jpg");
    JLabel dogLabel = new JLabel(icon);
    dogLabel.setSize( 500, 500 ) ;

    JLayeredPane layeredPane = new JLayeredPane() ;
    layeredPane.add( dogLabel, new Integer( 0 )) ;

    JPanel jp = new JPanel() ;
    jp.add( layeredPane ) ;
    jp.setSize( 500, 500 ) ;

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setViewportView(jp);

    frame.getContentPane().add( scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}

Thanks!

Sunny Jim
  • 585
  • 5
  • 13
  • As always I recommend using [WindowBuilder Pro](https://developers.google.com/java-dev-tools/wbpro/quick_start) – Kai Mar 29 '12 at 14:19
  • Can't find anything obviously wrong with your code. Have you put dog.jpg in your project root catalog? – John Snow Mar 29 '12 at 14:22

3 Answers3

4

You must set the preferred size for JLayeredPane if you are drawing components of larger widths and sizes to it. Especially since you are adding it to a JPanel with default layout. JLayeredPanes don't have layout managers by default - so either you manage the bounds or add a preferred layout manager to the layered pane. The simple way would be:

After

 JLayeredPane layeredPane = new JLayeredPane() ;

add

 layeredPane.setPreferredSize(new Dimension(500,500));

And then maximize your window ( or set your JFrame's size to 600X600) when the app runs.

Read up on : How to Use Layered Panes

ring bearer
  • 20,383
  • 7
  • 59
  • 72
  • Is the layout manager issue the reason why the intermediate JPanel jp is required? Took me a while to figure that out as well. – Sunny Jim Mar 29 '12 at 21:09
4
  • The default layout of a JPanel is a Flowlayout. A FlowLayout shows each component at its preferred size and has a 5 pixel border. Use a BorderLayout instead (or add the layered pane directly to the scroll pane).
  • The default preferred size of a JLayeredPane is (0, 0). Set a preferred size for it.
Walter Laan
  • 2,956
  • 17
  • 15
4

A Swing GUI should be started on the EDT. Left as an exercise for the user.

import java.awt.*;
import javax.swing.*;
import java.net.URL;

public class ScrollSample {

    public static void main(String args[]) throws Exception {
        final URL url = new URL("http://pscode.org/media/stromlo2.jpg");
        String title = (args.length == 0 ? "JScrollPane Sample" : args[0]);
        new ScrollSample( title, url ) ;
    }

    public ScrollSample ( String title, URL url) {
        JFrame frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Icon icon = new ImageIcon(url);
        JLabel dogLabel = new JLabel(icon);
        dogLabel.setBounds(0,0,640,480);

        JLayeredPane layeredPane = new JLayeredPane() ;
        layeredPane.add( dogLabel, new Integer( 0 )) ;
        layeredPane.setPreferredSize( new Dimension(500, 500) ) ;

        JPanel jp = new JPanel(new BorderLayout()) ;
        jp.add( layeredPane ) ;

        JScrollPane scrollPane = new JScrollPane(jp);

        frame.getContentPane().add( scrollPane, BorderLayout.CENTER);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { String title = (args.length == 0 ? "JScrollPane Sample" : args[0]); new ScrollSample( title, url ) ; } }); } – Sunny Jim Mar 29 '12 at 21:02