List Model controls (1)

Source: Internet
Author: User

Chapter 12 explores the border range components that support scrolling and entering or displaying certain boundary range values. In this chapter, we will discuss two selection controls for the Option List: jlist and jcombobox. The main difference between the two components is that the jlist component supports multiple choices, but jcombobox does not. In addition, jcombobox allows users to provide options that are not available.

13.1 listmodel Interface

Figure 13-1 shows the two controls we will explore in this chapter.

The data model shared between the two components is listmodel, which forms the listmode interface. The abstractlistmodel class provides the basis for implementation by supporting the management and notification of listdatalistener objects.

For the jlist component, the defaultlistmodel class is used to implement the data model. This class adds an actual data warehouse, which follows the vector API and can be used to display different elements in the jlist component.

For the jcombobox component, a listmodel interface extension named comboboxmodel provides the concept of selecting a project in the model. The defaultcomboboxmodel class uses another interface. mutablecomboboxmodel implements the comboboxmodel interface. mutablecomboboxmodel provides support for adding and removing elements in the model.

Note that the basicdirectorymodel class is another listmodel implementation. This implementation is used by the file selector component jfilechooser described in Chapter 1.

In fact, the listmodel interface is very simple. It provides listdatalistener management and accesses the dimensions of specific elements of the model.

public interface ListModel {  // Properties  public int getSize();  // Listeners  public void addListDataListener(ListDataListener l);  public void removeListDataListener(ListDataListener l);  // Other methods  public Object getElementAt(int index);}
13.1.1 abstractlistmodel class

The abstractlistmodel class provides partial implementation of the listmodel interface. We only need to provide the data structure and data. This class provides objects for listdatalistener list management and a framework for notification of these listeners when data changes. You can use the public listdatalistener [] getlistdatalistener () method to obtain the listener list. When we modify the data model, we must call the corresponding method of abstractlistmodel to notify the listener in the listdatalistener object:

