The professional, friendly Java community. 21,500 members and growing!

The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.

Resizing JPanels in JScrollPanes

First off, sorry for all these posts about JPanels, JScrollPanes, and resizing. I have been making different posts because the issues in each are not exactly directly related and I didn't want to take each post in a whole new direction a bunch of times.

Anywho, I have a rather interesting issue. So I made a small test program to play around with a functionality of setting JPanel's preferred size based on the painting inside of it. That JPanel was inside of a JScrollPane, which was the ContentPane for the JFrame on the test program. The test program worked as expected, by adding Scroll Bars on the JScrollPane when necessary.

But, when I implemented the same code in my large program (with the same input and all), it was not successful by any means. The Scroll Bars were not added and I am once again very frustrated. The key difference between the test program and the full sized program is that in the full sized program the JScrollPane is not the JFrame's ContentPane (as there are a bunch more elements in the JFrame). It would seem the JPanel does not want to reset its size when its JScrollPane is not the ContentPane. I have attempted revalidating in every location I could think of. I have attempted setting the preferred size of the JPanel is every location I could think of. And, based on advice I found on another messageboard, I attempted to override the JPanel's getPreferredSize() method to set it based on the values I want it to be. All failed to work and I am beginning to struggle with my sanity.

Does anyone have any advice for me that will actually work?

I can't really post any code since there is no way for me to narrow my problem down any smaller than my 200 line test program, where the issue does not occur. Plus, I cannot provide the image and text files the test program and the full program use so the context of the code I would provide wouldn't even be replicable.

EDIT: Ok, a much more interesting piece of the puzzle has been added and now I really am confused.
So my code create an Object that extends JPanel called TutorialPanel. TutorialPanel has a method called loadInput(int) that decides what will be painted to the JPanel, then calls the overwritten paintComponent() method. While painting, it determines what the last Y value was. I then overrode the getPreferredSize() method like this:

Now, the user decides what they want painted to the JPanel by using a JTree. I made a half-assed Change Listener for the JTree as I have not extensively researched how to find out what element has been selected. That Change Listener looks like this:

Now, what is interesting here is that when the user selected the path above, the JPanel paints, but not revalidates. BUT, if the user selects a different path (currently no implementation for other paths) and then reselects the path above, suddenly the TutorialPane revalidates and I have Scroll Bars.

Why doesn't it work the first time but it does the second? Has anything changed?

Last edited by aussiemcgr; November 22nd, 2010 at 03:11 PM.

NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

When asking for help, please follow these guidelines to receive better and more prompt help:
1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
2. Give full details of errors and provide us with as much information about the situation as possible.
3. Give us an example of what the output should look like when done correctly.

Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

Re: Resizing JPanels in JScrollPanes

Ok, I have solved my problem, but I'm not sure if I am right about why it happened.

I think the paintComponent() method runs on a separate thread or something. Which would mean that despite the order of my code above, it was actually revalidating before it finished painting, thus before it knew how large the JPanel should be. It also explains why it worked the second time, since the size of the JPanel was already set from the previous paintComponent() call. After I put a revalidate call in my paintComponent() method, it works fine.

Any thoughts on this?

NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

When asking for help, please follow these guidelines to receive better and more prompt help:
1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
2. Give full details of errors and provide us with as much information about the situation as possible.
3. Give us an example of what the output should look like when done correctly.

Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

Re: Resizing JPanels in JScrollPanes

Never never never never change state (and revalidate() does result in a change of state) in a painting method override.

Adding a call to repaint() just after revalidate() may solve your problem.

Ok, well calling the repaint() method after revalidate() just breaks it again. That doesn't exactly surprise me, since i have already said I tried that and it didnt work.

IF that doesn't do it, you need to post a SSCCE.

db

I already explained how I cannot really reduce this down:

I can't really post any code since there is no way for me to narrow my problem down any smaller than my 200 line test program, where the issue does not occur. Plus, I cannot provide the image and text files the test program and the full program use so the context of the code I would provide wouldn't even be replicable.

The changing of the paint in the main program is controlled by the user's input. Based on that input, it does about 6 file streams and formats the painting. This is a runtime change from the user's input.

I have done the best I could to narrow this down and I think I did it (to about 130 lines), but I cannot be sure:

