I cannot get a JScrollPane to allow me to scroll around inside a JViewport... I pasted two simplified classes below to demonstrate my point:
Running the WindowFrame class below shows a window and the image specified in the JViewer class but I am completely unable to scroll around the image. The JScrollBars are by default on DISPLAY_AS_NEEDED and the fact they do not appear shows that the program doesn't recognize that scrollbars are needed. Why is this?
-----------------------------------------
import javax.swing.*;
public class WindowFrame extends JFrame {
JScrollPane scroller;
JViewer view;
public WindowFrame () {
view = new JViewer();
scroller = new JScrollPane(view);
getContentPane().add(scroller);
setSize(50,50);
setTitle("This is not Scrollable!");
show();
}
public static void main (String[] args) {
new WindowFrame();
}
}
---------------------------------------------------
import javax.swing.*;
import java.awt.*;
public class JViewer extends JViewport {
public JViewer() {
}
public void paintComponent (Graphics g) {
//I display the image offscreen (100,100) to //demonstrate that the scrollbars do not show up
ImageIcon imageIcon =
new ImageIcon(/*enter any image filepath here*/);
g.drawImage(imageIcon.getImage(), 50,50, null);
}
}
-------------------------------------------------------------
Your help is much appreciated,
Mark
In your paintComponent method, try calling setPreferredSize and
revalidate.
> The JScrollBars are by default on DISPLAY_AS_NEEDED and the fact they
> do not appear shows that the program doesn't recognize that scrollbars
> are needed. Why is this?
Because they are not needed. :o)
There is nothing in the JViewer class that controls its preferred size, so
its preferred size is [0,0]. This is less than the size of the JViewport,
so scroll bars are not needed. Because of the way that the components are
arranged, the JViewer is being given a larger size than the [0,0] it asks
for, so you can see the image. But the JScrollPane only expands it to the
size of its viewport.
A few other notes:
You use JViewport as the superclass for JViewer. A JViewport is normally
used by the JScrollPane to hold the view component. You should use JPanel
as the superclass for JViewer.
You are loading the image in your paintComponent() method, which is not a
good idea. Instead, load it ahead of time, in the constructor or perhaps
in a setViewImage() method. Doing this will also give you access to the
image size, which you can use to derive the preferred size of the JViewer.
The paintComponent() method should call super.paintComponent() before it
paints the image. This is especially important, since it does not paint
the entire are of the image. As is, you will see artifacts around the
border, especially when you get it to scroll.
JFrame.show() is deprecated. Use setVisible(true) instead.
You do not validate your frame before showing it, which you should do.
Note that calling pack() also validates the frame, so you should call
either pack() or validate().

Signature
Regards,
John McGrath
Mark - 26 Jan 2005 15:58 GMT
Wow, thanks so much! You just made my day.
And by the way, why is none of this in the java documentation online?
It took me three seconds once you explained it to me but I've been trying to get it to work for the past three days.
Again thanks a million!
mark
John McGrath - 26 Jan 2005 20:25 GMT
> why is none of this in the java documentation online?
I assume that by "the java documentation online" you mean the JavaDocs.
They cover individual classes, but generally do not give the "big
picture". You really need a good Swing book to get that.
You will also find some very good material in the Java Tutorial, which is
available on the Sun web site. The JavaDocs for Swing components often
have links to the tutorial, usually in the class description at the top.
For an example, see the link labeled "How to Use Scroll Panes" in the
JavaDocs for JScrollPane.

Signature
Regards,
John McGrath
Babu Kalakrishnan - 30 Jan 2005 09:23 GMT
Not really nit-picking, but thought I'll point out a couple of errors in
the response.
> JFrame.show() is deprecated. Use setVisible(true) instead.
Actually the show() and hide() methods are not deprecated for
java.awt.Window and its descendants (at least it wasn't till JDK 1.4 -
Didn't checked the Javadocs for 1.5) - It is deprecated only for other
AWT/ Swing Components.
> You do not validate your frame before showing it, which you should do.
> Note that calling pack() also validates the frame, so you should call
> either pack() or validate().
Generally there is no need to call validate() explicitly on any
component. The only requirement is that on top level components like
Frames, Windows and Dialogs and their descendants who don't have a
parent container (and hence a LayoutManager to control their size), the
application must set its bounds - either by specifying absolute values
or by calling pack(). In case pack() is called, the validation occurs at
that point whereas in case a setSize() or setBounds() was called,
validation will occur automatically when the show() method is called.
BK
John McGrath - 30 Jan 2005 11:49 GMT
> > JFrame.show() is deprecated. Use setVisible(true) instead.
> >
> Actually the show() and hide() methods are not deprecated for
> java.awt.Window and its descendants (at least it wasn't till JDK 1.4 -
> Didn't checked the Javadocs for 1.5) - It is deprecated only for other
> AWT/ Swing Components.
As of JDK 1.5, show() and hide() are deprecated for java.awt.Window and
java.awt.Dialog, as well as the descendant classes that inherit those
methods.

Signature
Regards,
John McGrath
Babu Kalakrishnan - 02 Feb 2005 07:10 GMT
>>>JFrame.show() is deprecated. Use setVisible(true) instead.
>>
[quoted text clipped - 6 lines]
> java.awt.Dialog, as well as the descendant classes that inherit those
> methods.
Ah.. thanks for the update :-) Haven't started dabbling seriously in 1.5
yet because most of our apps have to run on 1.4 (and 1.3 if possible),
and therefore those nifty "1.5 only" features are off limits for now :-(
BK
John McGrath - 02 Feb 2005 10:13 GMT
> Haven't started dabbling seriously in 1.5 yet because most of our apps
> have to run on 1.4 (and 1.3 if possible), and therefore those nifty
> "1.5 only" features are off limits for now :-(
I have still not done a major project for the same reason, but I have done
a few small projects for my own entertainment and education. The new 1.5
features make a *really* big difference. Generics, the enhanced for loop,
and autoboxing have a significant effect on the character of the language.
Things are more concise, and casting is almost eliminated! I highly
recommend it.

Signature
Regards,
John McGrath