Dynamically Sized Scrollable JPanels
Can anyone help me figure out how to create a dynamically sized scrollable JPanel?
Here is a snippet of my code:
So I have already figured out that the JScrollPanel will scroll to the size of the JPanel's preferred size. Unfortunately, that doesn't help me when I add a large image to one of the JLabels inside of the JPanel at runtime. So, to achieve what I am wanting to do, I need the Scroll Pane to scroll to the ends of the JPanel, regardless of the size at the time. Any suggestions on how to do this?
Tell me if I am being unclear.
Re: Dynamically Sized Scrollable JPanels
When you add the image to the JPanel (or component within), first set the preferredSize of the JPanel (or component within) so that it incorporates the full size of the image (or whichever dimensions you wish - the necessity of this step may depend upon the component you are using and if its preferredsize is set when setting the image). Next, call revalidate() on the JPanel, which should notify the JViewport of the JScrollPane to recalculate the scrollable with and height.
Re: Dynamically Sized Scrollable JPanels
Quote:
Originally Posted by
copeg
When you add the image to the JPanel (or component within), first set the preferredSize of the JPanel (or component within) so that it incorporates the full size of the image (or whichever dimensions you wish - the necessity of this step may depend upon the component you are using and if its preferredsize is set when setting the image). Next, call revalidate() on the JPanel, which should notify the JViewport of the JScrollPane to recalculate the scrollable with and height.
Well, when the JFrame is begins there is not image on the JLabel. It is only after the user's input does an image load. Before then, I have no idea what the size of the image will be.
So I added outputPane.revalidate() at the end of the code that loads the image, but nothing happened.
Re: Dynamically Sized Scrollable JPanels
Quote:
Originally Posted by
aussiemcgr
So I added outputPane.revalidate() at the end of the code that loads the image, but nothing happened.
Did the preferredSize change? Can you post a small portion of code that reproduces the issue?
1 Attachment(s)
Re: Dynamically Sized Scrollable JPanels
This is the best I could do to replicate the issue in a way that I can actually show (work restrictions):
Code java:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Dimension;
public class PictureFrame
{
static JFrame frame;
static JPanel panel;
static JScrollPane scrollPane;
static JLabel pictureLabel;
static JButton loadPic;
public static void main(String[] args)
{
//Build JFrame
frame = new JFrame("Picture Frame");
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Build JPanel
panel = new JPanel();
panel.setPreferredSize(new Dimension(300,300));
//Build JScrollPane
scrollPane = new JScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(300,300));
//Create Blank JLabel
pictureLabel = new JLabel();
//Create JButton
loadPic = new JButton("Load Koala");
//Add Action Listener
loadPic.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//Set JLabel's Image to the Koala picture
pictureLabel.setIcon(new ImageIcon("Koala.jpg"));
//Revalidate
panel.revalidate();
}
});
//Add JLabel to JPanel
panel.add(pictureLabel);
//Get JFrame's Content Pane
Container contentPane = frame.getContentPane();
//Set Layout
contentPane.setLayout(new FlowLayout());
//Add JButton and JPanel
contentPane.add(loadPic);
contentPane.add(panel);
//Set Frame Visible
frame.setVisible(true);
}
}
The Koala.jpg image is a default image in Windows 7. I'll attach it if you feel like running the code to see what is happening.
Re: Dynamically Sized Scrollable JPanels
Cool. The first thing at least with this code, is that you are adding the panel to the frame instead of the JScrollPane. Next, if I run the code setting the preferredsize as follows, it works for me:
Code :
ImageIcon icon = new ImageIcon("Koala.jpg");//create the image icon
panel.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));//set the preferred size
pictureLabel.setIcon(icon);
panel.revalidate();
Re: Dynamically Sized Scrollable JPanels
setPreferredSize(...) is rarely needed in client code and this isn't one of those rare needs. Use of an appropriate layout manager along with a call to revalidate() and repaint() after changing the contained components is the correct approach when components are added to or removed from an already visible container.
db
Re: Dynamically Sized Scrollable JPanels
Quote:
Originally Posted by
Darryl.Burke
setPreferredSize(...) is rarely needed in client code and this isn't one of those rare needs. Use of an appropriate layout manager along with a call to revalidate() and repaint() after changing the contained components is the correct approach when components are added to or removed from an already visible container.
Isn't this one of those situations? No components are being added to a visible container, only an Icon being set. If I run the above example no resizing occurs unless both setPreferredSize and revalidate are called.
Re: Dynamically Sized Scrollable JPanels
Quote:
Originally Posted by
copeg
Cool. The first thing at least with this code, is that you are adding the panel to the frame instead of the JScrollPane. Next, if I run the code setting the preferredsize as follows, it works for me:
Code :
ImageIcon icon = new ImageIcon("Koala.jpg");//create the image icon
panel.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));//set the preferred size
pictureLabel.setIcon(icon);
panel.revalidate();
Ok, so I overlooked something very significant when I wrote my code example earlier. The Scrollable Panel does not just contain the JLabel. Specifically, my full program's Scrollable Panel will contain 3 JLabels (each with varying sizing images) and 3 JTextAreas (also scrollable for the time being, but that may change for style reasons).
To reflect that, I have changed the code a little to include a JTextField in the Scrollable Panel with the JLabel. Just like in my real program, the text in the JTextField (instead of the JTextArea in my real program) is set via a file read (although my example below uses FileReader instead of a stream like in my real program). Here is the changed code:
Code java:
import javax.swing.*;
import java.io.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Dimension;
public class PictureFrame
{
static JFrame frame;
static JPanel panel;
static JScrollPane scrollPane;
static JLabel pictureLabel;
static JButton loadPic;
//New Addition
static JTextField textField;
public static void main(String[] args)
{
//Build JFrame
frame = new JFrame("Picture Frame");
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Build JPanel
panel = new JPanel();
panel.setPreferredSize(new Dimension(300,300));
//Build JScrollPane
scrollPane = new JScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(300,300));
//Create Blank JLabel
pictureLabel = new JLabel();
//Create JTextField
textField = new JTextField(10);
//Create JButton
loadPic = new JButton("Load Koala");
//Add Action Listener
loadPic.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//Set JLabel's Image to the Koala picture
pictureLabel.setIcon(new ImageIcon("Koala.jpg"));
try{
BufferedReader in = new BufferedReader(new FileReader("text.txt"));
textField.setText(in.readLine());
in.close();
}catch(Exception ex){System.out.println("Error: "+ex); }
//Revalidate
panel.revalidate();
}
});
//Add JLabel to JPanel
panel.add(pictureLabel);
//Add JTextField
panel.add(textField);
//Get JFrame's Content Pane
Container contentPane = frame.getContentPane();
//Set Layout
contentPane.setLayout(new FlowLayout());
//Add JButton and JPanel
contentPane.add(loadPic);
contentPane.add(panel);
//Set Frame Visible
frame.setVisible(true);
}
}
And here is the content of text.txt for this example:
------------------------------------------------------------------------------------------------------------------------
Perhaps I am approaching this the wrong way, so I'll just outline the purpose of what I am doing and maybe someone will know a better way.
Basically, I am creating one of those basic tutorial/content helper things that exist on programs to allow the user to learn how to use certain features. I have a JTree on the left side that contains different categories and subcategories of different features. To the right of that I will have a panel that will update based on the selected item in the JTree to present the information on how to use the selected feature. To make it as editable as possible after production, the images are being stored as basic jpg (to allow changing if necessary) and the text is being stored in basic .txt files (to also allow changing if necessary). For my initial attempt at this and to provide a basic working product, I am assuming all feature details will consist of a maximum of 3 pictures and 3 blocks of text. After I have a basic version working and I get feedback on the design and whatnot, I will make it more dynamic, hopefully so the number of JLabels and JTextAreas depend on what is required for each category.
Am I approaching this the wrong way?
Re: Dynamically Sized Scrollable JPanels
Re: Dynamically Sized Scrollable JPanels
Quote:
Originally Posted by
Darryl.Burke
The company I work for isnt too wild about the idea of external libraries. As is, we are purchasing SmartXLS for this particular project.