Package charvax.swing

Source Code of charvax.swing.JList

/* class JList
*
* Copyright (C) 2003  R M Pitman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
* Modified Jul 15, 2003 by Tadpole Computer, Inc.
* Modifications Copyright 2003 by Tadpole Computer, Inc.
*
* Modifications are hereby licensed to all parties at no charge under
* the same terms as the original.
*
* Fixed case where visible row count was larger that the total number
* of rows in the model.
*/

package charvax.swing;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;

import charva.awt.Container;
import charva.awt.Dimension;
import charva.awt.EventQueue;
import charva.awt.Insets;
import charva.awt.Point;
import charva.awt.Scrollable;
import charva.awt.Toolkit;
import charva.awt.event.KeyEvent;
import charva.awt.event.MouseEvent;
import charva.awt.event.ScrollEvent;
import charva.awt.event.ScrollListener;
import charvax.swing.event.ListSelectionListener;

/**
* A component that allows the user to select one or more objects from a
* list.<p>
*
* The JList does not provide scrolling capability. The
* JList is normally inserted into a JScrollPane to provide scrolling.<p>
*
*/
public class JList
    extends JComponent
    implements Scrollable
{
    /** Constructs a JList with 5 rows, 10 columns wide.
     */
    public JList() {
  setModel(new DefaultListModel());
    }

    /**
     * Construct a JList that displays the elements in the specified
     * non-null model.
     */
    public JList(ListModel model_) {
  setModel(model_);
    }

    /**
     * Construct a JList containing the items in the specified array.
     */
    public JList(Object[] items_)
    {
  setListData(items_);
    }

    /**
     * Construct a JList containing the items in the specified Vector.
     */
    public JList(Vector<?> items_)
    {
  setListData(items_);
    }

    /** Constructs a ListModel from an array of Objects and then applies
     * setModel to it.
     */
    public void setListData(Object[] listData_) {
  DefaultListModel model = new DefaultListModel();

  for (int i=0; i<listData_.length; i++) {
      model.addElement(listData_[i]);
  }
  setModel(model);
    }

    /** Constructs a ListModel from a Vector and then applies setModel to it.
     */
    public void setListData(Vector<?> listData_) {
  Enumeration<?> e = listData_.elements();
  DefaultListModel model = new DefaultListModel();

  while (e.hasMoreElements()) {
      Object item = e.nextElement();
      model.addElement(item);
  }
  setModel(model);
    }

    /** Sets the model that represents the "contents" of the list, and
     * clears the selection.
     */
    public void setModel(ListModel model_) {
  _listModel = model_;
  _selectionModel.clearSelection();
    }

    /** Returns the data model that holds the list of items displayed by this
     * JList.
     */
    public ListModel getModel() {
  return _listModel;
    }

    /** Set the maximum number of rows that can be displayed at a time
     * by the JScrollPane which contains this JList.
     */
    public void setVisibleRowCount(int rows_) {
  _visibleRows = rows_;
    }

    public int getVisibleRowCount() {
  return _visibleRows;
    }

    /** Set the number of columns INSIDE the list.
     */
    public void setColumns(int cols_) {
  _columns = cols_;
    }

    public Dimension getSize() {
  return new Dimension(getWidth(), getHeight());
    }

    public int getWidth() {
  Insets insets = super.getInsets();
  return _columns + insets.left + insets.right;
    }

    public int getHeight() {
  Insets insets = super.getInsets();
  return _listModel.getSize() + insets.top + insets.bottom;
    }

    /** Returns the size of the viewport needed to display visibleRows rows.
     */
    public Dimension getPreferredScrollableViewportSize() {
  return new Dimension(getWidth(), getVisibleRowCount());
    }

    /** Sets the selection model of the JList to an implementation
     * of the ListSelectionModel interface.
     */
    public void setSelectionModel(ListSelectionModel model_) {
  _selectionModel = model_;
    }

    /** Returns the list's implementation of ListSelectionModel.
     */
    public ListSelectionModel getSelectionModel() {
  return _selectionModel;
    }

    /**
     * Register an ListSelectionListener object for this component.
     * The listener is notified each time a change to the selection occurs.
     */
    public void addListSelectionListener(ListSelectionListener il_) {
  _selectionModel.addListSelectionListener(il_);
    }

    /** Remove the specified ListSelectionListener from the list of listeners
     * that will be notified when the selection changes.
     */
    public void removeListSelectionListener(ListSelectionListener listener_) {
  _selectionModel.removeListSelectionListener(listener_);
    }

    /**
     * Get the first selected index, or -1 if there is no selected index.
     */
    public int getSelectedIndex() {
  return _selectionModel.getMinSelectionIndex();
    }

    /** Returns an array of the selected indices. The indices are
     * sorted in increasing index order.
     */
    public int[] getSelectedIndices() {
  ArrayList<Integer> objects = new ArrayList<Integer>();
  if ( ! _selectionModel.isSelectionEmpty()) {
      int first = _selectionModel.getMinSelectionIndex();
      int last = _selectionModel.getMaxSelectionIndex();
      for (int i=first; i<=last; i++) {
    if (_selectionModel.isSelectedIndex(i))
        objects.add(new Integer(i));
      }
  }

  int[] values = new int[objects.size()];
  for (int i=0; i<values.length; i++) {
      values[i] = objects.get(i).intValue();
  }
  return values;
    }

    /**
     * Get the first selected item on this list, or <code>null</code>
     * if the selection is empty.
     */
    public Object getSelectedValue() {

  /* Return null if there are no selected items.
   */
  int index = _selectionModel.getMinSelectionIndex();
  if (index == -1)
      return null;

  return _listModel.getElementAt(index);
    }

    /** Returns an array of the selected values. The objects are
     * sorted in increasing index order.
     */
    public Object[] getSelectedValues() {
  ArrayList<Object> objects = new ArrayList<Object>();
  if ( ! _selectionModel.isSelectionEmpty()) {
      int first = _selectionModel.getMinSelectionIndex();
      int last = _selectionModel.getMaxSelectionIndex();
      for (int i=first; i<=last; i++) {
    if (_selectionModel.isSelectedIndex(i))
        objects.add(_listModel.getElementAt(i));
      }
  }
  return objects.toArray();
    }

    /**
     * Make the specified item visible (by scrolling the list up or down).
     * This method does not do anything unless the JList is in a JViewport.
     * Note that the list is not redrawn by this method; the redrawing is
     * done by the JScrollPane (that is registered as a ScrollListener).
     */
    public synchronized void ensureIndexIsVisible(int index_) {
  if ( ! (getParent() instanceof JViewport) )
      return;

  if (index_ < 0)
      index_ = 0;
  else if (index_ > _listModel.getSize() - 1) {
      index_ = _listModel.getSize() - 1;
  }

  // It seems reasonable to assume that the "current row" should
  // be set to the index that is being made visible.
  _currentRow = index_;

  Toolkit term = Toolkit.getDefaultToolkit();
  EventQueue evtqueue = term.getSystemEventQueue();

  // First scroll the list DOWN so that index 0 is visible.
  evtqueue.postEvent(
          new ScrollEvent(this, ScrollEvent.DOWN,
    new Point(0, 0)));

  // Then (if necessary) scroll it UP so that the specified index
  // is not below the bottom of the viewport.
  evtqueue.postEvent(
          new ScrollEvent(this, ScrollEvent.UP,
    new Point(0, index_)));
    }

    /**
     * Select the item at the specified index. Note that this method
     * does not redraw the JList.
     */
    public void setSelectedIndex(int index_) {
  _selectionModel.setSelectionInterval(index_, index_);
    }

    /**
     * Sets the selection to be the set union between the current
     * selection and the specified interval between index0_ and index1_
     * (inclusive).
     */
    public void addSelectionInterval(int index0_, int index1_) {
  _selectionModel.addSelectionInterval(index0_, index1_);
    }

    /**
     * Sets the selection to be the set difference between the current
     * selection and the specified interval between index0_ and index1_
     * (inclusive).
     */
    public void removeSelectionInterval(int index0_, int index1_) {
  _selectionModel.removeSelectionInterval(index0_, index1_);
    }

    /** Clears the selection. After this <code>isSelectionEmpty()</code>
     * will return true.
     */
    public void clearSelection() {
  _selectionModel.clearSelection();
    }

    /** Returns the lowest selected item index.
     */
    public int getMinSelectionIndex() {
  return _selectionModel.getMinSelectionIndex();
    }

    /** Returns the highest selected item index.
     */
    public int getMaxSelectionIndex() {
  return _selectionModel.getMaxSelectionIndex();
    }

    /**
     * Sets the flag that determines whether this list allows multiple
     * selections.
     * @param mode_ the selection mode. Allowed values are:<p>
     * <ul>
     * <li> ListSelectionModel.SINGLE_SELECTION. Only one list index
     * can be selected at a time.
     * <li> ListSelectionModel.SINGLE_INTERVAL_SELECTION.
     * <li> ListSelectionModel.MULTIPLE_INTERVAL_SELECTION. Any number
     * of list items can be selected simultaneously.
     * </ul>
     */
    public void setSelectionMode(int mode_) {
  _selectionModel.setSelectionMode(mode_);
    }

    /**
     * Determines whether this list allows multiple selections.
     */
    public int getSelectionMode() {
  return _selectionModel.getSelectionMode();
    }

    /** Determines if the specified item in this scrolling list is selected.
     */
    public boolean isIndexSelected(int index_) {
  return _selectionModel.isSelectedIndex(index_);
    }

    /**
     * Called by LayoutManager.
     */
    public Dimension minimumSize() {

  /* Calculate the minimum number of columns that will contain all the
   * items in the list.
   */
  _columns = 1;
  for (int i=0; i< _listModel.getSize(); i++) {
      String c = _listModel.getElementAt(i).toString();
      if (c.length() > _columns)
    _columns = c.length();
  }

  /* Take into account the border inherited from the JComponent
   * superclass.
   */
  Insets insets = super.getInsets();
  return new Dimension(_columns + insets.left + insets.right,
    _visibleRows + insets.top + insets.bottom);
    }

    public void requestFocus() {
  /* Generate the FOCUS_GAINED event.
   */
  super.requestFocus();

  /* Get the absolute origin of this component
   */
  Point origin = getLocationOnScreen();
  Insets insets = super.getInsets();
  origin.translate(insets.left, insets.top);
  Toolkit.getDefaultToolkit().setCursor(
    origin.addOffset(0, _currentRow));
    }

    /** Draws this component. Overrides draw() in Component.
     * @param toolkit
     */
    public void draw(Toolkit toolkit) {

  /* This situation can occur if the ListModel has been changed.
   */
  if (_currentRow >= _listModel.getSize()) {
      if (_listModel.getSize() == 0)
    _currentRow = 0;
      else
    _currentRow = _listModel.getSize() - 1;
  }

  /* Draw the border if it exists
   */
  super.draw(toolkit);

  /* Get the absolute origin of this component.
   */
  Point origin = getLocationOnScreen();
  Insets insets = super.getInsets();
  origin.translate(insets.left, insets.top);

  int colorpair = getCursesColor();
  int attribute;

  StringBuffer blanks = new StringBuffer();
  for (int j=0; j<_columns; j++)
      blanks.append(' ');

  for (int i = 0; i < _listModel.getSize(); i++) {

      toolkit.setCursor(origin.x, origin.y + i);

      if (isIndexSelected(i))
    attribute = Toolkit.A_REVERSE;
      else
    attribute = 0;

      if (i == _currentRow)
    attribute += Toolkit.A_BOLD;

      String item = _listModel.getElementAt(i).toString();

      StringBuffer buffer = new StringBuffer(item);
      for (int k=item.length(); k<_columns; k++)
    buffer.append(' ');

      toolkit.addString(buffer.toString(), attribute, colorpair);
  // end FOR loop

  for (int i = _listModel.getSize(); i < _visibleRows; i++) {
      toolkit.setCursor(origin.x, origin.y + i);
      toolkit.addString(blanks.toString(), 0, colorpair);
  }
    }

    public void processKeyEvent(KeyEvent ke_) {
  /* First call all KeyListener objects that may have been registered
   * for this component.
   */
  super.processKeyEvent(ke_);

  /* Check if any of the KeyListeners consumed the KeyEvent.
   */
  if (ke_.isConsumed())
      return;

  Toolkit term = Toolkit.getDefaultToolkit();
  EventQueue evtqueue = term.getSystemEventQueue();
  int key = ke_.getKeyCode();
  switch (key) {
      case '\t':
    getParent().nextFocus();
    return;

      case KeyEvent.VK_BACK_TAB:
    getParent().previousFocus();
    return;

      case KeyEvent.VK_DOWN:
    /* If we are already at the bottom of the list, ignore
     * this keystroke.
     */
    if (_currentRow >= _listModel.getSize() -1)
        return;

    evtqueue.postEvent(
        new ScrollEvent(this, ScrollEvent.UP,
      new Point(0, ++_currentRow)));
    break;

      case KeyEvent.VK_PAGE_DOWN:
    _currentRow += _visibleRows;
    if (_currentRow >= _listModel.getSize())
        _currentRow = _listModel.getSize() -1;

    evtqueue.postEvent(
        new ScrollEvent(this, ScrollEvent.UP,
      new Point(0, _currentRow)));
    break;

      case KeyEvent.VK_END:
    _currentRow = _listModel.getSize() - 1;
    evtqueue.postEvent(new ScrollEvent(
            this, ScrollEvent.UP, new Point(0, _currentRow)));
    break;

      case KeyEvent.VK_UP:
    /* If we are already at the top of the list, ignore
     * this keystroke.
     */
    if (_currentRow < 1)
        return;

    evtqueue.postEvent(new ScrollEvent(
            this, ScrollEvent.DOWN, new Point(0, --_currentRow)));
    break;

      case KeyEvent.VK_PAGE_UP:
    _currentRow -= _visibleRows;
    if (_currentRow < 0)
        _currentRow = 0;

    evtqueue.postEvent(new ScrollEvent(this, ScrollEvent.DOWN,
      new Point(0, _currentRow)));
    break;

      case KeyEvent.VK_ENTER:
    _doSelect();
    break;

      case KeyEvent.VK_HOME:
    _currentRow = 0;
    break;
  }

  if ((getParent() instanceof JViewport) == false) {
      draw(Toolkit.getDefaultToolkit());
      requestFocus();
      super.requestSync();
  }
    }

    private void _doSelect() {
  /* Pressing ENTER or double-clicking on a row selects/deselects
   * the current row. If the list is empty, ignore the keystroke.
   */
  if (_listModel.getSize() == 0)
      return;

  if (isIndexSelected(_currentRow))
      removeSelectionInterval(_currentRow, _currentRow);
  else {
      int mode = getSelectionMode();
      if (mode == ListSelectionModel.SINGLE_SELECTION)
    setSelectedIndex(_currentRow);
      else
    addSelectionInterval(_currentRow, _currentRow);
  }
  repaint();
    }

    public void processMouseEvent(MouseEvent e_) {
  super.processMouseEvent(e_);

  if (e_.getButton() == MouseEvent.BUTTON1 &&
    e_.getModifiers() == MouseEvent.MOUSE_CLICKED &&
    this.isFocusTraversable()) {

      if (e_.getClickCount() == 1) {
    int y = e_.getY();
    Point origin = getLocationOnScreen();
    Container parent = getParent();
    if (parent instanceof JViewport) {
        _currentRow = y - origin.y;
        repaint();
    }
      }
      else
    _doSelect();
  }
    }

    /**
     * Register a ScrollListener object for this JList.
     */
    public void addScrollListener(ScrollListener sl_) {
  if (_scrollListeners == null)
      _scrollListeners = new Vector<ScrollListener>();
  _scrollListeners.add(sl_);
    }

    /**
     * Remove a ScrollListener object that is registered for this JList.
     */
    public void removeScrollListener(ScrollListener sl_) {
  if (_scrollListeners == null)
      return;
  _scrollListeners.remove(sl_);
    }

    /** Process scroll events generated by this JList.
     */
    public void processScrollEvent(ScrollEvent e_) {
  if (_scrollListeners != null) {
      for (Enumeration<ScrollListener> e = _scrollListeners.elements();
        e.hasMoreElements(); ) {

    ScrollListener sl = (ScrollListener) e.nextElement();
    sl.scroll(e_);
      }
  }
    }

    /** Outputs a textual description of this component to stderr.
     */
    public void debug(int level_) {
  for (int i=0; i<level_; i++)
      System.err.print("    ");
  System.err.println("JList origin=" + _origin +
      " size=" + minimumSize());
    }

    //================================================================
    // INSTANCE VARIABLES

    private int _visibleRows = 5;
    private int _columns = 10;

    /** Offset (from start of list) of the item under the cursor (i.e. the
     * item that will be selected/deselected if the user presses ENTER)
     */
    protected int _currentRow = 0;

    /** The ListSelectionModel used by this JList.
     */
    protected ListSelectionModel _selectionModel =
      new DefaultListSelectionModel();

    /** The ListModel that holds the items that are displayed by
     * this JList.
     */
    protected ListModel _listModel;

    /** A list of ScrollListeners registered for this JList.
     */
    private Vector<ScrollListener> _scrollListeners = null;

}
TOP

Related Classes of charvax.swing.JList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.