  • Protected void fireintervaladded (Object source, int index0, int index1): called after adding a continuous range value to the list.
  • Protected void fireintervalremoved (Object source, int index0, int index1): called after a continuous range value is removed from the list.
  • Protected void firecontentschanged (Object source, int index0, int index1): this parameter is called if the modified range is insert, remove, or both, and is not consecutive.

If our data is in an existing data structure, we need to convert it to a format that the swing component can understand or implement the listmodel interface by ourselves. As we will see, the data or vector is directly supported by jlist and jcombobox. We can wrap our data structure into abstractlistmodel. For example, if our initial data structure is the arraylist in the Collection framework, we can use the following code to convert it to a listmodel:

final List arrayList = ...;ListModel model = new AbstractListModel() {  public int getSize() {    return arrayList.size();  }  public Object getElementAt(int index) {    return arrayList.get(index);  }}

Another choice is to pass the list to the vector constructor, and then pass the vector to the jlist constructor. In fact, we have completed the same event.
13.1.2 defalistlistmodel class

The defaultlistmodel class provides a data structure for us to store internal data in the form of a vector. We only need to add data, because this class manages listdatalistener for us.

First, we use a constructor without parameters to create a data structure: defaultlistmodel model = new defaultlistmodel (). Then we perform ice packing. As shown in table 13-1, The defaultlistmodel class has only two attributes.

The defaultlistmodel class provides all the operation methods through a series of public methods. To add an element, use the following method:

public void add(int index, Object element)public void addElement(Object element)public void insertElementAt(Object element, int index)

The addelement () method of defaultlistmodel adds the element to the end of the data model. To modify an element, use the following method:

public Object set(int index, Object element)public void setElementAt(Object element, int index)

To remove an element, use the following method:

public void clear()public Object remove(int index)public void removeAllElements()public boolean removeElement(Object element)public void removeElementAt(int index)public void removeRange(int fromIndex, int toIndex)

The removeelement () method returns a state. If an object is found and removed, true is returned. Otherwise, false is returned.

The defalutlistmodel class is useful when data is not stored in an existing data structure. For example, the database query result is returned as a JDBC resultset. If we want to use these results as the basis for the content displayed in the jlist, We must store them in some places. This can be stored in defalistlistmodel, as shown in the following code:

ResultSet results = aJDBCStatement.executeQuery(   "SELECT columnName FROM tableName");DefaultListModel model = new DefaultListModel();while (results.next()) {  model.addElement(result.getString(1));}
13.1.3 use listdatalistener to listen to listmodel events

If you are interested in determining when the content of the list model changes, you can register a listdatalistsener with the model. The three separate methods of the interface tell us when the content is added, removed, or modified. Modifying a data model means adding or removing content from or without adding or removing elements to or modifying existing content in one or more regions of the data model. The interface is defined as follows:

public interface ListDataListener extends EventListener {  public void contentsChanged(ListDataEvent e);  public void intervalAdded(ListDataEvent e);  public void intervalRemoved(ListDataEvent e);}

Based on the List modification event notification, we can pass a listdataevent implementation, which contains three modifications required, as shown in table 13-2.

The index is not required by the sequence or the boundary of the region to be modified. In the example of modifying the list model content, not all content in the region is modified. The region where the content actually changes is the border area specified by the index. The Type attribute is one of the three constants in Table 13-3, which is directly mapped to the called interface method.


If the ultlistmodel class operation method is called, The listdatalistener object is associated with the data model, and each listener will be notified of changes to the data model. To demonstrate the use of listdatalistesner and the dynamic update of the data model, the modifymodelsample program in the list 13-1 uses the defaultlistmodel class modification method to send the output in the form of an event and list the contents of jtextarea.

package swingstudy.ch13; import java.awt.BorderLayout;import java.awt.EventQueue;import java.awt.FlowLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.PrintWriter;import java.io.StringWriter; import javax.swing.DefaultListModel;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JList;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.event.ListDataEvent;import javax.swing.event.ListDataListener; public class ModifyModelSample { static String labels[] = {"Chardonnay", "Sauvignon", "Riesling", "Cabernet","Zinfandel", "Merlot", "Pinot Noir", "Sauvignon Blanc", "Syrah", "Gewurztraminer"}; /** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub Runnable runner = new Runnable() {public void run() {JFrame frame = new JFrame("Modifying Model");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Fill modelfinal DefaultListModel model = new DefaultListModel();for(int i=0; i<labels.length; i++) {model.addElement(labels[i]);} JList jList = new JList(model);JScrollPane scrollPane1 = new JScrollPane(jList);frame.add(scrollPane1, BorderLayout.WEST); final JTextArea textArea = new JTextArea();textArea.setEditable(false);JScrollPane scrollPane2 = new JScrollPane(textArea);frame.add(scrollPane2, BorderLayout.CENTER); ListDataListener listDataListener = new ListDataListener() {public void contentsChanged(ListDataEvent event) {appendEvent(event);}public void intervalAdded(ListDataEvent event) {appendEvent(event);}public void intervalRemoved(ListDataEvent event) {appendEvent(event);}private void appendEvent(ListDataEvent event) {StringWriter sw = new StringWriter();PrintWriter pw = new PrintWriter(sw);switch(event.getType()) {case ListDataEvent.CONTENTS_CHANGED:pw.print("Type: contents Changed");break;case ListDataEvent.INTERVAL_ADDED:pw.print("Type: Interval Added");break;case ListDataEvent.INTERVAL_REMOVED:pw.print("Type: Interval Removed");break;}pw.print(", Index0: "+event.getIndex0());pw.print(", Index1 "+event.getIndex1());DefaultListModel theModel = (DefaultListModel)event.getSource();pw.println(theModel);textArea.append(sw.toString());}}; model.addListDataListener(listDataListener); // Set up buttonsJPanel jp = new JPanel(new GridLayout(2,1));JPanel jp1 = new JPanel(new FlowLayout(FlowLayout.CENTER, 1,1));JPanel jp2 = new JPanel(new FlowLayout(FlowLayout.CENTER, 1,1));jp.add(jp1);jp.add(jp2);JButton jb = new JButton("add F");jp1.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {model.add(0, "First");}});jb = new JButton("addElement L");jp1.add(jb);jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent event) {model.addElement("Last");}});jb = new JButton("insertElementAt M");jp1.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {int size = model.getSize();model.insertElementAt("Middle", size/2);}});jb = new JButton("set F");jp1.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {int size = model.getSize();if (size != 0) {model.set(0, "New First");}}});jb = new JButton("setElementAt L");jp1.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {int size = model.getSize();if(size!=0)model.setElementAt("New Last", size-1);}});jb = new JButton("load 10");jp1.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {for(int i=0, n=labels.length; i<n; i++) {model.addElement(labels[i]);}}});jb =  new JButton("clear");jp2.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {model.clear();}});jb = new JButton("remove F");jp2.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {int size = model.getSize();if(size !=0)model.remove(0);}});jb = new JButton("removeAllElements");jp2.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {model.removeAllElements();}});jb = new JButton("removeElement 'Last'");jp2.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {model.removeElement("Last");}});jb = new JButton("removeElementAt M");jp2.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {int size = model.getSize();if(size != 0)model.removeElementAt(size/2);}});jb = new JButton("removeRange FM");jp2.add(jb);jb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {int size = model.getSize();if(size !=0)model.removeRange(0, size/2);}});frame.add(jp, BorderLayout.SOUTH);frame.setSize(640, 300);frame.setVisible(true);}};EventQueue.invokeLater(runner);} }

Figure 13-2 shows the program running result.

The method for obtaining the defalistlistmodel class will change with their functions. This class has basic access methods: Public object get (INT index), Public object getelementat (INT index), and public object elementat (INT index ), all three methods can accomplish the same thing. The defaultlistmodel class also has more special methods. For example, to use all elements, we can use the public enumeration elements () method to obtain the enumeration instance.

Or if we want to operate all the elements in an array, we can use public object [] toarray () or public void copyinto (Object anarray []). We can also use methods to check whether an element exists in the model, such as public Boolean contains (object element), Public int indexof (object element), Public int indexof (object element, int index), Public int lastindexof (object element), and public int lastindexof (object element, int index ).

Note: It is a good idea to use the public void trimtosize () method to adjust the length of an element to be added to the data model. This removes the extra space allocated within the data structure. In addition, if we know the data size, we can call Public void ensurecapacity (INT mincapacity) to pre-allocate space. Both methods can be used for defalistlistmodel.

13.1.4 comboboxmodel Interface

The comboboxmodel interface extends the listmodel interface. The main reason for the extension is that the class implementing the comboboxmodel interface needs to manage the selected project through the selecteditem attribute, as shown in the following interface definition:

public interface ComboBoxModel extends ListModel {  // Properties  public Object getSelectedItem();  public void setSelectedItem(Object anItem);}
13.1.5 mutablecomboboxmodel Interface

In addition to the comboboxmodel interface, the other data model interface mutablecomboboxmodel extends the comboboxmodel to form a method for modifying the data model.

public interface MutableComboBoxModel extends ComboBoxModel {  // Other methods  public void addElement(Object obj);  public void insertElementAt(Object obj, int index);  public void removeElement(Object obj);  public void removeElementAt(int index);}

The jcombobox component uses this interface by default.
13.1.6 defaultcomboboxmodel class

The abstractcomboboxmodel class extends the abstractlistmodel class to provide corresponding methods for jcombobox. This extension inherits the management of the listdatalistener list.

Similar to defalistlistmodel, defacomcomboboxmodel adds the required data structure for collecting elements displayed in the component. At the same time, because the model is changeable, the implementation of mutablecomboboxmodel will make appropriate changes to the data elements in the model, the data model calls various filexxx () Methods of abstractlistmodel.

NOTE: If defaultcomboboxmodel is created for an array, the elements of the array will be copied to an internal data structure. If we use vector, they will not be copied; instead, the actual vector will be used internally.

To use the data model, we must first use the following constructor to create the model:

public DefaultComboBoxModel()DefaultComboBoxModel model = new DefaultComboBoxModel();public DefaultComboBoxModel(Object listData[])String labels[] = { "Chardonnay", "Sauvignon", "Riesling", "Cabernet", "Zinfandel",  "Merlot", "Pinot Noir", "Sauvignon Blanc", "Syrah", "Gewürztraminer"};DefaultComboBoxModel model = new DefaultComboBoxModel(labels);public DefaultComboBoxModel(Vector listData)Vector vector = aBufferedImage.getSources();DefaultComboBoxModel model = new DefaultComboBoxModel(vector);

Then, we operate the model. The defaultcomboboxmodel class introduces two new attributes, as shown in table 13-4.

The Data Model Modification Method of defaultcomboboxmodel is different from that of defalistlistmodel. They are from the mutablecomboboxmodel interface:

public void addElement(Object element)public void insertElementAt(Object element, int index)public boolean removeElement(Object element)public void removeElementAt(int index)

Due to the flexibility (and functionality) of defaultcomboboxmodel, we usually do not need to create our own comboboxmodel implementation. You only need to create a defaultcomboboxmodel instance, and then use the corresponding data source to assemble it.

Note that we may want to provide an example of our own model when we need to support representation of the same project in multiple models. For defaultcomboboxmodel, if we have two items in the list of its equals () method that returns true, the model will not work correctly.

If we really want to define our own model implementation, maybe because we already have data stored in our data structure, the best way is to inherit abstractlistmodel and implement the comboboxmodel or mutablecomboboxmodel interface method. When inheriting abstractlistmodel, we only need to provide the data structure and its access interface. Because the "selected project" part of the data model is managed outside of the basic data structure, we also need to provide a location for storage. The program source code in list 13-2 demonstrates the implementation of using arraylist as the data structure. The program contains the main () method to demonstrate the use of the model in jcombobox.

package swingstudy.ch13; import java.awt.BorderLayout;import java.awt.EventQueue;import java.util.ArrayList;import java.util.Collection; import javax.swing.AbstractListModel;import javax.swing.ComboBoxModel;import javax.swing.JComboBox;import javax.swing.JFrame; public class ArrayListComboBoxModel extends AbstractListModel implements ComboBoxModel{ private Object selectedItem;private ArrayList anArrayList; public ArrayListComboBoxModel(ArrayList arrayList) {anArrayList = arrayList;} public Object getSelectedItem() {return selectedItem;} public void setSelectedItem(Object newValue) {selectedItem = newValue;} public int getSize() {return anArrayList.size();} public Object getElementAt(int i) {return anArrayList.get(i);}/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub Runnable runner = new Runnable() {public void run() {JFrame frame = new JFrame("ArrayListComboBoxModel");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Collection<Object> col = System.getProperties().values();ArrayList<Object> arrayList = new ArrayList<Object>(col);ArrayListComboBoxModel model = new ArrayListComboBoxModel(arrayList); JComboBox comboBox = new JComboBox(model); frame.add(comboBox, BorderLayout.NORTH);frame.setSize(300, 225);frame.setVisible(true);}};EventQueue.invokeLater(runner);} }

Figure 13-3 shows the data source model that uses the current system attribute as the data model element.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.