/* * Code found at: http://groups.google.fr/group/comp.lang.java.gui/browse_thread/thread/11403002a25da9a3/da4cea55cf283a52?q=%2BJscrollPane++%2Bflowlayout&rnum=2&hl=fr#da4cea55cf283a52 * Chris Long <*> all...@cs.berkeley.edu <*> http://www.cs.berkeley.edu/~allanl * * This file has been adapted to Jajuk by the Jajuk Team. * */ package ext; import java.awt.AWTError; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import org.jdesktop.swingx.JXPanel; /** * . */ public class FlowScrollPanel extends JXPanel { /** Generated serialVersionUID. */ private static final long serialVersionUID = 1L; private FlowLayout layout = new FlowLayout(); private JScrollPane scroller; /** * Instantiates a new flow scroll panel. */ public FlowScrollPanel() { this(null); } /** * Instantiates a new flow scroll panel. * * @param scrollPane */ public FlowScrollPanel(JScrollPane scrollPane) { super(); super.setLayout(layout); setScroller(scrollPane); } /** * Sets the scroller. * * @param scrollPane the new scroller */ public final void setScroller(JScrollPane scrollPane) { // FIXME: do we really want to compare instances here instead of content?? if (scroller != scrollPane) { scroller = scrollPane; if (scroller != null) { scroller.getViewport().setView(this); scroller.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { scroller.getViewport().setViewSize(getSize()); scroller.invalidate(); scroller.validate(); doLayout(); } }); } } } /* (non-Javadoc) * @see javax.swing.JComponent#getPreferredSize() */ @Override public Dimension getPreferredSize() { if (scroller == null) { return super.getPreferredSize(); } Insets insets = getInsets(); int hgap = layout.getHgap(); int vgap = layout.getVgap(); JScrollBar vsb = scroller.getVerticalScrollBar(); if (vsb == null) { vsb = scroller.createVerticalScrollBar(); } int scrollerWidth = scroller.getSize().width - (insets.left + insets.right + hgap * 2) - vsb.getSize().width /*-2*/; // the -2 is a voodoo constant. I don't know why it's needed, but // it is. (I suspect that this routine and FlowLayout compute // required sizes in a subtly different way.) // No longer needed with Swing 1.1 (I think). int nmembers = getComponentCount(); int x = 0, y = insets.top + vgap; int rowh = 0; int maxRowWidth = scrollerWidth; for (int i = 0; i < nmembers; i++) { Component m = getComponent(i); if (m.isVisible()) { Dimension d = m.getPreferredSize(); if ((x == 0) || ((x + d.width) <= scrollerWidth)) { if (x > 0) { x += hgap; } x += d.width; rowh = Math.max(rowh, d.height); } else { if (x > maxRowWidth) { maxRowWidth = x + hgap; } x = d.width; y += vgap + rowh; rowh = d.height; } } } if (x > maxRowWidth) { maxRowWidth = x + 2 * hgap + insets.left + insets.right; } y += vgap + rowh + insets.bottom; return new Dimension(maxRowWidth, y); } /* (non-Javadoc) * @see java.awt.Container#setLayout(java.awt.LayoutManager) */ @Override public void setLayout(LayoutManager l) { if (l instanceof FlowLayout) { layout = (FlowLayout) l; super.setLayout(l); } else { throw new AWTError("FlowScrollPane can have only FlowLayout, not " + l); } } // // Scrollable methods // /* (non-Javadoc) * @see org.jdesktop.swingx.JXPanel#getPreferredScrollableViewportSize() */ @Override public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } /** * Returns height of a row. * * @param visibleRect * @param orientation * @param direction * * @return the scrollable unit increment */ @Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { Dimension prefSize = layout.preferredLayoutSize(this); return prefSize.height / 20; } /** * returns the height of the visible rect (so it scrolls by one screenfull). * * @param visibleRect * @param orientation * @param direction * * @return the scrollable block increment */ @Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return visibleRect.height; } /* (non-Javadoc) * @see org.jdesktop.swingx.JXPanel#getScrollableTracksViewportWidth() */ @Override public boolean getScrollableTracksViewportWidth() { return true; } /* (non-Javadoc) * @see org.jdesktop.swingx.JXPanel#getScrollableTracksViewportHeight() */ @Override public boolean getScrollableTracksViewportHeight() { return false; } }