Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

scrollPane not quite working as expected  RSS feed

 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,

I am trying to get a scrollPane working correctly, but not having any luck. The picture drawn in the center panel is quite large and goes off the screen. I visited http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html but I am missing something vital. Both tracks show, but there is no knob to do the scrolling. What am I doing wrong?

 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The only reason I can think of that you bars aren't showing is that the object inside isn't bigger than the scroll pane viewable area. If you mean the arrow buttons on the scroll bar aren't showing then that is a look and feel issue. Can you see the image in the scroll pane but you still aren't seeing the bars? I mocked up your code here:



If i change the panels size to 800 the scroll bars don't show. The only difference is I'm using ScrollPaneConstants for the scroll policy's instead of JScrollPane, and I don't have your other objects.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@R. Ramage: That has scrolling working, but is there a way getting the component size and creating a panel.setPreferredSize() based on those dimensions? The size of the item in the center pane is variable in size, leaving a lot of empty space at times.
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since you're using BorderLayout setting the size of the scroll pane isn't going to do anything. Using border layout will base it's size on the container. If you use a different layout you can work with the sizing better.
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
is there a way getting the component size and creating a panel.setPreferredSize() based on those dimensions?


You should NOT be playing with the preferred size of components. It is the job of each component to determine its own preferred size so that scrolling will work properly.

The idea of using a scrollpane is to let it adjust automatically as the user resizes the frame. As the frame is resized large the scrollbars shrink or disappear. As the frame is resized smaller the scrollbars appear or increase in size.
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe I misread the question but I didn't think we were trying to reset the preferred size of the components within but the size of the scroll pane. Yes in my example I did change the preferred size of the component within but that was just to show the scroll bars appearing if it's too large for the viewport, and to try and diagnose why it wasn't working. It wasn't meant to be a suggested practice. Sorry if there was confusion on that.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So far, the only way this has worked was by manually setting the preferred sizes (I had to use both). If this is not recommended, I am back to my original question of what is wrong with the above code?
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
what is wrong with the above code?




Above is the component that is added to the viewport of the scrollpane. Do NOT set its preferred size.

If this is a custom component then you should be overriding the getPreferredSize() method of the component to return an appropriate value.

If this is just a custom container holding other components, then use a proper layout manager and the layout manager will calculate the preferred size.

Post a proper SSCCE if you need more help because we can't guess what you are actually doing.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unfortunately, I can not post the code in a public forum as it does not belong to me.

The center component dynamically changes depending depending on user input and can go anywhere from a small constructed set of rectangle that fits quite nicely without scroll bars to a quite huge set of rectangle of unknown quantity at least double the size of the viewable screen.
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The middle component, are you rendering an image to a JPanel? I guess the question is what does DComponent extend?
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
DComponent extends JComponent.
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does the size vary based on things that a user is doing in the frame or does it depend on information given at startup? Based on your first post I kind of perceive this as an image viewer of sorts.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The DComponent is a series of rectangles put together to represent a floor plan. The initial drawing is based on a user inputed exterior dimensions located in the North panel. They can update the drawing at any time by entering new dimensions and hitting update located in the north panel. The west panel provides updated information. The south panel changes other items of the picture.
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After the user updates the dimensions and the new image is rendered try calling revalidate and repaint on the middle component. Also do away with setting its preferred size. Try that and let me know.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It made no difference.
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry Jenn. Hopefully this will at least point you in the right direction. Without seeing the code for the component I can only really guess at this.

This has a button on top that increases the size of the rectangle drawn in the JComponent. Where ever it is that you're updating the number and sizes of rectangles added you just need to compute the new preferred size, revalidate, and repaint. As the size of the rectangle exceeds the scroll pane the bars show up.



I'm assuming the rectangles are preset sizes or that you can get the dimensions from user input.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I can make this, or a variation of this work. Thanks for your effort!
 
R. Ramage
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hopefully its enough to get you going. Good luck.
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, that is NOT the way to solve the problem. Read all my comments.

You should NOT use the setPreferredSize() method. It is the responsibility of the component to determine its preferred size. This is done by overriding the getPreferredSize() method of the component. Only the component knows how many rectangles it need to paint etc. Therefore the getPreferredSize() method will use that information to return the appropriate size.

Also, it is the responsibility of the component to invoke revalidate() and repaint() whenever one of its properties changes.

When you invoke setText(...) on a JLabel or JTextField or JButton do you then change the preferred size and do revalidate() and repaint? No, because all that logic is part of the component so the application code doesn't have to remember to do it.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Rob Camick: If you look at my line 19 from the original code, I was attempting to do the getPreferredSize(). I just didn't know how to apply it properly. Do you have any code suggestions to try? I've danced with this for about 5 hours. I've tried so many different things, I can't even remember what I've tried!
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was attempting to do the getPreferredSize().


Where? I don't see where you are attempting to override the getPreferredSize() method? You override the getPreferredSize() method in your DComponent class since this is the class that does all the custom painting of your rectangles and whatever else it does.



So did you download the demo code to see how it works? The ScrollablePanel class gives an example on overriding the getPreferredSize() method. Since you did not post a SSCCE showing what you are attempting to do, I can't give any advice on what the preferred size calculation should be for your component. The whole point of a SSCCE is to create a simple example. Unless you can learn to isolate problems you won't be able to debug your code.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If I didn't attempt to use it in the way you described, then I guess I do not understand what you are saying.

Yes I did look at the code. I crawled up and down it. Inside and out. tried what I seen, and got no where. That is when I came here looking for help. I'm obviously not getting it on my own. That was the whole purpose of asking for help, and telling the forum that I had explored the lessons prior to doing so.

