Resize JPanel within JScrollPane - never smaller than viewport - java

I've created a JPanel and JScrollPane like so:
JPanel panel = new JPanel();
panel.setPreferredSize(5000, 5000);
JScrollPane scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPanel.getViewport().setBackground(Color.GRAY); //panel is white
I will be using event handlers to dynamically resize the panel. The problem is, sometimes the panel is smaller than the viewport. I'd set the panel's size like this:
panel.setPreferredSize(10, 10); //Just an example
but the panel will never be smaller than the viewport. I tried using
panel.setSize(10, 10);
and i saw a gray flicker (the viewport's background showing through), which indicated that the panel was being sized to what i wanted it to be, but then grew to the viewport's size. How can i stop this?

To control the sizing the view inside a JViewport, let it implement the Scrollable interface. Without, it's always forced to the size of the viewport.

Related

Binding JPanel's width to JScrollPane's width to prevent auto resize

I have code that looks something like this:
JPanel panel = new JPanel();
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(panel);
scrollPane.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
What happens is when the component in the panel becomes too wide, a horizontal scroll bar in the scrollPane appears and the user has to scroll left or right. The thing is, the component in panel is actually resizable, but because it's a JScrollPane, it maximizes.
Question: Is there any way I can bind the panel's width property to scrollPane's width property? So that the components inside the panel won't exceed the panel's width?
Below shows what it looks like:
With the horizontal scroll bar policy set to never, the scroll bar disappears but the panel width remains the same, but now a section of the panel is no longer viewable.
You can change the scroll bar policy using the setHorizontalScrollBarPolicy and setVerticalScrollBarPolicy methods or from the constructor JScrollPane(Component, int, int)
Quoting the Oracle documentation, the policies are:
VERTICAL_SCROLLBAR_AS_NEEDED
HORIZONTAL_SCROLLBAR_AS_NEEDED
VERTICAL_SCROLLBAR_ALWAYS
HORIZONTAL_SCROLLBAR_ALWAYS
VERTICAL_SCROLLBAR_NEVER
HORIZONTAL_SCROLLBAR_NEVER

How to automatically resize JFrame if elements are too large?

I have been researching for 30 minutes on how to automatically resize a JFrame when the elements are too large. I am trying to fit line segments inside the JFrame but it always exceeds the space but does not automatically generate more space.
What should I do?
DrivePanel panel = new DrivePanel(aCar, coordinates);
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.setSize(600,600);
application.setVisible(true);
Example of output:
Some things to consider :
if you are doing custom painting on your panel, remember that the panel's size it's not changed by what you are drawing.
For example, if the "last" point (i mean the point with the biggest values of x and y) is drawn at (1000,1000) coordinates, you should set the preferred size of your panel in order to contain it.
To let your application using the preferred size of your components, you should call application.pack() (where application is your JFrame object) instead of setting size manually.
If your panel is too big to be displayed enterily on your screen, you might add it to a JScrollPane, and then add the scrollpane to your jframe (not the panel itself).
The scrollpane will automatically use scroll bars if your panel can't be fully displayed on your screen.
So consider this small example, based on your code :
DrivePanel panel = new DrivePanel(aCar, coordinates);
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(new Dimension(1000,1000)); // change 1000,1000 with the coordinates you need ...
JScrollPane scrollPane = new JScrollPane(panel);
application.add(scrollPane);
application.pack();
application.setVisible(true);
Hope this helps :)

Knobs don't appear on scroll bars

I have a class that extends JComponent called Canvas. Even when it's bigger than my JScrollPane's JViewport, the knobs will not appear on the scroll bars and I cannot scroll down on the Canvas. The code for my scroll pane is here:
final JFrame frame = new JFrame("SketchPad");
frame.setLayout(new BorderLayout());
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
JScrollPane scrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JViewport vp = scrollPane.getViewport();
vp.setLayout(null);
vp.setBackground(Color.BLUE);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
canvas = new Canvas();
canvas.setBounds(0, 0, w, h);
vp.add(canvas);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Am I doing something wrong with the JScrollPane, or is it something else?
vp.setLayout(null);
Don't set a null layout on the viewport. 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 layout manager us used to determine the preferred size (as a general rule you should never use a null layout).
Also, don't use a Canvas, that is an AWT components. Use a JPanel when using Swing. Or, if it is a custom class then it should have a more descriptive name to avoid confusion.

JPanel Format Problems

I have a 2 JPanels, 1 a button Panel and one a Graphic Panel. I would like the button panel to situated right below the graphic panel but the button panel cuts off the Graphics Panel in the middle. I've been trying the box layout which seems from discussions seems like the best format for what I am trying to do. Can anyone please give me some advice on my formatting problem.
JFrame canvas = new JFrame("Baseball Strike K");
JFrame canvas = new JFrame ("GraphicBoard");
canvas.setVisible(true);
canvas.setSize(1000,1000);
canvas.setDefaultCloseOperation(EXIT_ON_CLOSE);
//create two panels
//add them to contentPane
//set Layout
JPanel buttonPanel = createButtons();
JPanel mainPanel = new Graphic(); //extends JPanel and writes the paint method
mainPanel.setSize(1000, 1000);
Container content = canvas.getContentPane();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.add(mainPanel);
content.add(buttonPanel);
mainPanel.setSize(1000, 1000);
The job of the layout manager is to determine the size of the component, so you would never invoke the setSize() method of a components.
Instead you give hints to the layout manager on what the size should be. You would do this by overriding the getPreferredSize() method to return an appropriate value. Also, I would pick a more reasonable size (1000, 1000) is a little big to display on most screens. If you really want your painting area this large then I would add the paint panel to a JScrollPane and then add the scrollpane to the frame.
Try getting your code to work using a BoxLayout. Then I would suggest a better layout manager would be to use a BorderLayout. Then you add the paint panel to the CENTER and the buttons to the SOUTH. Now as you resize the frame the paint panel will be adjusted in size.
canvas.setVisible(true);
Also, the placement of that line of code is wrong. You should add all your components to the frame first, before making the frame visible.

JPanel expanded to JScrollPane size when smaller?

So I am trying to have a JPanel inside a JScrollPane, which is located directly inside a JFrame, resize so that it is sometimes smaller than the JScrollPane. Problem is that when I try this it, the lesser size seems to be resized to the original size of the JScrollPane. It works fine when I leave it at a larger size. How do I get this to work? Code will be provided if needed.
Wrap you panel in another panel that uses a FlowLayout. This way the outer panel will be resized to fill the viewport of the scroll pane:
JPanel red = new JPanel();
red.setBackground(Color.RED);
red.setPreferredSize( new Dimension(200, 200) );
JPanel outer = new JPanel();
outer.add( red );
add( new JScrollPane(outer) );

Categories

Resources