用Java实现了简单的列表功能,仅供参考,效果如图所示:
ListView.java
package gditc.studio401.listview;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ListView extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean flag;
private JLabel lblIcon;
private JLabel lblItemName;
private ImageIcon image;
private ImageIcon bgImage;
private ItemPanel item;
private JPanel listItems;
public ListView() {
// TODO Auto-generated constructor stub
}
public ListView(String groupName, String[] groupItems) {
// TODO Auto-generated constructor stub
this.setLayout(new BorderLayout());
flag = false;
lblIcon = new JLabel();
listItems = new JPanel();
listItems.setLayout(new BoxLayout(listItems, BoxLayout.Y_AXIS));
arrowIcon();
item = new ItemPanel();
item.setLayout(new FlowLayout(FlowLayout.LEFT));
item.setBackground(new Color(0x5186BE));
lblItemName = new JLabel(groupName);
item.add(lblIcon);
item.add(lblItemName);
this.add(item, BorderLayout.NORTH);
creatItems(listItems, groupItems);
lblIcon.addMouseListener(new MyMouseAdapter());
lblItemName.addMouseListener(new MyMouseAdapter());
this.addMouseListener(new MyMouseAdapter());
}
private void creatItems(JPanel listItem, String[] groupItems) {
// TODO Auto-generated method stub
for (int i = 0; i < groupItems.length; i++) {
int size = 16;
Label label = new Label(groupItems[i]);
label.setFont(new Font("arial", Font.PLAIN, size));
label.setBackground(new Color(0xE3EAF2));
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
label.setBackground(new Color(0x9AC7F6));
}
@Override
public void mouseExited(MouseEvent e) {
label.setBackground(new Color(0xE3EAF2));
}
});
listItem.add(label);
}
this.add(listItem, BorderLayout.CENTER);
}
private class MyMouseAdapter extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
arrowIcon();
}
}
private void arrowIcon() {
this.setVisible(false);
if (flag == false) {
image = new ImageIcon(this.getClass().getResource(
"/images/arrow-right.png"));
listItems.setVisible(false);
lblIcon.setIcon(image);
flag = true;
} else {
image = new ImageIcon(this.getClass().getResource(
"/images/arrow.png"));
listItems.setVisible(true);
lblIcon.setIcon(image);
flag = false;
}
this.setVisible(true);
}
public class ItemPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
bgImage = new ImageIcon(this.getClass().getResource(
"/images/bg-item.png"));
g.drawImage(bgImage.getImage(), 0, 0, null);
}
}
}
VFlowLayout.java
package gditc.studio401.listview;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import javax.swing.JFrame;
/**
* VerticalFlowLayout is similar to FlowLayout except it lays out components
* vertically. Extends FlowLayout because it mimics much of the behavior of the
* FlowLayout class, except vertically. An additional feature is that you can
* specify a fill to edge flag, which causes the VerticalFlowLayout manager to
* resize all components to expand to the column width Warning: This causes
* problems when the main panel has less space that it needs and it seems to
* prohibit multi-column output. Additionally there is a vertical fill flag,
* which fills the last component to the remaining height of the container.
*/
public class VFlowLayout extends FlowLayout {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Specify alignment top.
*/
public static final int TOP = 0;
/**
* Specify a middle alignment.
*/
public static final int MIDDLE = 1;
/**
* Specify the alignment to be bottom.
*/
public static final int BOTTOM = 2;
private int hgap;
private int vgap;
private boolean hfill;
private boolean vfill;
/**
* Construct a new VerticalFlowLayout with a middle alignment, and the fill
* to edge flag set.
*/
public VFlowLayout() {
this(TOP, 0, 1, true, false);
}
/**
* Construct a new VerticalFlowLayout with a middle alignment.
*
* @param hfill
* the fill to edge flag
* @param vfill
* the vertical fill in pixels.
*/
public VFlowLayout(boolean hfill, boolean vfill) {
this(TOP, 0, 1, hfill, vfill);
}
/**
* Construct a new VerticalFlowLayout with a middle alignment.
*
* @param align
* the alignment value
*/
public VFlowLayout(int align) {
this(align, 0, 1, true, false);
}
/**
* Construct a new VerticalFlowLayout.
*
* @param align
* the alignment value
* @param hfill
* the horizontalfill in pixels.
* @param vfill
* the vertical fill in pixels.
*/
public VFlowLayout(int align, boolean hfill, boolean vfill) {
this(align, 0, 1, hfill, vfill);
}
/**
* Construct a new VerticalFlowLayout.
*
* @param align
* the alignment value
* @param hgap
* the horizontal gap variable
* @param vgap
* the vertical gap variable
* @param hfill
* the fill to edge flag
* @param vfill
* true if the panel should vertically fill.
*/
public VFlowLayout(int align, int hgap, int vgap, boolean hfill,
boolean vfill) {
setAlignment(align);
this.hgap = hgap;
this.vgap = vgap;
this.hfill = hfill;
this.vfill = vfill;
}
/**
* Returns the preferred dimensions given the components in the target
* container.
*
* @param target
* the component to lay out
*/
public Dimension preferredLayoutSize(Container target) {
Dimension tarsiz = new Dimension(0, 0);
for (int i = 0; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
tarsiz.width = Math.max(tarsiz.width, d.width);
if (i > 0) {
tarsiz.height += hgap;
}
tarsiz.height += d.height;
}
}
Insets insets = target.getInsets();
tarsiz.width += insets.left + insets.right + hgap * 2;
tarsiz.height += insets.top + insets.bottom + vgap * 2;
return tarsiz;
}
/**
* Returns the minimum size needed to layout the target container.
*
* @param target
* the component to lay out.
* @return the minimum layout dimension.
*/
public Dimension minimumLayoutSize(Container target) {
Dimension tarsiz = new Dimension(0, 0);
for (int i = 0; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getMinimumSize();
tarsiz.width = Math.max(tarsiz.width, d.width);
if (i > 0) {
tarsiz.height += vgap;
}
tarsiz.height += d.height;
}
}
Insets insets = target.getInsets();
tarsiz.width += insets.left + insets.right + hgap * 2;
tarsiz.height += insets.top + insets.bottom + vgap * 2;
return tarsiz;
}
/**
* Set true to fill vertically.
*
* @param vfill
* true to fill vertically.
*/
public void setVerticalFill(boolean vfill) {
this.vfill = vfill;
}
/**
* Returns true if the layout vertically fills.
*
* @return true if vertically fills the layout using the specified.
*/
public boolean getVerticalFill() {
return vfill;
}
/**
* Set to true to enable horizontally fill.
*
* @param hfill
* true to fill horizontally.
*/
public void setHorizontalFill(boolean hfill) {
this.hfill = hfill;
}
/**
* Returns true if the layout horizontally fills.
*
* @return true if horizontally fills.
*/
public boolean getHorizontalFill() {
return hfill;
}
/**
* places the components defined by first to last within the target
* container using the bounds box defined.
*
* @param target
* the container.
* @param x
* the x coordinate of the area.
* @param y
* the y coordinate of the area.
* @param width
* the width of the area.
* @param height
* the height of the area.
* @param first
* the first component of the container to place.
* @param last
* the last component of the container to place.
*/
private void placethem(Container target, int x, int y, int width,
int height, int first, int last) {
int align = getAlignment();
if (align == MIDDLE) {
y += height / 2;
}
if (align == BOTTOM) {
y += height;
}
for (int i = first; i < last; i++) {
Component m = target.getComponent(i);
Dimension md = m.getSize();
if (m.isVisible()) {
int px = x + (width - md.width) / 2;
m.setLocation(px, y);
y += vgap + md.height;
}
}
}
/**
* Lays out the container.
*
* @param target
* the container to lay out.
*/
public void layoutContainer(Container target) {
Insets insets = target.getInsets();
int maxheight = target.getSize().height
- (insets.top + insets.bottom + vgap * 2);
int maxwidth = target.getSize().width
- (insets.left + insets.right + hgap * 2);
int numcomp = target.getComponentCount();
int x = insets.left + hgap, y = 0;
int colw = 0, start = 0;
for (int i = 0; i < numcomp; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
// fit last component to remaining height
if ((this.vfill) && (i == (numcomp - 1))) {
d.height = Math.max((maxheight - y),
m.getPreferredSize().height);
}
// fit component size to container width
if (this.hfill) {
m.setSize(maxwidth, d.height);
d.width = maxwidth;
} else {
m.setSize(d.width, d.height);
}
if (y + d.height > maxheight) {
placethem(target, x, insets.top + vgap, colw,
maxheight - y, start, i);
y = d.height;
x += hgap + colw;
colw = d.width;
start = i;
} else {
if (y > 0) {
y += vgap;
}
y += d.height;
colw = Math.max(colw, d.width);
}
}
}
placethem(target, x, insets.top + vgap, colw, maxheight - y, start,
numcomp);
}
}
MainFrame.java
package gditc.studio401.listview;
import javax.swing.JFrame;
public class MainFrame {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 300, 600);
VFlowLayout vfl = new VFlowLayout();
frame.setLayout(vfl);
String itemName = "item name";
String[] groupItems = { "item1", "item2", "item3" };
for(int i = 0; i < 10; i++) {
frame.add(new ListView(itemName, groupItems));
}
frame.setVisible(true);
}
}