Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Custom component in a JScrollPane - how/where to set the correct height?

800390Aug 25 2008 — edited Aug 27 2008
Hello,

I had a hard time trying to get the following done, but I'm totally stuck. The initial situation is this:

I have a JFrame with a JScrollPane in it. The content (more precisely the viewPortView) of that scroll pane is my own class "MyComponent", which extends a JPanel. What this MyComponent class does is to dynamically creates some JLabels and adding it to itself. I can parameterize it (in my example code below) to specify how many JLabels should be created. The layout of MyComponent is "TableLayout", and for each added JLabel I first create a new row (so every JLabel is in it's own row). I could say that MyComponent is a bit like a JTable.

The problem is: I need to set the preferred size (only the height) of MyComponent, so the surrounding JScrollPane can display it's scroll bars correctly. That is all - and I just don't know where and when I must set the size.

Some thoughts about the problem:

- I can set the height of MyComponent not until the frame (or
dialog...) has been displayed (setVisible(true)).

- I think it is correct that the Layout Manager (TableLayout) must
first layout all JLabels in MyComponent, and than I must use the
"layout.preferredLayoutSize( container )" method to determine the
real size (height)? I'm not sure about this..

- Maybe I must override amethod of MyComponent in which I calculate
and/or set the height of MyComponent?

- I'm not sure, but the JTable component does the same thing? It is
a component, that "grows vertically" and lies in a JScrollPane,
therefore must adjust it's own size to the JScrollPane is able to
display the scroll bars correctly.

To make things easier to understand, I wrote a small program to demonstrate my problem. It consists of two simple classes - the first one creates the window and the scrollpane, the second class is the MyComponent:
public class CustomCompInScrollpaneTest {
  public CustomCompInScrollpaneTest() {
    // Creating the frame
    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(800, 600);
    frame.setLocationRelativeTo(null);
    frame.setLayout(null);
    
    // Create Scrollpane
    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setSize(300, 300);
    scrollPane.setPreferredSize(new Dimension(300, 300));
    scrollPane.setLocation(100, 100);
    
    // Add MyComponent with 5 rows to the scrollpane
    scrollPane.setViewportView(new MyComponent(5));
    
    // Add scrollpane to frame and show it
    frame.add(scrollPane);
    SwingUtilities.invokeLater(new Runnable() {
	  @Override public void run() {
	    frame.setVisible(true);
      }
    });
  }

  public static void main(String[] args) {
    new CustomCompInScrollpaneTest();
  }
}
The second class is the interesting one:
public class MyComponent extends JPanel {
  public MyComponent(int count) {
    // Create table layout with just one column and 0 rows (rows get added in the for loop)
    TableLayout layout = new TableLayout(new double[] {TableLayout.FILL}, new double[0]);
    setLayout(layout);
		
    // Set preferred size - by setting this, especially the x-value, the
    // line/word wrapping of the JLabels will work
    setPreferredSize(new Dimension(0, 0));

    // Create count rows
    for (int row = 0; row < count; row++) {
      JLabel label = new JLabel();
      label.setBorder( BorderFactory.createLineBorder(Color.RED));
      label.setText(
        "<html>" + 
            "<div style='font-size:18px'>" + 
            "This is JLabel #" + ( row + 1 ) + ".<br>" +
            "And this is the second line of the label text." +  
          "</div>" +
        "</html>"
      );

      // Insert a new row and adding the JLabel 
      layout.insertRow(row, TableLayout.PREFERRED);
      add(label, "0, " + row); 
    }
  }
}
(The only dependency of the example above is the TableLayout layout manager.)

The second class is the one, that should set it's own size - if I understand that correctly.
Please have a look at the line "setPreferredSize(new Dimension(0, 0));", when I omit the line, the JLabel-word-wrap does not work. I need to set the x value of the preferred size at least to get word wrapping.

The question is now, where and how must I set the preferred height of MyComponent? Or is it the complete wrong way or do I misunderstand anything here? Isn't the JTable doing the same?


I really appreciatie any help you can give me


Thanks a lot!


Best Regards,
Ben
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 24 2008
Added on Aug 25 2008
7 comments
443 views