问题
I would like to have layout manager which works like Windows Explorer in folder view (not any list view). What I need is something like this Marginal Layout panel like Windows 7 Explorer ListView in Swing. Is there any way to customize standard layouts or do you know any external layouts?
回答1:
http://java-sl.com/tip_columns_flow_layout.html The link to screenshot and article about the code below
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class ColumnsFlowLayout implements LayoutManager {
int hGap;
int vGap;
public ColumnsFlowLayout() {
this(2,2);
}
public ColumnsFlowLayout(int hGap, int vGap) {
this.hGap=hGap;
this.vGap=vGap;
}
public void addLayoutComponent(String name, Component comp) {
}
public void removeLayoutComponent(Component comp) {
}
public Dimension preferredLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
int count = target.getComponentCount();
int visibleCount = 0;
for (int i=0; i<count; i++) {
if (target.getComponent(i).isVisible()) {
visibleCount++;
}
}
Insets insets = target.getInsets();
Dimension maxPref=getCellSize(target);
if (target.getWidth()!=0) {
int maxWidth = target.getWidth() - (insets.left + insets.right);
int colCount=maxWidth/(maxPref.width+hGap);
int row=visibleCount/colCount;
if (visibleCount % colCount!=0) {
row++;
}
dim.width += insets.left + insets.right + hGap*(visibleCount-1)+maxPref.width*visibleCount;
dim.height += insets.top + insets.bottom + row*maxPref.height;
}
else {
dim.width += insets.left + insets.right + hGap*(visibleCount-1)+maxPref.width*visibleCount;
dim.height += insets.top + insets.bottom + maxPref.height;
}
return dim;
}
}
private Dimension getCellSize(Container target) {
Dimension maxPref=new Dimension();
int count = target.getComponentCount();
for (int i = 0 ; i < count ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
maxPref.width = Math.max(maxPref.width, d.width);
maxPref.height = Math.max(maxPref.height, d.height);
}
}
return maxPref;
}
public Dimension minimumLayoutSize(Container target) {
return preferredLayoutSize(target);
}
/**
* Lays out the container.
*
* @param target the specified component being laid out
* @see Container
* @see java.awt.Container#doLayout
*/
public void layoutContainer(Container target) {
synchronized (target.getTreeLock()) {
Insets insets = target.getInsets();
int maxWidth = target.getWidth() - (insets.left + insets.right);
int count = target.getComponentCount();
Dimension cellSize=getCellSize(target);
int x=insets.left;
int y=insets.top;
int row=0;
int colCount=maxWidth/(cellSize.width+hGap);
int realHGap=colCount>1 ?(maxWidth-colCount*(cellSize.width+hGap))/(colCount-1) : 0;
for (int i = 0 ; i < count ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
m.setSize(cellSize.width, cellSize.height);
m.setLocation(x, y+row*(cellSize.height+vGap));
x+=hGap+cellSize.width+realHGap;
if (x+cellSize.width>=maxWidth) {
row++;
x=insets.left;
}
}
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Multi column flow layout (Windows Explorer like)");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel container=new JPanel(new ColumnsFlowLayout(3,3));
container.setBorder(new EmptyBorder(2,2,2,2));
for (int i=0; i<27; i++) {
container.add(new JButton("Test "+i));
}
frame.getContentPane().add(container);
frame.setSize(500, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
来源:https://stackoverflow.com/questions/9385800/is-there-any-layout-which-works-like-windows-explorer