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 no开发者_运维技巧w 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.
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.
Try adding:
c.fill = GridBagConstraints.BOTH;
This should ensure that your panel is resized in both directions when you resize. Incidentally if this is the only component then consider using BorderLayout
and adding the component to BorderLayout.CENTER
.
c.weightx = 1.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
before adding the viewer
.
You need to set the preferredSize(), minimumSize() and maximumSize() of the component you are adding to the JScrollpane. Or you can set the cell to expand horizontally and vertically as far as possible by adding
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
to the GridBagConstraints.
Try setting prefferedsize(setPrefferedSize()) to the component which you are adding to ScrollPane.
精彩评论