Welcome to the Java Programming Forums


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.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 5 of 5

Thread: Resizing JPanels in JScrollPanes

  1. #1
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,707
    Thanks
    25
    Thanked 338 Times in 313 Posts

    Default 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:
    public Dimension getPreferredSize()
    	{
    		Dimension pref = super.getPreferredSize();
    		pref.height = lastY;
    		return pref;
    	}

    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:
    tree.addTreeSelectionListener(new TreeSelectionListener(){
        		public void valueChanged(TreeSelectionEvent e)
        		{
        			TreePath path = e.getPath();
        			System.out.println(path.toString());
        			if(path.toString().equalsIgnoreCase("[Features, Event Table, Category Overview]"))
        			{
        				outputPane.loadInput(0);
        				outputPane.revalidate();
        			}
        		}
        	});

    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/


  2. #2
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,707
    Thanks
    25
    Thanked 338 Times in 313 Posts

    Default 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/

  3. #3
    Member Darryl.Burke's Avatar
    Join Date
    Mar 2010
    Location
    Madgaon, Goa, India
    Posts
    495
    Thanks
    8
    Thanked 48 Times in 46 Posts

    Default Re: Resizing JPanels in JScrollPanes

    After I put a revalidate call in my paintComponent() method, it works fine.
    no no No No NO! That's one route to 100% CPU usage.

    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. IF that doesn't do it, you need to post a SSCCE.

    db

  4. #4
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,707
    Thanks
    25
    Thanked 338 Times in 313 Posts

    Default Re: Resizing JPanels in JScrollPanes

    Quote Originally Posted by Darryl.Burke View Post
    no no No No NO! That's one route to 100% CPU usage.

    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:
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JButton;
    import java.awt.event.*;
    import javax.swing.JPanel;
    import java.text.AttributedString;
    import java.text.AttributedCharacterIterator;
    import java.awt.font.LineBreakMeasurer;
    import java.util.Vector;
    import java.awt.image.BufferedImage;
    import java.awt.Graphics2D;
    import java.awt.Graphics;
    import java.io.File;
    import javax.imageio.ImageIO;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.awt.font.FontRenderContext;
    import java.awt.Dimension;
    import java.awt.font.TextLayout;
     
    public class TutorialPanel extends JPanel
    {
    	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();
        }
     
        public Dimension getPreferredSize()
    	{
    		Dimension pref = super.getPreferredSize();
    		pref.height = lastY;
    		return pref;
    	}
     
        public void loadInput(int n)
        {
    		lastInput = n;
    		repaint();
        }
     
        public void 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 = new String[]{text};
        	for(int i=0;i<text0Vals.length;i++)
        	{
        		attributedString = new AttributedString(text0Vals[i]);
    			attributedCharacterIterator = attributedString.getIterator();
    			start = attributedCharacterIterator.getBeginIndex();
    			end = attributedCharacterIterator.getEndIndex();
    			lineBreakMeasurer = new LineBreakMeasurer(attributedCharacterIterator,new FontRenderContext(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;
        }
     
        public void paintComponent(Graphics g)
        {
        	super.paintComponent(g);
     
    		System.out.println(lastInput);
     
        	if(lastInput==-1)
        	{
        		lastY = 0;
        		return;
        	}
        	else if(lastInput==0)
        	{
        		loadEventTableCategoryOverview((Graphics2D)g);
        	}
        }
     
        static TutorialPanel panel;
     
    	public static void main(String[] args)
        {
        	JFrame frame = new JFrame("Test Frame");
        	frame.setSize(500,450);
        	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        	panel = new TutorialPanel();
        	JScrollPane scrollPane = new JScrollPane(panel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
     
        	scrollPane.setPreferredSize(new Dimension(400,100));
     
        	JPanel panel2 = new JPanel();
        	JButton button = new JButton("Press to Load");
        	button.addActionListener(new ActionListener(){
        		public void 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/

  5. #5
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,707
    Thanks
    25
    Thanked 338 Times in 313 Posts

    Default Re: Resizing JPanels in JScrollPanes

    Hmm, I see what you mean about CPU usage.

    Any suggestions as to how to fix this?


    EDIT:
    In the loadInput method, if I change it to be the following:
    public void loadInput(int n)
        {
    		lastInput = n;
    		repaint();
    		super.revalidate();
    		repaint();
    		super.revalidate();
        }
    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/

Similar Threads

  1. Dynamically resizing an applet
    By mjpam in forum AWT / Java Swing
    Replies: 6
    Last Post: September 19th, 2010, 11:32 PM
  2. [SOLVED] Dynamic numbber of JPanels
    By nasi in forum AWT / Java Swing
    Replies: 2
    Last Post: May 14th, 2010, 03:44 AM
  3. repainting a jframe containing two jpanels
    By musasabi in forum What's Wrong With My Code?
    Replies: 0
    Last Post: May 11th, 2010, 11:31 PM
  4. dynamically resizing 2d array
    By Flamespewer in forum Collections and Generics
    Replies: 2
    Last Post: March 2nd, 2010, 11:10 AM
  5. JAVA Image Icon and JButton resizing problem
    By antitru5t in forum AWT / Java Swing
    Replies: 1
    Last Post: March 13th, 2009, 05:39 AM