失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Java图形化界面编程超详细知识点(8)——列表框

Java图形化界面编程超详细知识点(8)——列表框

时间:2021-09-20 05:16:51

相关推荐

Java图形化界面编程超详细知识点(8)——列表框

目录

5 JList、JCpmboBox实现列表框

5.1 简单列表框

5.2 不强制存储列表项的ListModel和ComboBoxMedel

5.3 强制存储列表项的DefaultListModel和DefaultComboBoxModel

5.4 使用ListCellRenderer改变列表外观

5 JList、JCpmboBox实现列表框

无论从哪个角度来看,JList和JComboBox都是极其相似的,他们都有一个列表框,只是JComboBox的列表框需要以下拉方式显示出来;JList和JComboBox都可以通过调用setRenderer()方法来改变列表项的表现形式。甚至维护这两个组件的Model都是相似的,JList使用ListModel,JComboBox使用ComboBoxModel,而ComboBoxModel是ListModel的子类。

5.1 简单列表框

使用JList或JComboBox实现简单列表框的步骤:

1.创建JList和JComboBox实现简单列表框的步骤:

JList(final E[ ] listData);创建JList对象,把listData数组中的每项内容转换成一个列表项显示

JList(final Vector<? extends E> listData);创建JList对象,把listData数组中的每项内容转换成一个列表项展示

JComboBox(E[ ] items);

JComboBox(Vector<E> items);

2.设置JList或JComboBox的外观行为

---------------------------------------JList--------------------------------------------------------------

addSelectionInterval(int anchor,int lead);在已经选中列表项的基础上,增加选中从anchor到lead索引范围内的所有列表项

setFixedCellHeight(int hight)/setFixedCellWidth(int width);设置列表项的高度和宽度

setLayoutOrientation(int layoutOrientation);设置列表框的布局方向

setSelectedIndex(int index);默认选中项

setSelectedIndices(int [ ] indices);设置默认选中的多个列表项

setSelectedValue(Object anObject,boolean shouldScroll);设置默认选中项,并滚动到该项显示

setSelectionBackground(Color selectionBackground);设置选中项的背景颜色

setSelectionForeground(Color selectionForeground);设置选中项的前景色

setSelectionInterval(int anchor,int lead);设置从anchor到lead范围内的所有列表项被选中

setSelectionMode(int selectionMode);设置选中模式,默认没有限制,也可以设置为单选或者区域选中

setVisibleRowCount(int visibleRowCount);设置列表框的可视高度足以显示多少行列表项

---------------------------------------JComboBox----------------------------------------------------

setEditable(boolean aFlag);设置是否可以直接修改列表文本框的值,默认为不可以

setMaximumRowCount(int count);设置列表框的可视高度足以显示多少行列表项

setSelectedIndex(int anIndex);设置默认选中项

setSelectedItem(Object anObject);根据列表项的值,设置默认选中项

3.设置监听器,监听列表变化,JList通过addListSelectionListener完成,JComboBox通过addItemListener完成。

案例:

public class ListTest {JFrame jf = new JFrame("列表框测试");String[] books = {"java自学宝典","轻量级javaEE企业应用实战","Android基础教程","jQuery实战教程","SpringBoot企业级开发"};//定义 布局选择按钮 所在的面板JPanel layoutPanel = new JPanel();ButtonGroup layoutGroup = new ButtonGroup();//定义 选择模式按钮 所在面板JPanel selectModePanel = new JPanel();ButtonGroup selectModeGroup = new ButtonGroup();JTextArea favorite = new JTextArea(4,40);//用一个字符串数组来创建一个JList对象JList<String> bookList ;JComboBox<String> bookSelector;public void init(){//组装视图//组装Jlist相关内容bookList = new JList<>(books);addBtn2LayoutPanel("纵向滚动",JList.VERTICAL);addBtn2LayoutPanel("纵向换行",JList.VERTICAL_WRAP);addBtn2LayoutPanel("横向换行",JList.HORIZONTAL_WRAP);addBtn2SelectModelPanel("无限制",ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);addBtn2SelectModelPanel("单选",ListSelectionModel.SINGLE_SELECTION);addBtn2SelectModelPanel("单范围",ListSelectionModel.SINGLE_INTERVAL_SELECTION);//对JList做设置bookList.setVisibleRowCount(3);bookList.setSelectionInterval(2,4);//处理条目选中事件bookList.addListSelectionListener(new ListSelectionListener() {@Overridepublic void valueChanged(ListSelectionEvent e) {//获取当前选中的条目List<String> selectedValuesList = bookList.getSelectedValuesList();//把当前条目的内容设置到文本域中。favorite.setText("");for (String str : selectedValuesList) {favorite.append(str+"\n");}}});Box bookListVBox = Box.createVerticalBox();bookListVBox.add(new JScrollPane(bookList));bookListVBox.add(layoutPanel);bookListVBox.add(selectModePanel);//组装JComboBoxVector<String> vector = new Vector<>();// List<String> list = List.of("java自学宝典", "轻量级javaEE企业应用实战", "Android基础教程", "jQuery实战教程", "SpringBoot企业级开发");// vector.addAll(list);for (int i = 0; i < books.length; i++) {vector.add(books[i]);}bookSelector = new JComboBox<>(vector);bookSelector.setEditable(true);bookSelector.setMaximumRowCount(4);bookSelector.addItemListener(new ItemListener() {@Overridepublic void itemStateChanged(ItemEvent e) {//获取当前已经选中的条目,把内容设置到文本域中Object selectedItem = bookSelector.getSelectedItem();favorite.setText(selectedItem.toString());}});//组装顶部的左右两部分Box topBox = Box.createHorizontalBox();topBox.add(bookListVBox);JPanel bookSelectPanel = new JPanel();bookSelectPanel.add(bookSelector);topBox.add(bookSelectPanel);//组装底部JPanel bottomPanel = new JPanel();bottomPanel.setLayout(new BorderLayout());bottomPanel.add(new JLabel("您最喜欢的图书:"),BorderLayout.NORTH);bottomPanel.add(favorite);//组装整体Box holeBox = Box.createVerticalBox();holeBox.add(topBox);holeBox.add(bottomPanel);jf.add(holeBox);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.pack();jf.setVisible(true);}//封装方法,往layoutPanel中添加单选按钮public void addBtn2LayoutPanel(String name,int layoutType){//设置标题边框layoutPanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选项布局"));//创建单选按钮JRadioButton button = new JRadioButton(name);layoutPanel.add(button);//让第一个按钮默认选中if (layoutGroup.getButtonCount()==0){button.setSelected(true);}layoutGroup.add(button);button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {bookList.setLayoutOrientation(layoutType);}});}//封装方法,给selectModelPanel添加按钮public void addBtn2SelectModelPanel(String name,int selectionModel){//设置标题边框selectModePanel.setBorder(new TitledBorder(new EtchedBorder(),"确定选择模式"));//创建单选按钮JRadioButton button = new JRadioButton(name);selectModePanel.add(button);//让第一个按钮默认选中if (selectModeGroup.getButtonCount()==0){button.setSelected(true);}selectModeGroup.add(button);button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {bookList.setSelectionMode(selectionModel);}});}public static void main(String[] args) {new ListTest().init();}}

5.2 不强制存储列表项的ListModel和ComboBoxMedel

与ProgressBar一样,JList和JComboBox也采用了MVC设计模式,JList和JComboBox只负责外观的显示,而组件底层的状态数据则由对应的Model来维护,JList对应的Model是ListModel接口,JComboBox对应的Model是ComboBox接口,其代码如下:

public interface ListModel<E>{int getSize();E getElementAt(int index);void addListDataListener(ListDataListener l);void removeListDataListener(ListDataListener l);}public interface ComboBoxModel<E> extends ListModel<E> {void setSelectedItem(Object anItem);Object getSelectedItem();}

从上面接口来看,这个ListModel不管JList里的所有列表项的存储形式,它甚至不强制存储所有的列表项,只要ListModel的实现类提供了getSize()和getElementAt()两个方法,JList就可以根据该ListModel对象来生成列表项。ComboBoxModel继承了ListModel,它添加了“选择项”的概念,选择项代表JComboBox显示区域内可见的列表项。

在使用JList和JComboBox时,除了可以使用jdk提供的Model实现类,程序员自己也可以根据需求,自己定义Model的实现类,实现对应的方法使用。

案例:

自定义NumberListModel和NumberComboBoxModel实现类,允许使用数据范围来创建JList和JComboBox:

public class NumberListModel extends AbstractListModel<BigDecimal> {BigDecimal start;BigDecimal end;BigDecimal step;public NumberListModel(BigDecimal start, BigDecimal end, BigDecimal step) {this.start = start;this.end = end;this.step = step;}@Overridepublic int getSize() {int floor = (int) Math.floor(end.subtract(start).divide(step,2, RoundingMode.HALF_DOWN).doubleValue());return floor+1;}@Overridepublic BigDecimal getElementAt(int index) {BigDecimal ele = new BigDecimal(index).multiply(step).add(start).setScale(2, RoundingMode.HALF_DOWN);return ele;}}

public class NumberComboBoxListModel extends NumberListModel implements ComboBoxModel<BigDecimal> {//当前选中条目的索引private int selectedId;public NumberComboBoxListModel(BigDecimal start, BigDecimal end, BigDecimal step) {super(start, end, step);}@Overridepublic void setSelectedItem(Object anItem) {if (anItem instanceof BigDecimal){BigDecimal curr = (BigDecimal) anItem;selectedId = curr.subtract(super.start).divide(super.step,2, RoundingMode.HALF_DOWN).intValue();}}@Overridepublic Object getSelectedItem() {BigDecimal item = new BigDecimal(selectedId).multiply(super.step).add(super.start).setScale(1, RoundingMode.HALF_DOWN);return item;}}

public class ListModelTest {JFrame jf = new JFrame("测试ListModel");JList<BigDecimal> jList = new JList<>(new NumberListModel(new BigDecimal(1),new BigDecimal(21),new BigDecimal(2)));JComboBox<BigDecimal> jComboBox = new JComboBox<>(new NumberComboBoxListModel(new BigDecimal(0.1),new BigDecimal(1.2),new BigDecimal(0.1)));JLabel label = new JLabel("您选择的值是:");JTextField jTextField = new JTextField(15);public void init(){//组装视图//组装顶部jList.setVisibleRowCount(4);jList.setSelectionInterval(2,4);jList.setFixedCellWidth(90);jList.setFixedCellHeight(30);jList.addListSelectionListener(new ListSelectionListener() {@Overridepublic void valueChanged(ListSelectionEvent e) {List<BigDecimal> selectedValuesList = jList.getSelectedValuesList();jTextField.setText("");for (BigDecimal item : selectedValuesList) {jTextField.setText(jTextField.getText()+item.toString()+",");}}});jComboBox.setMaximumRowCount(4);jComboBox.addItemListener(new ItemListener() {@Overridepublic void itemStateChanged(ItemEvent e) {Object selectedItem = jComboBox.getSelectedItem();jTextField.setText(selectedItem.toString());}});Box hBox = Box.createHorizontalBox();hBox.add(new JScrollPane(jList));JPanel tempPanel = new JPanel();tempPanel.add(jComboBox);hBox.add(tempPanel);jf.add(hBox);//组装底部JPanel bottomPanel = new JPanel();bottomPanel.add(label);bottomPanel.add(jTextField);jf.add(bottomPanel,BorderLayout.SOUTH);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.pack();jf.setVisible(true);}public static void main(String[] args) {new ListModelTest().init();}}

5.3 强制存储列表项的DefaultListModel和DefaultComboBoxModel

前面只是介绍了如何创建JList、JComboBox对象,当调用JList和JComboBox构造方法时传入数组或Vector作为参数,这些数组元素或集合元素将会作为列表项。当使用JList或JComboBox时常常还需要动态地增加、删除列表项,例如JCombox提供了下列方法完成增删操作:

addItem( E item);添加一个列表项

insertItemAt(E item,int index);向指定索引处插入一个列表项

removeAllItems();删除所有列表项

removeItem(Object anObject);删除指定列表项

removeItemAt(int anIndex);删除指定索引处的列表项

JList并没有提供这些类似的方法,如果需要创建一个可以添加、删除列表项的JList对象,则应该在创建JList的显式使用DefaultListModel作为构造参数。因为DefaultListModel作为JList的Model,它负责维护JList组件的所有列表数据,所以可以通过向DefaultListModel中添加、删除元素来实现向JList对象中增加、删除列表项。

DefaultListModel提供了如下方法来添加、删除元素:

add(int index,E element);在该ListModel的指定位置插入指定元素

addElement(E obj);将指定元素添加到该ListModel的末尾

insertElementAt(E obj,int index);在该ListModel的指定位置处插入指定元素

Object remove(int index);删除该ListModel中指定位置处的元素

removeAllElements();删除该ListModel中所有元素

removeElement(E obj);删除该ListModel中第一个与参数匹配的元素

removeElementAt(int index);删除该ListModel中指定索引处的元素

removeRange(int fromIndex,int toIndex);删除该ListModel中指定范围内的所有元素

set(int index,E element);将该ListModel指定索引处的元素替换成指定元素

setElement(E obj,int index);将该ListModel指定索引处的元素替换成指定元素

案例:

使用DefaultListModel实现下图效果:

public class DefaultListModelTest {JFrame jf = new JFrame("测试DefaultListModel");JTextField bookName = new JTextField(20);JButton removeBtn = new JButton("删除选中图书");JButton addBtn = new JButton("添加指定图书");//创建JListJList<String> bookList;DefaultListModel<String> model = new DefaultListModel<>();public void init(){//组装视图model.addElement("java自学宝典");model.addElement("轻量级JavaEE企业应用实战");model.addElement("Android基础教程");model.addElement("JQuery实战教程");bookList = new JList<>(model);//设置JlistbookList.setVisibleRowCount(4);//设置单选bookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);jf.add(new JScrollPane(bookList));//组装底部addBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String name = bookName.getText();if (!name.trim().equals("")){//不是空字符串才添加model.addElement(name);}}});removeBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int selectedIndex = bookList.getSelectedIndex();if (selectedIndex>=0){model.remove(selectedIndex);}}});JPanel bottomPanel = new JPanel();bottomPanel.add(bookName);bottomPanel.add(addBtn);bottomPanel.add(removeBtn);jf.add(bottomPanel,BorderLayout.SOUTH);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.pack();jf.setVisible(true);}public static void main(String[] args) {new DefaultListModelTest().init();}}

5.4 使用ListCellRenderer改变列表外观

前面程序中的JList和JComboBox采用的都是简单的字符串列表项,实际上,JList和JComboBox还可以支持图标列表项,如果在创建JList或JComboBox时传入图标数组,则创建的JList和JComboBox的列表项就是图标。

如果希望列表项是更复杂的组件,例如,希望像QQ一样每个列表项既有图标,又有字符串,此时需要使用ListCellRenderer接口的实现类对象,自定义每个条目组件的渲染过程:

public interface ListCellRenderer<E>{Component getListCellRendererComponent(JList<? extends E> list,//列表组件E value,//当前列表项的内容int index,//当前列表项的索引boolean isSelected,//当前列表项是否被选中boolean cellHasFocus);//当前列表项是否获取了焦点}

通过JList的setCellRenderer(ListCellRenderer<? super E> cellRenderer)方法,把自定义的ListCellRenderer对象传递给JList,就可以按照自定义的规则绘制列表项组件了。

案例:

使用ListCellRenderer实现下图效果:

public class ListCellRendererTest {private JFrame mainWin = new JFrame("好友列表");private String[] friends = {"李清照","苏格拉底","李白","弄玉","虎头"};//定义一个JList对象JList friendsList = new JList(friends);public void init() {//组装视图//给JList设置ListCellRenderer对象,指定列表项绘制的组件friendsList.setCellRenderer(new MyRenderer());mainWin.add(friendsList);mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);mainWin.pack();mainWin.setVisible(true);}private class MyRenderer extends JPanel implements ListCellRenderer{private String name;private ImageIcon icon;//记录背景色private Color backGround;//记录前景色:文字的颜色private Color forceGround;@Overridepublic Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {//重置成员变量的值this.name = value.toString();this.icon = new ImageIcon("E:\\GUISwing\\img\\tree\\"+name+".gif");this.backGround = isSelected? list.getSelectionBackground() : list.getBackground();this.forceGround = isSelected? list.getSelectionForeground() : list.getForeground();return this;}@Overridepublic Dimension getPreferredSize() {return new Dimension(60,80);}//绘制列表项的内容@Overridepublic void paint(Graphics g) {int imageWidth = icon.getImage().getWidth(null);int imageHeight = icon.getImage().getHeight(null);//填充背景矩形g.setColor(backGround);g.fillRect(0,0,getWidth(),getHeight());//绘制头像g.drawImage(icon.getImage(),this.getWidth()/2 -imageWidth/2 ,10,null);//绘制昵称g.setColor(forceGround);g.setFont(new Font("StSong",Font.BOLD,18));g.drawString(this.name,this.getWidth()/2 - this.name.length()*20/2,imageHeight+30);}}public static void main(String[] args) {new ListCellRendererTest().init();}}

如果觉得《Java图形化界面编程超详细知识点(8)——列表框》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。