importjavax.swing.JFrame;importjavax.swing.JScrollPane;importjavax.swing.JButton;importjava.awt.event.*;importjavax.swing.JPanel;importjava.text.AttributedString;importjava.text.AttributedCharacterIterator;importjava.awt.font.LineBreakMeasurer;importjava.util.Vector;importjava.awt.image.BufferedImage;importjava.awt.Graphics2D;importjava.awt.Graphics;importjava.io.File;importjavax.imageio.ImageIO;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.awt.font.FontRenderContext;importjava.awt.Dimension;importjava.awt.font.TextLayout;publicclass TutorialPanel extendsJPanel{int lastInput =-1;String text0;AttributedString attributedString;AttributedCharacterIterator attributedCharacterIterator;int start,end;LineBreakMeasurer lineBreakMeasurer;
Vector<String> textBlocks =new Vector<String>();
Vector<BufferedImage> images =new Vector<BufferedImage>();int lastY;public TutorialPanel(){super();}publicDimension getPreferredSize(){Dimension pref =super.getPreferredSize();
pref.height= lastY;return pref;}publicvoid loadInput(int n){
lastInput = n;
repaint();}publicvoid loadEventTableCategoryOverview(Graphics2D g2){String text ="Java is a programming language originally developed by James Gosling at Sun Microsystems (which is now a subsidiary of Oracle Corporation) and released in 1995 as a core component of Sun Microsystems Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities. Java applications are typically compiled to bytecode (class file) that can run on any Java Virtual Machine (JVM) regardless of computer architecture. Java is a general-purpose, concurrent, class-based, object-oriented language that is specifically designed to have as few implementation dependencies as possible. It is intended to let application developers write once, run anywhere. Java is currently one of the most popular programming languages in use, and is widely used from application software to web applications.[9][10] The original and reference implementation Java compilers, virtual machines, and class libraries were developed by Sun from 1995. As of May 2007, in compliance with the specifications of the Java Community Process, Sun relicensed most of its Java technologies under the GNU General Public License. Others have also developed alternative implementations of these Sun technologies, such as the GNU Compiler for Java, GNU Classpath, and Dalvik";float X =10, Y =0;String[] text0Vals =newString[]{text};for(int i=0;i<text0Vals.length;i++){
attributedString =newAttributedString(text0Vals[i]);
attributedCharacterIterator = attributedString.getIterator();
start = attributedCharacterIterator.getBeginIndex();
end = attributedCharacterIterator.getEndIndex();
lineBreakMeasurer =newLineBreakMeasurer(attributedCharacterIterator,newFontRenderContext(null, false, false));Dimension size = getSize();float width =(float) size.width-5;
lineBreakMeasurer.setPosition(start);int count=0;while(lineBreakMeasurer.getPosition()< end){TextLayout textLayout = lineBreakMeasurer.nextLayout(width);
Y += textLayout.getAscent();
X =5;if(count>0)
X =25;
textLayout.draw(g2, X, Y);
Y += textLayout.getDescent()+ textLayout.getLeading();
count++;}}
X =10;
Y+=10;
lastY =(int)Y;}publicvoid paintComponent(Graphics g){super.paintComponent(g);System.out.println(lastInput);if(lastInput==-1){
lastY =0;return;}elseif(lastInput==0){
loadEventTableCategoryOverview((Graphics2D)g);}}static TutorialPanel panel;publicstaticvoid main(String[] args){JFrame frame =newJFrame("Test Frame");
frame.setSize(500,450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel =new TutorialPanel();JScrollPane scrollPane =newJScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(newDimension(400,100));JPanel panel2 =newJPanel();JButton button =newJButton("Press to Load");
button.addActionListener(newActionListener(){publicvoid actionPerformed(ActionEvent e){
panel.loadInput(0);}});
panel2.add(button);
panel2.add(scrollPane);
frame.setContentPane(panel2);
frame.setVisible(true);}}

And before I get the usual lecture: Yes, there is a reason I am using paint instead of normal text components. This is a small part of a much larger thing and this is the best way of doing it, from the user's point of view.

NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

When asking for help, please follow these guidelines to receive better and more prompt help:
1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
2. Give full details of errors and provide us with as much information about the situation as possible.
3. Give us an example of what the output should look like when done correctly.

Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

It seems to be able to adjust the size of the Scrolling to the amount of painting being done, but it still doesn't work the first time something is selected but does the second time something is selected. I'm very confused about what is happening...

Last edited by aussiemcgr; November 29th, 2010 at 03:23 PM.

NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

When asking for help, please follow these guidelines to receive better and more prompt help:
1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
2. Give full details of errors and provide us with as much information about the situation as possible.
3. Give us an example of what the output should look like when done correctly.

Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/