1.需要【JScrollPane】对象,将JList放置在JScrollPane上,而不是普通的JPane中。
JScrollPane scrollPane = new JScrollPane(list);
panel_1.add(scrollPane, BorderLayout.CENTER);
2.需要【JList】对象,JList对象中设置模型
JList list = new JList();
3.需要【DefaultListCellRenderer】接口
(1)JList并不会显示图片,那么我们就重写JList的渲染器ListCellRenderer。可是ListCellRenderer是一个接口,在这里我们选择自定义一个DefaultListCellRenderer类,从API中,我们看到DefaultListCellRenderer继承了JLabel,这意味着我们可以使用这个类的对象,在绘制的时候直接设置JLabel标签的图标。而不用再去创建很多JLabel对象。
public class ImageCellRender extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
}
(2)真正控制如何绘制JList的是getListCellRendererComponent(参数列表)方法,所以我们在自定义类ImageCellRender 中需要重写getListCellRendererComponent(参数列表)方法,在重写里面的具体代码之前,我们先分析一下这个方法的参数列表:
JList<? extends Object> list:正在绘制的JList
Object value:由list.getModel().getElementAt(index)返回的值
int index:单元格索引
boolean isSelected:如果选择了指定的单元格,则为true
cellHsaFocus:如果指定的单元格拥有焦点,则为true
public class ImageCellRender extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
public Component getListCellRendererComponent(JList extends Object> list,
Object value, int index, boolean isSelected, boolean cellHasFocus){
}
}
(3)分析:在这个方法中我们需要做什么?
要setIcon(图标);我们需要一个ImageIcon对象
setIcon(ImageIcon imageIcon);
要ImageIcon对象,我们需要图片路径
ImageIcon icon = new ImageIcon(String imagePath);
要图片的路径,我们可以通过getListCellRendererComponent()方法传入图片文件
String imagePath = xxxx.....
(4)从上面的分析中,我们知道我们需要一个【File】类型的对象,这个对象的路径是文件夹中的某一个图片。所以在这个方法中我们需要传入的Value值为File类型的对象。而这个File对象全部存放于JList中,所以我们可以给JList定义一个泛型JList
4.需要【ListMode】对象
(1)重写好渲染器ImageCellRender之后,我们将开始往JList中存放元素。如果使用list.add()方法去添加元素,不利于我们对JList进行操作,JList为我们提供了一个list.setModel(ListModel listModel)方法。下面我们来看一下ListModel这个类。
(2)打开API我们会发现ListModel是一个接口,从名字来看实现子类中和ListModel相关的类有:AbstractListModel和DefaultListModel。点开DefaultListModel类后发现,DefaultListModel继承了AbstractListModel,而且具有很多对元素操作的方法。所以我们新建一个类,继承DefaultListModel,并对一些方法进行重写
public class ImageListModel extends DefaultListModel {
private static final long serialVersionUID = 1L;
private List imageFile = new ArrayList();
public void addElement(File file){
this.imageFile.add(file);
}
public int getSize(){
return imageFile.size();
}
public File getElementAt(int index){
return imageFile.get(index);
}
}
(3)创建一个imageFile集合对象,由于model中存放的都是File类型的对象,所以将List集合定义泛型为
5.需要【File】对象
(1)所有准备工作都做好了,那么我们现在需要创建File对象了。创建一个文件夹new File("文件路径"),从这个文件夹下获得文件夹中的全部文件,存进File[]数组中。使用foreach循环遍历files数组添加进listModel模型中。
File[] files = new File("head").listFiles();
for(File file : files){
listModel.addElement(file);
}
(2)注意:我的"head"中 放的全是jpg文件,如果路径下还有别的格式的文件(.txt .exe等)需要筛选!不然会报错!
File[] files = new File("head").listFiles(new FileFilter(){
public boolean accept(File file){
return file.getName().endsWith("jpg");
}
});
package JListAndImage;
import java.awt.BorderLayout;
import java.io.File;
import java.io.FileFilter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
public class JListDemo extends JFrame{
private static final long serialVersionUID = 1L;
public JListDemo(){
JList list = new JList();
ImageListModel listModel = new ImageListModel();
/**
* 这里使用了一个匿名内部内,来过滤文件格式
* files.list()是获取该目录下的所有文件
* files.listFiles()是获取该目录下所有文件和目录的绝对路径
* 我们在获取的时候可以传入一个【FileFilter】过滤器
* 用到一个匿名内部类,accept则是过滤方法,file.name得到这个文件的名字.endsWith("jpg")
* 在rootpath路径下筛选出jpg格式的文件存入files集合中
*
*/
File[] files = new File("head").listFiles(new FileFilter(){
public boolean accept(File file){
return file.getName().endsWith("jpg");
}
});
for(File file : files){
listModel.addElement(file);
}
list.setModel(listModel);
//设置JList的渲染器为我们自己构建的渲染器
list.setCellRenderer(new ImageCellRender());
//setVisibleRowCount设置显示的行数,但是如果设置了面板的高度 这个会不起效果
//list.setVisibleRowCount(4);
//将JList放在滚动面板上
JScrollPane scrollPane = new JScrollPane(list);
getContentPane().add(scrollPane, BorderLayout.CENTER);
getContentPane().add(new JLabel("带图片的Jlist"), BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(900, 350, 50, 300);
}
public static void main(String[] args) {
new JListDemo().setVisible(true);
}
}
package JListAndImage;
import java.awt.Color;
import java.awt.Component;
import java.awt.Image;
import java.io.File;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JList;
import javax.swing.SwingConstants;
/**
* DefaultListCellRenderer是Swing JList的渲染器
* ImageCellRender继承DefaultListCellRender,DefaultListCellRender继承于JLabel,所以只要将图片赋给JLabel就可以更改显示样式
* @author Silly
*
*/
public class ImageCellRender extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
/**
* 重写【ListCellRenderer】的getListCellRendererComponent()方法
* JList extends Object> list:表示JList中ListModel中存放的对象可以是任何引用类型(从JList的源码得知这个泛型是控制ListModel中对象类型的)
* Object value:由list.getModel().getElementAt(index)返回的值,也就是当前正在绘制的对象
* index:当前选择的单元格下标
* isSelected:单元格被选择的状态(这个被选择是发生在选择单元格改变时,如果选了A再选A返回是false,如果选了A选B再选A才为true)
* cellHasFocus:和isSelected的效果一样 不过没有用到这个参数 不知道有什么作用
*/
@Override
public Component getListCellRendererComponent(JList extends Object> list,
Object value, int index, boolean isSelected, boolean cellHasFocus){
//instanceof 判断其左边对象是否为其右边类的实例
if(value instanceof File){
File imageFile = (File) value;
try{
//拿到当前文件的URI再拿到URL
ImageIcon icon = new ImageIcon(imageFile.toURI().toURL());
//设置图标大小
icon.setImage(icon.getImage().getScaledInstance(50, 50, Image.SCALE_DEFAULT));
setIcon(icon);
//a.这里可以用html来控制字体的颜色
String text1 = ""+imageFile.getName()+"";
//b.也可以通过设置前景色来改变字体颜色
setForeground(Color.blue);
String text2 = imageFile.getName();
setText(text2);
//设置背景色
setBackground(Color.white);
//设置文本的水平和垂直位置:比如(右上)
setVerticalTextPosition(SwingConstants.TOP);
setHorizontalTextPosition(SwingConstants.RIGHT);
}catch(Exception e){
e.printStackTrace();
}
}
if(isSelected){
if(index == 0){
System.out.println("第一个被选择了,注意鼠标按下算一次,鼠标松开算一次,只有选择发生改变时才会触发,重复点击无效果");
}
}
if(cellHasFocus){
System.out.println("???");
}
return this;
}
}
package JListAndImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractListModel;
/**
* 【swing中JList控件使用】
* 每一项以 图片+文字(文字在图片的下面)的形式显示并且在水平方向排序
*
* 实现这个功能的重点在以下几个方面:
* (1)需要改变JList的cellRender来支持对图片的显示,默认的cellRender只会显示文本字符串
* (2)设置JList的每一项的显示方向(文字和图片的排列关系)
* (3)设置每一项选中后的背景
*
* @author Silly
*/
/**
* 1.创建一个ImageListModel,继承【AbstractListModel】,设置为JList的列表模型
* @author Silly
*
*/
public class ImageListModel extends AbstractListModel {
private static final long serialVersionUID = 1L;
private List imageFile = new ArrayList();
public void addElement(File file){
this.imageFile.add(file);
}
public int getSize(){
return imageFile.size();
}
public File getElementAt(int index){
return imageFile.get(index);
}
}
Over啦~ 初学Swing整理了下思路 希望跟我一样的初学者能看懂