【Java】高级Swing——JList

Java中广泛采用一种接口式的设计,这使得Java的Swing组件的表现上十分灵活。

Jlist究竟是如何设计的呢?事实上:Jlist把图形和数据进行的分离。JList中可以T可以是字符串数组。

String[] text={
    
    A,B,C,D};
JList<String> list=new JList<String>(text);

如想要自由地添加列表元素,可以获得一个DefaultListModel,它实现了ListModel接口

DefaultListModel<String> model=new DefaultListModel<>();

使用addElement()就可以添加元素了,并且还会通知JList重新绘制列表。

改变JList的外观需要设置单元格渲染器,单元格渲染器需要继承JComponent并实现ListCellRenderer接口

每次绘制单元格时,就会调用public Component
getListCellRendererComponent(JList<? extends Object> list, Object value,
int index,boolean isSelected, boolean cellHasFocus)方法,并返回
Component对象,并使用paintComponent()方法绘制出单元格,绘制完成后,调用
getPreferredSize()返回组件的大小。

有一种简单的方法就是在public Component
getListCellRendererComponent(JList<? extends Object> list, Object value,
int index,boolean isSelected, boolean cellHasFocus)方法中创建JLabel对象并返回,这样就不要我们用画笔(Graphics对象)绘制了。这就相当于在列表中加入了标签。

JList是不带滚动条的,也需要我们自己去定制。

不得不承认,这十分复杂,但这样的设计可以使得我们自由的设置列表的样式。甚至对每一个单元格都可以定制它的样式。这用其他的语言实现恐怕会需要更多的代码。

下面给出一个例子

package JList;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;

import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;

public class JListTest {
    
    

	public static void main(String[] args) 
	{
    
    
		AreaListFrame frame=new AreaListFrame("Area");
		EventQueue.invokeLater(()->{
    
    
			frame.setVisible(true);
		});
	}
	
}
class AreaListFrame extends JFrame
{
    
    
	private JList<String> areaList;
	public AreaListFrame(String title)
	{
    
    
		super(title);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new BorderLayout());
		JPanel cpanel=new JPanel();
		DefaultListModel<String> model=new DefaultListModel<>();
		model.addElement("安徽");		
		model.addElement("湖南");
		model.addElement("山东");
		model.addElement("东北");
		model.addElement("辽宁");
		model.addElement("湖北");
		model.addElement("河北");
		model.addElement("河南");
		model.addElement("江苏");
		model.addElement("浙江");
		model.addElement("新疆");
		areaList=new JList<>(model);
		areaList.setCellRenderer(new MyRenderer());
		//后来加入元素,列表自动重新绘制
		model.addElement("黑龙江");
		cpanel.add(new JScrollPane(areaList),BorderLayout.CENTER);
		add(cpanel);
		pack();
	}
	class MyRenderer extends JComponent implements ListCellRenderer<String>
	{
    
    
		private Font font=new Font(Font.SANS_SERIF,Font.PLAIN,18);
		private String text;
		private int index;
		private Color evenColor=Color.LIGHT_GRAY;
		private Color oddColor=new Color(34, 134, 235);
		private Color selectedColor=Color.RED;
		private Color background;
		@Override
		public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
				boolean isSelected, boolean cellHasFocus)
		{
    
    
			text=value;
			
			
			list.setSelectionBackground(selectedColor);
			this.index=index;
			//根据是否选中得到动态的颜色
			ibackground = isSelected ? selectedColor : index%2==0? evenColor:oddColor;
			return this;
		}
		public void  paintComponent(Graphics g)
		{
    
    
			FontMetrics fm=g.getFontMetrics(font);
			
			g.setColor(background);
			g.fillRect(0, 0, getWidth(), getHeight());
			g.setColor(Color.GREEN);
			g.drawString(text,0 ,fm.getAscent());
		}
		@Override
		public Dimension getPreferredSize()
		{
    
    
			Graphics g=getGraphics();
			FontMetrics fm=g.getFontMetrics(font);
			return new Dimension(fm.stringWidth(text),fm.getHeight());
		}
		
		/*public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
				boolean isSelected, boolean cellHasFocus)
		{
			JLabel j1=new JLabel(value);
			
			j1.setOpaque(true);
			evenColor=Color.LIGHT_GRAY;
			oddColor=new Color(34, 134, 235);
			if(index%2==0) j1.setBackground(evenColor);
			else j1.setBackground(oddColor);
			
			j1.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,16));
			if(isSelected) j1.setBackground(Color.YELLOW);
			
			return j1 ;
		}
		*/
	}
	
}

猜你喜欢

转载自blog.csdn.net/m0_47202518/article/details/108301520
今日推荐