Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: JScrollPane doesn't work with GridBagLayout

In my Java application, I'm writing a component that is used to view PDF files. I had a pretty slick implementation where the user could click on the PDF and drag it to view the areas that didn't fit on the screen. But my boss didn't like it, so now I have to use scroll bars. So I did the obvious thing and just put it into a JScrollPane, but almost no matter what I do it refuses to work.

The PDF just gets converted to a BufferedImage and then I convert it to an ImageIcon so I can add it to a JLabel which gets added to a JScrollPane.

I have a PDFViewer class which subclasses JScrollPane, and the important code is here:

private void drawPDF() {
    PDFRenderer renderer = new PDFDrawer(pdfFile);
    BufferedImage image = renderer.makeImage(page);
    JLabel img = new JLabel(new ImageIcon(image));
    this.setViewportView(img);
}

Now I have a separate class which subclasses JFrame that I need to add my PDFViewer to. It works as long as I don't use a layout and add the PDFViewer directly to the JFrame. If I even just add the JScrollPane to a JPanel and then add the JPanel to the JFrame the scroll bars disappear and it looks like I just added the JLabel directly. The image is too big for this, and it gets cut off easily.
I need to add some controls to the frame as well, so I set up a really basic GridBagLayout with the PDFViewer as the only component being added. And with the following code I get a window that looks like this.

GridBagLayout glayout = new GridBagLayout();
GridBagConstraints c;
setLayout(glayout);
PDFViewer viewer = new PDFViewer("foo.pdf");
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 1;
add(viewer, c);
setVisible(true);

Why does the JScrollPane get smooshed like that when I just simply add it to a layout instead of directly to the JFrame? I found out that it works with GridLayout, but a GridLayout is not what I want.

like image 842
jonescb Avatar asked Nov 19 '10 15:11

jonescb


1 Answers

You need at least ONE component with the weightx/y set to a non zero value for GridBagLayout to work.

You need to specify

c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;

This means that it will take all available space that is not used by other components. I suggest reading up on GridBagLayout for more information.

like image 130
willcodejavaforfood Avatar answered Oct 13 '22 03:10

willcodejavaforfood