Package net.datacrow.console.components.lists

Source Code of net.datacrow.console.components.lists.DcListUI$PropertyChangeHandler

/******************************************************************************
*                                     __                                     *
*                              <-----/@@\----->                              *
*                             <-< <  \\//  > >->                             *
*                               <-<-\ __ /->->                               *
*                               Data /  \ Crow                               *
*                                   ^    ^                                   *
*                              info@datacrow.net                             *
*                                                                            *
*                       This file is part of Data Crow.                      *
*       Data Crow is free software; you can redistribute it and/or           *
*        modify it under the terms of the GNU General Public                 *
*       License as published by the Free Software Foundation; either         *
*              version 3 of the License, or any later version.               *
*                                                                            *
*        Data Crow 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 General Public License for more details.             *
*                                                                            *
*        You should have received a copy of the GNU General Public           *
*  License along with this program. If not, see http://www.gnu.org/licenses  *
*                                                                            *
******************************************************************************/

package net.datacrow.console.components.lists;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ListUI;
import javax.swing.plaf.basic.BasicListUI;

import net.datacrow.console.components.lists.elements.DcListElement;

import org.apache.log4j.Logger;

public class DcListUI extends BasicListUI {
   
    private static Logger logger = Logger.getLogger(DcListUI.class.getName());
   
    protected final static int columnsPerRowChanged = cellRendererChanged << 1;
    protected int columnsPerRow = 1;
    protected int[] cellWidths    = null;

    /**
     * Paint the rows that intersect the Graphics objects clipRect.
     * This method calls paintCell as necessary.  Subclasses
     * may want to override these methods.
     *
     * @see #paintCell
     */
    @Override
    public void paint(Graphics g, JComponent c) {
       
        try {
            try {
                maybeUpdateLayoutState();
            } catch (Exception e) {
                logger.error(e, e);
            }

            ListCellRenderer renderer = list.getCellRenderer();
            ListModel dataModel = list.getModel();
            ListSelectionModel selModel = list.getSelectionModel();
            if ((renderer == null) || (dataModel.getSize() == 0))
                return;

            // Compute the area we're going to paint in terms of the affected
            // columns/rows (firstPaintColumn, firstPaintRow, lastPaintColumn,
            // lastPaintRow), and the clip bounds.
            Rectangle paintBounds = g.getClipBounds();
  
            int firstPaintColumn = convertXToColumn(paintBounds.x);
            int firstPaintRow = convertYToRow(paintBounds.y);
            int lastPaintColumn = convertXToColumn((paintBounds.x+ paintBounds.width) - 1);
            int lastPaintRow = convertYToRow((paintBounds.y + paintBounds.height) - 1);
  
            if (firstPaintRow == -1)
                firstPaintRow = 0;

            if (lastPaintRow == -1)
                lastPaintRow = (dataModel.getSize()-1)/columnsPerRow;
           
            if (firstPaintColumn == -1)
                firstPaintColumn = 0;

            if (lastPaintColumn == -1)
                lastPaintColumn = columnsPerRow-1;
  
            Rectangle itemBounds = getCellBoundsPerColumnRow(list, firstPaintColumn, firstPaintRow);
            if (itemBounds == null)
                return;
  
            int leadIndex = list.getLeadSelectionIndex();
            int startItemBoundX = itemBounds.x;
  
            for(int row = firstPaintRow; row <= lastPaintRow; row++) {
                itemBounds.x = startItemBoundX;

                for(int column = firstPaintColumn; column <= lastPaintColumn; column++) {
                    int index = row * columnsPerRow + column;
                    if(index >= dataModel.getSize())
                        break;
                   
                    itemBounds.width  = getItemWidth(index);
                    itemBounds.height = getItemHeight(index);
  
                    // Set the clip rect to be the intersection of rowBounds
                    // and paintBounds and then paint the cell.
                    g.setClip(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height);
                    g.clipRect(paintBounds.x, paintBounds.y, paintBounds.width, paintBounds.height);
                   
                    try {
                        paintCell(g, index, itemBounds, renderer, dataModel, selModel, leadIndex);
                    } catch (Exception exp) {
                        // An exception occured. Probably an incorrect element. Rebuild and retry
                     
                        try {
                          list.setSelectedIndex(index);
                          ((DcListElement) list.getSelectedValue()).update();
                          paintCell(g, index, itemBounds, renderer, dataModel, selModel, leadIndex);
                        } catch (Exception e)  {
                          return;
                        }
                    }
                   
                    itemBounds.x += itemBounds.width;
                }
                itemBounds.y += itemBounds.height;
            }
        } catch (Exception e) {
            logger.error(e, e);
        }
    }