I don't know how else to ask for help, but I am begging you, or some one else for it! I have tried so many things and spent so long on this one problem, that I am almost in tears. Never have I been stumped like this before.

Unless you can learn to isolate problems you won't be able to debug your code.


I guess I will be a crappy coder for the rest of my life then as I am totally stumped!
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just told you where to specifically look for an example of how to override the getPOreferredSize() method. If was 7 minutes from my posting until your reply. You obviously did not take a second look at that code to try and understand it. You also have made no effort to post a SSCCE. I don't know what else I can do.

The basic rule of a scrollpane is that the scrollbars will appear automatically when the preferred size of the component added to the viewport of the scrollpane is greater than the size of the scrollpane. The original code you posted does not help us because the important part of the code is the getPreferredSize() method of your custom class which you did not post.

That is why I suggested you create a SSCCE. All you do is extend a JPanel and override the getPreferredSize() method to return a hard coded value. Then you add this component to a scrollpane and add the scrollpane to a frame. Then you resize the frame and see what happens as the frame grows/shrinks. Once you understand this basic concept, then you can implement a more complicated getPreferredSize() method that changes dynamically as properties of you component change. You have already been given a simple example of this approach although my comment was that the "increaseSize" methjod should be part of your component so that you update an internal variable to track the preferred size. Then the getPreferredSize() method can just return this variable.

Forget about your real program and create a SSCCE to learn the basics first.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've gone back and played with various simple panel designs and had success getting the scrollPane to activate every time. As such, I deducted that the issue is specific to this particular program.

I removed all other panels to take those out of the mix, simplifying the program above as much as possible. I then removed the setSize() on the frame and switched to pack(). When I ran the program, the window that opened was as small as possible, only big enough to show the java icon, 2 resizing buttons, and the red x. When I stretched out the frame, the picture was there. That told me that Java was not seeing the size. I then decided it was time to pull up a console reading on that panel to confirm my suspicions. When I used System.out.println("Width: "+ centerComponent.getWidth()); and System.out.println("Height: "+ centerComponent.getHeight()); on the above program, I get the a dimension of the panel being height 0 by width 0.

So, I can now conclude that java jScrollPane will never work if it believes the panel is 0x0. That brings me to what ends up being the true issue. How do I get Java to see the drawn rectangles that are drawn from the constructor on another page?
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That brings me to what ends up being the true issue. How do I get Java to see the drawn rectangles that are drawn from the constructor on another page?


Already answered.

You override the getPreferredSize() method of your custom component.

Since you still refuse to post a SSCCE, that is a much help as we can give.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I will see if I can build something that simulates this issue. Everything else I have tried has always worked, so I will try to translate the code into a simulation of some sort.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, this seems to recreate the error.





 
Paul Clapham
Sheriff
Posts: 22472
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Here you try to set the scroll pane's preferred size to be the same as the JFrame's preferred size, if I'm not mistaken. But you do that before pack() is called, so at that point the JFrame doesn't have a preferred size.

And I don't see anything else with a preferred size, so (without trying to run your code and without going back to read the whole thread -- sorry!) I guess you're going to end up with a tiny JFrame with only a border and no contents. The JFrame just gets made large enough to contain the components you put in it, based on their preferred size. Don't you have a preferred size for anything? You don't have a choice for how big a D_Component ought to be, for example?
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried moving pack() around and it is the same result. Originally, I had the program setting the frame to the size of the screen. The jScrolls still would not activate. Since the D_Component is reporting a size of 0x0, this would make sense. The problem with D_Component is, in the real program, the user is constantly changing the size of the rectangles (This is an extremely stripped version of the program that in reality is calling on 13 different constructor classes to draw out everything that must be drawn). I just used this as an example code that end up simulating accurately the conditions that were causing me problems.
 
Rob Camick
Ranch Hand
Posts: 2800
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For the 3rd time, where do you implement the getPreferredSize() method in you D_Component method?

I have no idea if this is the only problem with your code but I sure am not going to take the time to test your code until you show you have made an effort to follow suggestions given.

What is the point of asking a question when you don't even make an effort to follow the suggestion?

 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deleted
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deleted
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deleted
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deleted
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Deleted
 
Scotty Steven
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Camick:

This girl is obviously not understanding what you are saying. It might be beyond her knowledge level. I think that is why she came here looking for help and asking questions. Would it really hurt you after a week to maybe put out a little extra effort and give her the answer that you obviously already know? Why would you ask her to post code if you were just going to tell her off after doing as you ask? I'd help, but I just started reading this forum trying to learn swing myself and for sure know less then her.
 
Scotty Steven
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jenn Terry: I reread this thread and if I understand what Rob is saying, you somehow have to create a way for the Component class to figure out it's own size and pass those sizes to the Viewer class. Maybe you could just add up all of the x and y axis starting and stop points and make them public variables? If you can't figure out how to make it work with Robs way, then you could manually set those values using the method that R. Ramage posted since you said it kind of worked. I hope this helps.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Scotty Steven Yes, I was able to get @R. Ramage way to work before but @Rob Camick made it seem that this was the wrong thing to do. I thought it might be a good skill to learn. I just can't figure out how to make it work so I will probably just go back to @R. Ramage method. I don't know why @Rob Camick would ask me in almost every post he made to post SSCCE and then not be willing to work with it. There is no logic to it at all.

Thanks for trying to help.
 
Scotty Steven
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What about adding the following to the D_Component class



In the D_Viewer class change line 21 to


or if that doesn't work,

I haven't tried it on your code, but some research at this link makes me feel this could work.
 
Jenn Terry
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Scotty Steven

I tried both suggestions you made. The window now opens at 500x500 using either method, but the component console size printout is still showing 0x0 and the jScrollPane is still not there. At least something is happening. Here is where I am.

 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!