1

I am trying to create a JScrollPane that contains a JPanel that will be increasing and decreasing in height. When it becomes larger than the size of the JScrollPane, it should create a vertical scroll bar which will allow me to scroll through the entire JPanel. However, I am having difficulty achieving this. Yes, I know I am not using LayoutManagers. No, I will not be using them, and I need a solution that does not involve their usage.

Here are the two button's AbstractActions that add and subtract from the JPanel:

class AddACT extends AbstractAction
    {
      public void actionPerformed(ActionEvent e)
      {
        info.setSize(420,info.getHeight() + 40);
        info.add(new SubPanel); // Adds another JPanel into the main JPanel (for content input)
        gui.repaint();
        infoS.validate();
      }
    }

class RemoveACT extends AbstractAction
    {
      public void actionPerformed(ActionEvent e)
      {
        info.remove(subPanel()); // This would remove the last JPanel added to the main JPanel
        info.setSize(420,info.getHeight() - 40);
        gui.repaint();
        infoS.validate();
      }

And here is the code for the main JPanel and the JScrollPane:

final JPanel info = new JPanel();
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);  
info.setLayout(null);
info.setSize(420,600);
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)

This is the second project I've been trying to learn GUI by doing. I am a complete novice in Swing and am only intermediate in Java. Sorry if I am making a blindingly obvious mistake.

David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
Thrfoot
  • 125
  • 2
  • 7
  • 4
    -1 _Yes, I know I am not using layout managers. No, I will not be using them_ shrugs, it's your time you insist on wasting ;-) – kleopatra Nov 20 '12 at 16:39
  • Is is completely and absolutely necessary to use a layout manager? I was hoping that it wouldn't be necessary, and that, like most things in Java, there were other ways to do it. – Thrfoot Nov 20 '12 at 16:55
  • 1
    @Thrfoot : A quote from [**Java Docs**](http://docs.oracle.com/javase/tutorial/uiswing/layout/none.html) **"Although it is possible to do without a layout manager, you should use a layout manager if at all possible. A layout manager makes it easier to adjust to look-and-feel-dependent component appearances, to different font sizes, to a container's changing size, and to different locales. Layout managers also can be reused easily by other containers, as well as other programs."**. – nIcE cOw Nov 20 '12 at 17:05
  • All right, it seems I have no choice. If I were to use a layout manager (probably BoxLayout, to make a vertical list), what would I need to change (beyond the obvious changes like `setSize` to `setPreferredSize`)? I really am not sure as to how JScrollPane interacts with layout managers, and have never really used a layout manager before. – Thrfoot Nov 20 '12 at 17:11

2 Answers2

7

1) Use LayoutManagers (+1 to @kleopatra and @GagandeepBali comments)

The absence of LayoutManagers only guarantees your GUI's will look very trashy (especially when run on other OSes/builds) and being a Novice you should rather learn the correct way than learn the wrong way and get into bad habits like calling setSize() etc.

Have a read on these links to get you started:

2) See this example for how to use a JScrollPane, it simply adds a JPanel with buttons to a JScrollPane which in-turn is added to the JFrame.

3) Also see this example for how to make the JScrollPane vertically scroll-able only.

4) For more on JScrollPanes have a look here: How to Use Scroll Panes.

5) As for how it interacts with LayoutManager, if you do not explicitly set its size via setPreferredSize(Dimension d) the scroll pane computes it based on the preferred size of its nine components (the viewport, and, if present, the two scroll bars, the row and column headers, and the four corners)

6) On your usage of validate():

  • validate() is used when new JComponents are added to a visible component

  • revalidate() is used when JComponent is removed/added from a visible component

  • revalidate() covers validate() too

Thus always use this:

//add or remove component(s)
revalidate();
repaint();

References:

Community
  • 1
  • 1
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
2

LayoutManager is not required to solve the problem. The problem in Thrfoot's example is in these lines:

final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);  
info.setLayout(null);
info.setSize(420,600);

The program appears to recognize there is a need for scroll bars (it would show the scroll bar if your setting was VERTICAL_SCROLLBAR_AS_NEEDED), but the actual scrolling does not work (the scroll bar slider is not there).

To fix this, first set the preferred size of info, then construct the infoS.

Example:

info.setPreferredSize(420,600);
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

The idea is to set the preferred size of the info panel before it is used for the scroll pane. This is the same reason to set the size and location of infoS before adding to the gui:

infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)
JoshDM
  • 4,939
  • 7
  • 43
  • 72
jaytibann
  • 121
  • 3