    /**
     * The preferredSize of a list is total height of the rows
     * and the maximum width of the cells.  If JList.fixedCellHeight
     * is specified then the total height of the rows is just
     * (cellVerticalMargins + fixedCellHeight) * model.getSize() where
     * rowVerticalMargins is the space we allocate for drawing
     * the yellow focus outline.  Similarly if JListfixedCellWidth is
     * specified then we just use that plus the horizontal margins.
     *
     * @param c The JList component.
     * @return The total size of the list.
     */
    @Override
    public Dimension getPreferredSize(JComponent c) {
        maybeUpdateLayoutState();

        int lastItem = list.getModel().getSize() - 1;
        if (lastItem < 0)
            return new Dimension(0, 0);

        Insets insets = list.getInsets();

        int width  = convertItemToX(columnsPerRow-1) + getItemWidth(lastItem) + insets.right;
        int height = convertItemToY(lastItem) + getItemHeight(lastItem) + insets.bottom;
        return new Dimension(width, height);
    }

    @Override
    public Dimension getMinimumSize(JComponent c) {
        return getPreferredSize(c);
    }

    @Override
    public Dimension getMaximumSize(JComponent c) {
        return getPreferredSize(c);
    }

    /**
     * Returns a new instance of Basic2DListUI.  Basic2DListUI delegates are
     * allocated one per JList.
     *
     * @return A new ListUI implementation for the Windows look and feel.
     */
    public static ComponentUI createUI(JComponent list) {
        return new DcListUI();
    }

    /**
     * @return The index of the cell at location, or -1.
     * @see ListUI#locationToIndex
     */
    @Override
    public int locationToIndex(JList list, Point location) {
        maybeUpdateLayoutState();
        return convertXYToIndex(location.x, location.y);
    }

    /**
     * @return The origin of the index'th cell, null if index is invalid.
     * @see ListUI#indexToLocation
     */
    @Override
    public Point indexToLocation(JList list, int index) {
        maybeUpdateLayoutState();
        int x = convertItemToX(index);
        int y = convertItemToY(index);
        return ((y == -1) || (x == -1)) ? null : new Point(x, y);
    }

    public int locationToNearestIndex(DcList list, Point p) {
        // Determine the nearest index == center of index that would
        // be the most logical position to insert an item
        int index = locationToIndex(list, p);
        if (index != -1) {
            Rectangle cell = getCellBounds(list, index, index);
            if(cell.getX()+cell.getWidth()/2<p.getX())
                index++;
        } else {
            //It is possible, that we are on some white space on the
            //right of the List check this by calculating the row
            int row = convertYToRow(p.y);
            //The insertion index is the first Item on the next row
            if(row != -1)
                index = (row+1) * columnsPerRow;
        }

        if (index >= list.getModel().getSize())
            index = -1;

        return index;
    }


    public Rectangle getCellBoundsPerColumnRow(JList list, int column, int row) {
        int index = row * columnsPerRow + column;
        return getCellBounds(list, index, index);
    }

    /**
     * @return The bounds of the index'th cell.
     * @see ListUI#getCellBounds
     */
    @Override
    public Rectangle getCellBounds(JList list, int index1, int index2) {
        maybeUpdateLayoutState();


        int minIndex = Math.min(index1, index2);
        int maxIndex = Math.max(index1, index2);
        int minX = convertItemToX(minIndex);
        int maxX = convertItemToX(maxIndex);
        int minY = convertItemToY(minIndex);
        int maxY = convertItemToY(maxIndex);

        if ((minX == -1) || (maxX == -1) || (minY == -1) || (maxY == -1))
            return null;

        int x = minX;
        int y = minY;
        int w = (maxX + getItemWidth(maxIndex)) - minX;
        int h = (maxY + getItemHeight(maxIndex)) - minY;
        return new Rectangle(x, y, w, h);
    }

    @Override
    protected int getRowHeight(int row) {
        return getItemHeight(row);
    }

