title: Fixed-Width But Fluid-Height Component - Possible?
body: <p>If you use setPreferredSize() on a component, it fixes both width and height. Therefore, this is no good if I only want a fixed width, and to adapt the height as necessary to accommodate the contents into that constrained width. </p>
  
  <p>Consider a piece of HTML text. In a browser window, the string will automatically wrap and the height it requires adapt, so that it fits within the available width. So if we were to fix the width of the browser, the height of the text would remain fluid. </p>
  
  <p>Can the same be achieved with a component? Specifically, a JPanel. </p>
  
  <p>Note that I believed setMaximumSize() would do what I wanted - allow me to set a maximum width, and set the height to something huge so that it could never go wider than I specify, but had plenty of height to grow into. However, the system seems to completely ignore that function. For example: </p>
  
  <pre><code>import java.awt.BorderLayout;
  import java.awt.Color;
  import java.awt.Container;
  import java.awt.Dimension;
  
  import javax.swing.BoxLayout;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  import javax.swing.JViewport;
  
  public class TMSApp
  {
      public static void main(String[] args)
      {
          JFrame frame = new JFrame("TestMaximumSize"); 
          Container container = frame.getContentPane(); 
          container.setBackground(Color.RED); 
  
          container.setLayout(new BorderLayout() ); 
  
          JViewport viewport = new JViewport(); 
          viewport.setBackground(Color.BLACK); 
          viewport.setPreferredSize(new Dimension(640, 480) ); 
          container.add(viewport, BorderLayout.CENTER); 
  
          JPanel testPanel = new JPanel(); 
          testPanel.setBackground(Color.WHITE); 
          testPanel.setMaximumSize(new Dimension(100, 9999) ); 
          //testPanel.setPreferredSize(new Dimension(100, 9999) ); 
  
          viewport.setView(testPanel); 
  
          testPanel.setLayout(new BoxLayout(testPanel, BoxLayout.Y_AXIS) ); 
  
          testPanel.add(new JLabel("&lt;html&gt;This is a very long HTML label " 
                                      + "that should adapt to the width of " 
                                      + "the parent container by wrapping text, " 
                                      + "just as it would in a web page " 
                                      + "constrained to the window width.&lt;/html&gt;") ); 
  
          frame.setVisible(true); 
          frame.pack(); 
  
      }
  
  }
  </code></pre>
  
  <p>If you run this app, despite me saying 'no wider than 100', testPanel goes as wide as it needs to leave the label on one line. To me, this breaks the contract of setMaximumSize(). </p>
  
  <p>(Note that if you use setPreferredSize(), it <em>does</em> constrain it correctly - but we can't use setPreferredSize() on a component as mentioned above because it also fixes the height instead of giving it some fluidity - yes, setMaximumSize() would have limited the height eventually but it was acceptable).</p>
  
  <p>Any idea how I can control width but leave height to adapt as necessary? </p>
  
  <p>(For the record, I want to add a bunch of panels to a larger panel wrapped in a JScrollPane, thus acting as a list with panels instead of labels. I consider having to scroll the large panel sideways to see all of an item to be a bad UI, so I want the width to be no wider than the scroll pane's actual displayable area sans scroll bars, and thus have the smaller panels adjust their height in order to fit their content - JLabels with HTML strings - into the available width. Thus, the user would only need to scroll vertically to see all of each item. As demonstrated above, even manually using a viewport + scroll bar would suffer the same problem. </p>
  
  <p>If I could fix the width only of the larger panel, the smaller child panels would be automatically constrained by width; or, if I could fix the width only of the child panels the larger panel would never go wider than I want it.) </p>