The goal for the layout manager was to mimic the layout of icons in a "windows explorer" style arrangement. If you open up windows explorer and change the view to "List" mode, you will notice that you never see an active right-hand scrollbar. This List view will bound the window contents vertically and only activate the bottom horizontal scrollbar. If you change the windows explorer view to "Thumbnails", you will see the contrasting layout. In Thumbnails mode, you will not have an active bottom horizontal scrollbar, only the vertical bar will be available for scrolling up and down.
How to do this in java? The idea is similar to the windows explorer example. We have a panel full of little components, how can we set the boundaries of the viewport within the ScrollPane. Let me introduce ScrollFlowLayout
innerPanel = new Panel(); scroll = new ScrollPane(); scroll.add(innerPanel); innerPanel.setLayout(new ScrollFlowLayout(scroll));
Above is the main example of how to implement ScrollFlowLayout. The layout's default is "LEFT_TO_RIGHT", the same as "List" in Windows Explorer. There is also the option to set the layout orientation to "TOP_TO_BOTTOM", the same as "Thumbnails" view in Windows Explorer. One of the nice things about ScrollFlowLayout is that it extends Flowlayout, since the components in the panel are "flowing" across an area that is bounded by the ScrollPane's viewport.
The difference between the two layouts is how it lays out the sequence of inner components:
import java.awt.*;
import java.awt.event.*;
/**
* @author SMarkowitz
*
*/
public class ScrollFlowLayout extends FlowLayout {
public final static int LEFT_TO_RIGHT = 0;
public final static int RIGHT_TO_LEFT = 1;
public final static int TOP_TO_BOTTOM = 2;
private int orientation = TOP_TO_BOTTOM,rows,cols;
private ScrollPane sp = null;
public ScrollFlowLayout() {
super();
}
public ScrollFlowLayout(ScrollPane p) {
super();
this.sp = p;
}
public ScrollFlowLayout(ScrollPane p, int orientation) {
super();
this.sp = p;
this.orientation = orientation;
}
public int getTallestElement (Container c) {
int ncomponents = c.getComponentCount();
int h=0;
for (int i = 0; i < ncomponents ; i++) {
Component m = c.getComponent(i);
int x = m.getMinimumSize().height;
h = (h>x)?h:x;
}
return h;
}
public int getWidestElement(Container c) {
int ncomponents = c.getComponentCount();
int w=0;
for (int i = 0; i < ncomponents ; i++) {
Component m = c.getComponent(i);
int x = m.getMinimumSize().width;
w = (w>x)?w:x;
}
return w;
}
public Dimension preferredLayoutSize(Container target) {
int hBounds = target.getSize().height
- target.getInsets().bottom
- target.getInsets().top;
int wBounds = target.getSize().width;
if (sp != null) {
hBounds = sp.getSize().height
- sp.getInsets().bottom
- sp.getInsets().top;
wBounds = sp.getSize().width;
}
int ncomponents = target.getComponentCount();
if (ncomponents == 0) return new Dimension(0,0);
int widest = getWidestElement(target);
int tallest = getTallestElement(target);
int rows = (tallest > hBounds) ? 1 : hBounds / tallest;
int cols = (int)Math.ceil((double)ncomponents / rows);
if (orientation == LEFT_TO_RIGHT) {
cols = (widest>wBounds) ? 1 : wBounds/widest;
rows = (int)Math.ceil((double)ncomponents / cols);
}
Dimension d = new Dimension(cols*widest,rows*tallest);
return d;
}
public void layoutContainer(Container target) {
synchronized (target.getTreeLock()) {
int hBounds = target.getSize().height
- target.getInsets().bottom
- target.getInsets().top;
int wBounds = target.getSize().width;
if (sp != null) {
hBounds = sp.getSize().height
- sp.getInsets().bottom
- sp.getInsets().top;
wBounds = sp.getSize().width;
}
int ncomponents = target.getComponentCount();
int widest = getWidestElement(target);
int tallest = getTallestElement(target);
if (ncomponents == 0) {
return;
}
target.invalidate();
if (orientation == LEFT_TO_RIGHT) {
int i = 0;
int cols = (widest>wBounds) ? 1 : wBounds/widest;
int rows = (int)Math.ceil((double)ncomponents / cols);
for (int x = 0; x < rows ; x++) {
for (int y = 0; y < cols ; y++) {
if (i < ncomponents) {
int px = y*widest;
int py = x*tallest;
target.getComponent(i).setBounds(px
,py
,widest
,tallest);
}
i++;
}
}
}
else if (orientation == TOP_TO_BOTTOM) {
int rows = (tallest > hBounds) ? 1 : hBounds / tallest;
int cols = (int)Math.ceil((double)ncomponents / rows);
int i = 0;
for (int y = 0; y < cols ; y++) {
for (int x = 0; x < rows ; x++) {
if (i < ncomponents) {
int px = y*widest;
int py = x*tallest;
target.getComponent(i).setBounds(px
,py
,widest
,tallest);
}
i++;
}
}
}
}
}
}
L&M Art Gallery.com
See how we brought a small business to the Internet with a full service solution.
Go to the site
©2004 SM Consulting International LLC