    protected int getItemHeight(int index) {
        if ((index < 0) || (index >= list.getModel().getSize()))
            return -1;
       
        int row = index/columnsPerRow;
        return (cellHeights == null) ? cellHeight : ((row < cellHeights.length) ? cellHeights[row] : -1);
    }

    protected int getItemWidth(int index) {
        if ((index < 0) || (index >= list.getModel().getSize()))
            return -1;
   
        int column = index%columnsPerRow;
        return (cellWidths == null) ? cellWidth : ((column < cellWidths.length) ? cellWidths[column] : -1);
    }


    protected int convertXYToIndex(int x, int y) {
        int column = convertXToColumn(x);
        int row    = convertYToRow(y);
       
        column = column == -1 ? 0 : column;
        row = row == -1 ? 0 : row;

        int index = row * columnsPerRow + column;
        //Due to independent calculation of column/row
        //the index can be higher as the listSize
        if(index >= list.getModel().getSize())
            return -1;

        return index;
    }

    /**
     * Convert the JList relative coordinate to the row that contains it,
     * based on the current layout.  If y0 doesn't fall within any row,
     * return -1.
     *
     * @return The row that contains y0, or -1.
     * @see #getRowHeight
     * @see #updateLayoutState
     */
    @Override
    protected int convertYToRow(int y0) {
        int nItems = list.getModel().getSize();
        Insets insets = list.getInsets();

        if (nItems <= 0)
            return -1;

        int rowCount = (nItems-1)/columnsPerRow+1;

        if (cellHeights == null) {
            int row = (cellHeight == 0) ? 0 : ((y0 - insets.top) / cellHeight);
            return ((row < 0) || (row >= rowCount)) ? -1 : row;
        } else if (rowCount > cellHeights.length) {
            return -1;
        } else {
            int y = insets.top;
            int row = 0;

            for(int i = 0; i < rowCount; i++) {
                if ((y0 >= y) && (y0 < y + cellHeights[i]))
                    return row;

                y += cellHeights[i];
                row += 1;
            }
           
            return -1;
        }
    }

    protected int convertXToColumn(int x0) {
        int nItems = list.getModel().getSize();
        Insets insets = list.getInsets();

        if (nItems <= 0)
            return -1;

        int columnCount = Math.min(nItems, columnsPerRow);
   
        if (cellWidths == null) {
            int column = (cellWidth == 0) ? 0 : ((x0 - insets.left) / cellWidth);
            return ((column < 0) || (column >= columnCount)) ? -1 : column;
        } else if (columnCount > cellWidths.length) {
            return -1;
        } else {
            int x = insets.left;
            int column = 0;
   
            for(int i = 0; i < columnCount; i++) {
                if ((x0 >= x) && (x0 < x + cellWidths[i]))
                    return column;
           
                x += cellWidths[i];
                column += 1;
            }
            return -1;
        }
    }

    @Override
    protected int convertRowToY(int row) {
        return convertItemToY(row);
    }

    protected int convertItemToY(int index) {
        int nItems = list.getModel().getSize();
        Insets insets = list.getInsets();

        if ((nItems < 0) || (index >= nItems))
            return -1;

        int row = index / columnsPerRow;
   
        if (cellHeights == null) {
            return insets.top + (cellHeight * row);
        } else if (row >= cellHeights.length) {
            return -1;
        } else {
            int y = insets.top;
            for(int i = 0; i < row; i++) {
                y += cellHeights[i];
            }
            return y;
        }
    }

    protected int convertItemToX(int index) {
        int nItems = list.getModel().getSize();
        Insets insets = list.getInsets();
   
        if ((nItems < 0) || (index >= nItems))
            return -1;
   
        int column = index % columnsPerRow;
   
        if (cellWidths == null) {
            return insets.top + (cellWidth * column);
        } else if (column >= cellWidths.length) {
            return -1;
        } else {
            int x = insets.left;
            for(int i = 0; i < column; i++) {
                x += cellWidths[i];
            }
            return x;
        }
    }


    /**
     * Recompute the value of cellHeight or cellHeights based
     * and cellWidth, based on the current font and the current
     * values of fixedCellWidth, fixedCellHeight, and prototypeCellValue.
     *
     * @see #maybeUpdateLayoutState
     */
    @Override
    protected void updateLayoutState() {
        try {
            // If both JList fixedCellWidth and fixedCellHeight have been
            // set, then initialize cellWidth and cellHeight, and set
            // cellHeights to null.
            columnsPerRow = ((DcList) list).getColumnsPerRow();
            int fixedCellHeight = list.getFixedCellHeight();
            int fixedCellWidth  = list.getFixedCellWidth();
            int nItems = list.getModel().getSize();
       
            if (fixedCellWidth != -1) {
                cellWidth = fixedCellWidth;
                cellWidths = null;
            } else {
                cellWidth = -1;
                cellWidths = new int[Math.min(nItems, columnsPerRow)];
            }
       
            if (fixedCellHeight != -1) {
                cellHeight = fixedCellHeight;
                cellHeights = null;
            } else {
                cellHeight = -1;
                cellHeights = new int[(nItems-1)/columnsPerRow+1];
            }
       
            // If either of  JList fixedCellWidth and fixedCellHeight haven't
            // been set, then initialize cellWidth and cellHeights by
            // scanning through the entire model.  Note: if the renderer is
            // null, we just set cellWidth and cellHeights[*] to zero,
            // if they're not set already.
            if ((fixedCellWidth == -1) || (fixedCellHeight == -1)) {
       
                ListModel dataModel = list.getModel();
                int dataModelSize = dataModel.getSize();
                ListCellRenderer renderer = list.getCellRenderer();
       
                if (renderer != null) {
                    for(int index = 0; index < dataModelSize; index++) {
                        Object value = dataModel.getElementAt(index);
                        Component c = renderer.getListCellRendererComponent(list, value, index, false, false);
                        rendererPane.add(c);
                        Dimension cellSize = c.getPreferredSize();
                        int column = index%columnsPerRow;
                        int row    = index/columnsPerRow;
                        if (fixedCellWidth == -1)
                            cellWidths[column] = Math.max(cellWidths[column], cellSize.width);
                       
                        if (fixedCellHeight == -1)
                            cellHeights[row] = Math.max(cellHeights[row], cellSize.height);
                    }
                } else {
                    if (fixedCellWidth == -1) {
                        for(int index = 0; index < cellWidths.length; index++) {
                            cellWidths[index] = 0;
                        }
                    }
                   
                    if (fixedCellHeight == -1) {
                        for(int index = 0; index < cellHeights.length; index++) {
                            cellHeights[index] = 0;
                        }
                    }
                }
            }
       
            list.invalidate();
        } catch (Exception e) {
            //logger.debug("Layout", e);
        }
    }

    protected int getMaxColumnsPerRow(int width) {
        int maxColumns = -1;
       
        try {
            int fixedCellWidth  = list.getFixedCellWidth();
           
            if (fixedCellWidth != -1) {
                maxColumns = width/fixedCellWidth;
            } else {
                ListModel dataModel = list.getModel();
                int nItems = dataModel.getSize();
                ListCellRenderer renderer = list.getCellRenderer();
       
                if (renderer != null) {
                    Dimension[] cellDims = new Dimension[nItems];
                    for(int index = 0; index < nItems; index++) {
                        Object value = dataModel.getElementAt(index);
                        Component c = renderer.getListCellRendererComponent(list, value, index, false, false);
                        rendererPane.add(c);
                        cellDims[index] = c.getPreferredSize();
                    }
   
                    //Reduce until all widhts on all rows fit
                    maxColumns = cellDims.length > 0 ? getMaxItemsBasedOnFirstRow(cellDims, width) : 0;
                    int index = maxColumns;
                    while(index < nItems && maxColumns > 0) {
                        int newColMax = getMaxItemsBasedOnRow(cellDims, width);
                        if(newColMax != -1 && newColMax<maxColumns) {
                            //Increase only one, because width variable fields
                            //we cannot foresee the result if the items are
                            //reordered in the rows
                            maxColumns = maxColumns-1;
                            index = maxColumns;
                        } else {
                            index += maxColumns;
                        }
                    }
                }
           
                maxColumns = maxColumns == 0 ? 1 : maxColumns;
            }
        } catch (Exception exp) {}

        return maxColumns;
    }


    private int getMaxItemsBasedOnFirstRow(Dimension[] dims, int width) {
        return getMaxItemsBasedOnRow(dims, width);
    }


    private int getMaxItemsBasedOnRow(Dimension[] dims, int width) {
        int localWidth = dims[0].width;
        return width / localWidth;
    }

    /**
     * Mouse input, and focus handling for JList.  An instance of this
     * class is added to the appropriate java.awt.Component lists
     * at installUI() time.  Note keyboard input is handled with JComponent
     * KeyboardActions, see installKeyboardActions().
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases.  The current serialization support is appropriate
     * for short term storage or RMI between applications running the same
     * version of Swing.  A future release of Swing will provide support for
     * long term persistence.
     *
     * @see #createMouseInputListener
     * @see #installKeyboardActions
     * @see #installUI
     */
    public class MouseInputHandler implements MouseInputListener {
        private boolean ignoreMouseReleased = false;

        @Override
        public void mouseClicked(MouseEvent e) {}

        @Override
        public void mouseEntered(MouseEvent e) {}

        @Override
        public void mouseExited(MouseEvent e) {}

        @Override
        public void mousePressed(MouseEvent e) {
            ignoreMouseReleased = false;

            if (!SwingUtilities.isLeftMouseButton(e))
                return;

            if (!list.isEnabled())
                return;

            // Request focus before updating the list selection.  This implies
            // that the current focus owner will see a focusLost() event
            // before the lists selection is updated IF requestFocus() is
            // synchronous (it is on Windows).  See bug 4122345
            if (!list.hasFocus())
                list.requestFocus();

            //ACTION TABLE TO SUPPORT DND FOR MULTIPLE INTERVAL SELECTIONS
            //
            //MousePressed:
            //------------------------------------------------------------
            //         |No Selection   |On Selection     |Out Selection
            //------------------------------------------------------------
            //No key   |set[Item]      |No action        |set[item]
            //------------------------------------------------------------
            //Shift    |set[0,item]*   |set[Anchor,item] |set[anchor,item]
            //------------------------------------------------------------
            //Control  |add/set[item]  |remove[item]     |add[item]
            //------------------------------------------------------------
            //* 0 if there hasn't been any selection, otherwise the anchor
            //No Selection/Out Selection appear to have the same behaviour
       
           
            //MouseReleased:
            //------------------------------------------------------------
            //         |No Selection   |On Selection     |Out Selection
            //------------------------------------------------------------
            //No key   |No action      |Set[item]*       |No action
            //------------------------------------------------------------
            //Shift    |No action      |No action        |No action
            //------------------------------------------------------------
            //Control  |No action      |No action        |No action
            //------------------------------------------------------------
            //* unless there has been a drop
            // No Selection/Out Selection appear to have the same behavior
       
            try {
              int index = convertXYToIndex(e.getX(), e.getY());
              if (index != -1) {
                  list.setValueIsAdjusting(true);
                  int anchorIndex = list.getAnchorSelectionIndex();
                  if(anchorIndex == -1) {
                      anchorIndex = 0;
                  }
 
                  if (e.isShiftDown()) {
                      //Regardless set from anchor till index
                      list.setSelectionInterval(anchorIndex, index);
                      //if(Debug.INFO) Debug.out.println("setSelectionInterval("+anchorIndex+", "+index+")");
                  } else if (e.isControlDown()) {
                      //We need to toggle the index
                      if (list.isSelectedIndex(index))
                          list.removeSelectionInterval(index, index);
                      else
                          list.addSelectionInterval(index, index);
                  } else {
                      //Only action if the index is not Selected!
                      if (!list.isSelectedIndex(index))
                          list.setSelectionInterval(index, index);
                  }
              }
            } catch (Exception exp) {
              logger.error(exp, exp);
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {}

        @Override
        public void mouseMoved(MouseEvent e) {}

        @Override
        public void mouseReleased(MouseEvent e) {
            if (!SwingUtilities.isLeftMouseButton(e))
                return;

            list.setValueIsAdjusting(false);
            int index = convertXYToIndex(e.getX(), e.getY());
            if(index != -1) {
                if (!ignoreMouseReleased && !e.isShiftDown() && !e.isControlDown()
                    && list.isSelectedIndex(index)) {
                    //We gave the drag all time, but it didn't
                    //happen, wipe out everything that is selected
                    //and select the current index
                    list.setSelectionInterval(index, index);
                }
            }
        }
    }

    /**
     * Creates a delegate that implements MouseInputListener.
     * The delegate is added to the corresponding java.awt.Component listener
     * lists at installUI() time. Subclasses can override this method to return
     * a custom MouseInputListener, e.g.
     *
     * @see MouseInputHandler
     * @see #installUI
     */
    @Override
     protected MouseInputListener createMouseInputListener() {
         return new MouseInputHandler();
     }

    /**
     * The ListSelectionListener that's added to the JLists selection
     * model at installUI time, and whenever the JList.selectionModel property
     * changes.  When the selection changes we repaint the affected rows.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases.  The current serialization support is appropriate
     * for short term storage or RMI between applications running the same
     * version of Swing.  A future release of Swing will provide support for
     * long term persistence.
     *
     * @see #createListSelectionListener
     * @see #getCellBounds
     * @see #installUI
     */
    public class ListSelectionHandler implements ListSelectionListener {
        @Override
        public void valueChanged(ListSelectionEvent e) {
            maybeUpdateLayoutState();
   
            int first = e.getFirstIndex();
            int last  = e.getLastIndex();
   
            int minX = convertItemToX(first);
            int maxX = convertItemToX(last);
   
            int minY = convertItemToY(first);
            int maxY = convertItemToY(last);
   
            //Determine the clipping area
            if ((minX == -1) || (maxX == -1) || (minY == -1) || (maxY == -1)) {
                list.repaint(0, 0, list.getWidth(), list.getHeight());
            } else {
                maxX += getItemWidth(e.getLastIndex());
                maxY += getItemHeight(e.getLastIndex());
                boolean moreThanOneRow = (first/columnsPerRow) != (last/columnsPerRow);
                if( moreThanOneRow)
                    list.repaint(0, minY, list.getWidth(), maxY - minY);
                else
                    list.repaint(minX, minY, maxX - minX, maxY - minY);
            }
        }
    }


    /**
     * Creates an instance of ListSelectionHandler that's added to
     * the JLists by selectionModel as needed.  Subclasses can override
     * this method to return a custom ListSelectionListener, e.g.
     *
     * @see ListSelectionHandler
     * @see #installUI
     */
    @Override
    protected ListSelectionListener createListSelectionListener() {
        return new ListSelectionHandler();
    }

    private void redrawList() {
        list.repaint();
    }

    /**
     * Creates an instance of ListDataListener that's added to
     * the JLists by model as needed.  Subclasses can override
     * this method to return a custom ListDataListener, e.g.
     *
     * @see ListDataListener
     * @see JList#getModel
     * @see #installUI
     */
    @Override
    protected ListDataListener createListDataListener() {
        return new ListDataHandler();
    }

    /**
     * The PropertyChangeListener that's added to the JList at
     * installUI time.  When the value of a JList property that
     * affects layout changes, we set a bit in updateLayoutStateNeeded.
     * If the JLists model changes we additionally remove our listeners
     * from the old model.  Likewise for the JList selectionModel.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases.  The current serialization support is appropriate
     * for short term storage or RMI between applications running the same
     * version of Swing.  A future release of Swing will provide support for
     * long term persistence.
     *
     * @see #maybeUpdateLayoutState
     * @see #createPropertyChangeListener
     * @see #installUI
     */
    public class PropertyChangeHandler extends BasicListUI.PropertyChangeHandler {
        @Override
        public void propertyChange(PropertyChangeEvent e) {
            super.propertyChange(e);
   
            String propertyName = e.getPropertyName();
   
            // If the JList.model property changes, remove our listener,
            // listDataListener from the old model and add it to the new one.
            if (propertyName.equals("columnsPerRow")) {
                updateLayoutStateNeeded |= columnsPerRowChanged;
                redrawList();
            }
        }
    }


    /**
     * Creates an instance of PropertyChangeHandler that's added to
     * the JList by installUI().  Subclasses can override this method
     * to return a custom PropertyChangeListener, e.g.
     *
     * @see PropertyChangeListener
     * @see #installUI
     */
    @Override
    protected PropertyChangeListener createPropertyChangeListener() {
        return new PropertyChangeHandler();
    }
}
TOP

Related Classes of net.datacrow.console.components.lists.DcListUI$PropertyChangeHandler

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.