|
Java example source code file (BasicListUI.java)
This example Java source code file (BasicListUI.java) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Learn more about this Java project at its project page.
The BasicListUI.java Java example source code
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.plaf.basic;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.text.Position;
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.Transferable;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import sun.swing.SwingUtilities2;
import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag;
/**
* An extensible implementation of {@code ListUI}.
* <p>
* {@code BasicListUI} instances cannot be shared between multiple
* lists.
*
* @author Hans Muller
* @author Philip Milne
* @author Shannon Hickey (drag and drop)
*/
public class BasicListUI extends ListUI
{
private static final StringBuilder BASELINE_COMPONENT_KEY =
new StringBuilder("List.baselineComponent");
protected JList list = null;
protected CellRendererPane rendererPane;
// Listeners that this UI attaches to the JList
protected FocusListener focusListener;
protected MouseInputListener mouseInputListener;
protected ListSelectionListener listSelectionListener;
protected ListDataListener listDataListener;
protected PropertyChangeListener propertyChangeListener;
private Handler handler;
protected int[] cellHeights = null;
protected int cellHeight = -1;
protected int cellWidth = -1;
protected int updateLayoutStateNeeded = modelChanged;
/**
* Height of the list. When asked to paint, if the current size of
* the list differs, this will update the layout state.
*/
private int listHeight;
/**
* Width of the list. When asked to paint, if the current size of
* the list differs, this will update the layout state.
*/
private int listWidth;
/**
* The layout orientation of the list.
*/
private int layoutOrientation;
// Following ivars are used if the list is laying out horizontally
/**
* Number of columns to create.
*/
private int columnCount;
/**
* Preferred height to make the list, this is only used if the
* the list is layed out horizontally.
*/
private int preferredHeight;
/**
* Number of rows per column. This is only used if the row height is
* fixed.
*/
private int rowsPerColumn;
/**
* The time factor to treate the series of typed alphanumeric key
* as prefix for first letter navigation.
*/
private long timeFactor = 1000L;
/**
* Local cache of JList's client property "List.isFileList"
*/
private boolean isFileList = false;
/**
* Local cache of JList's component orientation property
*/
private boolean isLeftToRight = true;
/* The bits below define JList property changes that affect layout.
* When one of these properties changes we set a bit in
* updateLayoutStateNeeded. The change is dealt with lazily, see
* maybeUpdateLayoutState. Changes to the JLists model, e.g. the
* models length changed, are handled similarly, see DataListener.
*/
protected final static int modelChanged = 1 << 0;
protected final static int selectionModelChanged = 1 << 1;
protected final static int fontChanged = 1 << 2;
protected final static int fixedCellWidthChanged = 1 << 3;
protected final static int fixedCellHeightChanged = 1 << 4;
protected final static int prototypeCellValueChanged = 1 << 5;
protected final static int cellRendererChanged = 1 << 6;
private final static int layoutOrientationChanged = 1 << 7;
private final static int heightChanged = 1 << 8;
private final static int widthChanged = 1 << 9;
private final static int componentOrientationChanged = 1 << 10;
private static final int DROP_LINE_THICKNESS = 2;
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.SELECT_PREVIOUS_COLUMN));
map.put(new Actions(Actions.SELECT_PREVIOUS_COLUMN_EXTEND));
map.put(new Actions(Actions.SELECT_PREVIOUS_COLUMN_CHANGE_LEAD));
map.put(new Actions(Actions.SELECT_NEXT_COLUMN));
map.put(new Actions(Actions.SELECT_NEXT_COLUMN_EXTEND));
map.put(new Actions(Actions.SELECT_NEXT_COLUMN_CHANGE_LEAD));
map.put(new Actions(Actions.SELECT_PREVIOUS_ROW));
map.put(new Actions(Actions.SELECT_PREVIOUS_ROW_EXTEND));
map.put(new Actions(Actions.SELECT_PREVIOUS_ROW_CHANGE_LEAD));
map.put(new Actions(Actions.SELECT_NEXT_ROW));
map.put(new Actions(Actions.SELECT_NEXT_ROW_EXTEND));
map.put(new Actions(Actions.SELECT_NEXT_ROW_CHANGE_LEAD));
map.put(new Actions(Actions.SELECT_FIRST_ROW));
map.put(new Actions(Actions.SELECT_FIRST_ROW_EXTEND));
map.put(new Actions(Actions.SELECT_FIRST_ROW_CHANGE_LEAD));
map.put(new Actions(Actions.SELECT_LAST_ROW));
map.put(new Actions(Actions.SELECT_LAST_ROW_EXTEND));
map.put(new Actions(Actions.SELECT_LAST_ROW_CHANGE_LEAD));
map.put(new Actions(Actions.SCROLL_UP));
map.put(new Actions(Actions.SCROLL_UP_EXTEND));
map.put(new Actions(Actions.SCROLL_UP_CHANGE_LEAD));
map.put(new Actions(Actions.SCROLL_DOWN));
map.put(new Actions(Actions.SCROLL_DOWN_EXTEND));
map.put(new Actions(Actions.SCROLL_DOWN_CHANGE_LEAD));
map.put(new Actions(Actions.SELECT_ALL));
map.put(new Actions(Actions.CLEAR_SELECTION));
map.put(new Actions(Actions.ADD_TO_SELECTION));
map.put(new Actions(Actions.TOGGLE_AND_ANCHOR));
map.put(new Actions(Actions.EXTEND_TO));
map.put(new Actions(Actions.MOVE_SELECTION_TO));
map.put(TransferHandler.getCutAction().getValue(Action.NAME),
TransferHandler.getCutAction());
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
map.put(TransferHandler.getPasteAction().getValue(Action.NAME),
TransferHandler.getPasteAction());
}
/**
* Paint one List cell: compute the relevant state, get the "rubber stamp"
* cell renderer component, and then use the CellRendererPane to paint it.
* Subclasses may want to override this method rather than paint().
*
* @see #paint
*/
protected void paintCell(
Graphics g,
int row,
Rectangle rowBounds,
ListCellRenderer cellRenderer,
ListModel dataModel,
ListSelectionModel selModel,
int leadIndex)
{
Object value = dataModel.getElementAt(row);
boolean cellHasFocus = list.hasFocus() && (row == leadIndex);
boolean isSelected = selModel.isSelectedIndex(row);
Component rendererComponent =
cellRenderer.getListCellRendererComponent(list, value, row, isSelected, cellHasFocus);
int cx = rowBounds.x;
int cy = rowBounds.y;
int cw = rowBounds.width;
int ch = rowBounds.height;
if (isFileList) {
// Shrink renderer to preferred size. This is mostly used on Windows
// where selection is only shown around the file name, instead of
// across the whole list cell.
int w = Math.min(cw, rendererComponent.getPreferredSize().width + 4);
if (!isLeftToRight) {
cx += (cw - w);
}
cw = w;
}
rendererPane.paintComponent(g, rendererComponent, list, cx, cy, cw, ch, true);
}
/**
* Paint the rows that intersect the Graphics objects clipRect. This
* method calls paintCell as necessary. Subclasses
* may want to override these methods.
*
* @see #paintCell
*/
public void paint(Graphics g, JComponent c) {
Shape clip = g.getClip();
paintImpl(g, c);
g.setClip(clip);
paintDropLine(g);
}
private void paintImpl(Graphics g, JComponent c)
{
switch (layoutOrientation) {
case JList.VERTICAL_WRAP:
if (list.getHeight() != listHeight) {
updateLayoutStateNeeded |= heightChanged;
redrawList();
}
break;
case JList.HORIZONTAL_WRAP:
if (list.getWidth() != listWidth) {
updateLayoutStateNeeded |= widthChanged;
redrawList();
}
break;
default:
break;
}
maybeUpdateLayoutState();
ListCellRenderer renderer = list.getCellRenderer();
ListModel dataModel = list.getModel();
ListSelectionModel selModel = list.getSelectionModel();
int size;
if ((renderer == null) || (size = dataModel.getSize()) == 0) {
return;
}
// Determine how many columns we need to paint
Rectangle paintBounds = g.getClipBounds();
int startColumn, endColumn;
if (c.getComponentOrientation().isLeftToRight()) {
startColumn = convertLocationToColumn(paintBounds.x,
paintBounds.y);
endColumn = convertLocationToColumn(paintBounds.x +
paintBounds.width,
paintBounds.y);
} else {
startColumn = convertLocationToColumn(paintBounds.x +
paintBounds.width,
paintBounds.y);
endColumn = convertLocationToColumn(paintBounds.x,
paintBounds.y);
}
int maxY = paintBounds.y + paintBounds.height;
int leadIndex = adjustIndex(list.getLeadSelectionIndex(), list);
int rowIncrement = (layoutOrientation == JList.HORIZONTAL_WRAP) ?
columnCount : 1;
for (int colCounter = startColumn; colCounter <= endColumn;
colCounter++) {
// And then how many rows in this columnn
int row = convertLocationToRowInColumn(paintBounds.y, colCounter);
int rowCount = getRowCount(colCounter);
int index = getModelIndex(colCounter, row);
Rectangle rowBounds = getCellBounds(list, index, index);
if (rowBounds == null) {
// Not valid, bail!
return;
}
while (row < rowCount && rowBounds.y < maxY &&
index < size) {
rowBounds.height = getHeight(colCounter, row);
g.setClip(rowBounds.x, rowBounds.y, rowBounds.width,
rowBounds.height);
g.clipRect(paintBounds.x, paintBounds.y, paintBounds.width,
paintBounds.height);
paintCell(g, index, rowBounds, renderer, dataModel, selModel,
leadIndex);
rowBounds.y += rowBounds.height;
index += rowIncrement;
row++;
}
}
// Empty out the renderer pane, allowing renderers to be gc'ed.
rendererPane.removeAll();
}
private void paintDropLine(Graphics g) {
JList.DropLocation loc = list.getDropLocation();
if (loc == null || !loc.isInsert()) {
return;
}
Color c = DefaultLookup.getColor(list, this, "List.dropLineColor", null);
if (c != null) {
g.setColor(c);
Rectangle rect = getDropLineRect(loc);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
}
private Rectangle getDropLineRect(JList.DropLocation loc) {
int size = list.getModel().getSize();
if (size == 0) {
Insets insets = list.getInsets();
if (layoutOrientation == JList.HORIZONTAL_WRAP) {
if (isLeftToRight) {
return new Rectangle(insets.left, insets.top, DROP_LINE_THICKNESS, 20);
} else {
return new Rectangle(list.getWidth() - DROP_LINE_THICKNESS - insets.right,
insets.top, DROP_LINE_THICKNESS, 20);
}
} else {
return new Rectangle(insets.left, insets.top,
list.getWidth() - insets.left - insets.right,
DROP_LINE_THICKNESS);
}
}
Rectangle rect = null;
int index = loc.getIndex();
boolean decr = false;
if (layoutOrientation == JList.HORIZONTAL_WRAP) {
if (index == size) {
decr = true;
} else if (index != 0 && convertModelToRow(index)
!= convertModelToRow(index - 1)) {
Rectangle prev = getCellBounds(list, index - 1);
Rectangle me = getCellBounds(list, index);
Point p = loc.getDropPoint();
if (isLeftToRight) {
decr = Point2D.distance(prev.x + prev.width,
prev.y + (int)(prev.height / 2.0),
p.x, p.y)
< Point2D.distance(me.x,
me.y + (int)(me.height / 2.0),
p.x, p.y);
} else {
decr = Point2D.distance(prev.x,
prev.y + (int)(prev.height / 2.0),
p.x, p.y)
< Point2D.distance(me.x + me.width,
me.y + (int)(prev.height / 2.0),
p.x, p.y);
}
}
if (decr) {
index--;
rect = getCellBounds(list, index);
if (isLeftToRight) {
rect.x += rect.width;
} else {
rect.x -= DROP_LINE_THICKNESS;
}
} else {
rect = getCellBounds(list, index);
if (!isLeftToRight) {
rect.x += rect.width - DROP_LINE_THICKNESS;
}
}
if (rect.x >= list.getWidth()) {
rect.x = list.getWidth() - DROP_LINE_THICKNESS;
} else if (rect.x < 0) {
rect.x = 0;
}
rect.width = DROP_LINE_THICKNESS;
} else if (layoutOrientation == JList.VERTICAL_WRAP) {
if (index == size) {
index--;
rect = getCellBounds(list, index);
rect.y += rect.height;
} else if (index != 0 && convertModelToColumn(index)
!= convertModelToColumn(index - 1)) {
Rectangle prev = getCellBounds(list, index - 1);
Rectangle me = getCellBounds(list, index);
Point p = loc.getDropPoint();
if (Point2D.distance(prev.x + (int)(prev.width / 2.0),
prev.y + prev.height,
p.x, p.y)
< Point2D.distance(me.x + (int)(me.width / 2.0),
me.y,
p.x, p.y)) {
index--;
rect = getCellBounds(list, index);
rect.y += rect.height;
} else {
rect = getCellBounds(list, index);
}
} else {
rect = getCellBounds(list, index);
}
if (rect.y >= list.getHeight()) {
rect.y = list.getHeight() - DROP_LINE_THICKNESS;
}
rect.height = DROP_LINE_THICKNESS;
} else {
if (index == size) {
index--;
rect = getCellBounds(list, index);
rect.y += rect.height;
} else {
rect = getCellBounds(list, index);
}
if (rect.y >= list.getHeight()) {
rect.y = list.getHeight() - DROP_LINE_THICKNESS;
}
rect.height = DROP_LINE_THICKNESS;
}
return rect;
}
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
int rowHeight = list.getFixedCellHeight();
UIDefaults lafDefaults = UIManager.getLookAndFeelDefaults();
Component renderer = (Component)lafDefaults.get(
BASELINE_COMPONENT_KEY);
if (renderer == null) {
ListCellRenderer lcr = (ListCellRenderer)UIManager.get(
"List.cellRenderer");
// fix for 6711072 some LAFs like Nimbus do not provide this
// UIManager key and we should not through a NPE here because of it
if (lcr == null) {
lcr = new DefaultListCellRenderer();
}
renderer = lcr.getListCellRendererComponent(
list, "a", -1, false, false);
lafDefaults.put(BASELINE_COMPONENT_KEY, renderer);
}
renderer.setFont(list.getFont());
// JList actually has much more complex behavior here.
// If rowHeight != -1 the rowHeight is either the max of all cell
// heights (layout orientation != VERTICAL), or is variable depending
// upon the cell. We assume a default size.
// We could theoretically query the real renderer, but that would
// not work for an empty model and the results may vary with
// the content.
if (rowHeight == -1) {
rowHeight = renderer.getPreferredSize().height;
}
return renderer.getBaseline(Integer.MAX_VALUE, rowHeight) +
list.getInsets().top;
}
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
/**
* The preferredSize of the list depends upon the layout orientation.
* <table summary="Describes the preferred size for each layout orientation">
* <tr>Layout Orientation | Preferred Size | |
* <tr>
* <td>JList.VERTICAL
* <td>The preferredSize of the 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 fixedCellWidth is
* specified then we just use that.
* </td>
* <tr>
* <td>JList.VERTICAL_WRAP
* <td>If the visible row count is greater than zero, the preferredHeight
* is the maximum cell height * visibleRowCount. If the visible row
* count is <= 0, the preferred height is either the current height
* of the list, or the maximum cell height, whichever is
* bigger. The preferred width is than the maximum cell width *
* number of columns needed. Where the number of columns needs is
* list.height / max cell height. Max cell height is either the fixed
* cell height, or is determined by iterating through all the cells
* to find the maximum height from the ListCellRenderer.
* <tr>
* <td>JList.HORIZONTAL_WRAP
* <td>If the visible row count is greater than zero, the preferredHeight
* is the maximum cell height * adjustedRowCount. Where
* visibleRowCount is used to determine the number of columns.
* Because this lays out horizontally the number of rows is
* then determined from the column count. For example, lets say
* you have a model with 10 items and the visible row count is 8.
* The number of columns needed to display this is 2, but you no
* longer need 8 rows to display this, you only need 5, thus
* the adjustedRowCount is 5.
* <p>If the visible row
* count is <= 0, the preferred height is dictated by the
* number of columns, which will be as many as can fit in the width
* of the <code>JList (width / max cell width), with at
* least one column. The preferred height then becomes the
* model size / number of columns * maximum cell height.
* Max cell height is either the fixed
* cell height, or is determined by iterating through all the cells
* to find the maximum height from the ListCellRenderer.
* </table>
* The above specifies the raw preferred width and height. The resulting
* preferred width is the above width + insets.left + insets.right and
* the resulting preferred height is the above height + insets.top +
* insets.bottom. Where the <code>Insets are determined from
* <code>list.getInsets().
*
* @param c The JList component.
* @return The total size of the list.
*/
public Dimension getPreferredSize(JComponent c) {
maybeUpdateLayoutState();
int lastRow = list.getModel().getSize() - 1;
if (lastRow < 0) {
return new Dimension(0, 0);
}
Insets insets = list.getInsets();
int width = cellWidth * columnCount + insets.left + insets.right;
int height;
if (layoutOrientation != JList.VERTICAL) {
height = preferredHeight;
}
else {
Rectangle bounds = getCellBounds(list, lastRow);
if (bounds != null) {
height = bounds.y + bounds.height + insets.bottom;
}
else {
height = 0;
}
}
return new Dimension(width, height);
}
/**
* Selected the previous row and force it to be visible.
*
* @see JList#ensureIndexIsVisible
*/
protected void selectPreviousIndex() {
int s = list.getSelectedIndex();
if(s > 0) {
s -= 1;
list.setSelectedIndex(s);
list.ensureIndexIsVisible(s);
}
}
/**
* Selected the previous row and force it to be visible.
*
* @see JList#ensureIndexIsVisible
*/
protected void selectNextIndex()
{
int s = list.getSelectedIndex();
if((s + 1) < list.getModel().getSize()) {
s += 1;
list.setSelectedIndex(s);
list.ensureIndexIsVisible(s);
}
}
/**
* Registers the keyboard bindings on the <code>JList that the
* <code>BasicListUI is associated with. This method is called at
* installUI() time.
*
* @see #installUI
*/
protected void installKeyboardActions() {
InputMap inputMap = getInputMap(JComponent.WHEN_FOCUSED);
SwingUtilities.replaceUIInputMap(list, JComponent.WHEN_FOCUSED,
inputMap);
LazyActionMap.installLazyActionMap(list, BasicListUI.class,
"List.actionMap");
}
InputMap getInputMap(int condition) {
if (condition == JComponent.WHEN_FOCUSED) {
InputMap keyMap = (InputMap)DefaultLookup.get(
list, this, "List.focusInputMap");
InputMap rtlKeyMap;
if (isLeftToRight ||
((rtlKeyMap = (InputMap)DefaultLookup.get(list, this,
"List.focusInputMap.RightToLeft")) == null)) {
return keyMap;
} else {
rtlKeyMap.setParent(keyMap);
return rtlKeyMap;
}
}
return null;
}
/**
* Unregisters keyboard actions installed from
* <code>installKeyboardActions.
* This method is called at uninstallUI() time - subclassess should
* ensure that all of the keyboard actions registered at installUI
* time are removed here.
*
* @see #installUI
*/
protected void uninstallKeyboardActions() {
SwingUtilities.replaceUIActionMap(list, null);
SwingUtilities.replaceUIInputMap(list, JComponent.WHEN_FOCUSED, null);
}
/**
* Creates and installs the listeners for the JList, its model, and its
* selectionModel. This method is called at installUI() time.
*
* @see #installUI
* @see #uninstallListeners
*/
protected void installListeners()
{
TransferHandler th = list.getTransferHandler();
if (th == null || th instanceof UIResource) {
list.setTransferHandler(defaultTransferHandler);
// default TransferHandler doesn't support drop
// so we don't want drop handling
if (list.getDropTarget() instanceof UIResource) {
list.setDropTarget(null);
}
}
focusListener = createFocusListener();
mouseInputListener = createMouseInputListener();
propertyChangeListener = createPropertyChangeListener();
listSelectionListener = createListSelectionListener();
listDataListener = createListDataListener();
list.addFocusListener(focusListener);
list.addMouseListener(mouseInputListener);
list.addMouseMotionListener(mouseInputListener);
list.addPropertyChangeListener(propertyChangeListener);
list.addKeyListener(getHandler());
ListModel model = list.getModel();
if (model != null) {
model.addListDataListener(listDataListener);
}
ListSelectionModel selectionModel = list.getSelectionModel();
if (selectionModel != null) {
selectionModel.addListSelectionListener(listSelectionListener);
}
}
/**
* Removes the listeners from the JList, its model, and its
* selectionModel. All of the listener fields, are reset to
* null here. This method is called at uninstallUI() time,
* it should be kept in sync with installListeners.
*
* @see #uninstallUI
* @see #installListeners
*/
protected void uninstallListeners()
{
list.removeFocusListener(focusListener);
list.removeMouseListener(mouseInputListener);
list.removeMouseMotionListener(mouseInputListener);
list.removePropertyChangeListener(propertyChangeListener);
list.removeKeyListener(getHandler());
ListModel model = list.getModel();
if (model != null) {
model.removeListDataListener(listDataListener);
}
ListSelectionModel selectionModel = list.getSelectionModel();
if (selectionModel != null) {
selectionModel.removeListSelectionListener(listSelectionListener);
}
focusListener = null;
mouseInputListener = null;
listSelectionListener = null;
listDataListener = null;
propertyChangeListener = null;
handler = null;
}
/**
* Initializes list properties such as font, foreground, and background,
* and adds the CellRendererPane. The font, foreground, and background
* properties are only set if their current value is either null
* or a UIResource, other properties are set if the current
* value is null.
*
* @see #uninstallDefaults
* @see #installUI
* @see CellRendererPane
*/
protected void installDefaults()
{
list.setLayout(null);
LookAndFeel.installBorder(list, "List.border");
LookAndFeel.installColorsAndFont(list, "List.background", "List.foreground", "List.font");
LookAndFeel.installProperty(list, "opaque", Boolean.TRUE);
if (list.getCellRenderer() == null) {
list.setCellRenderer((ListCellRenderer)(UIManager.get("List.cellRenderer")));
}
Color sbg = list.getSelectionBackground();
if (sbg == null || sbg instanceof UIResource) {
list.setSelectionBackground(UIManager.getColor("List.selectionBackground"));
}
Color sfg = list.getSelectionForeground();
if (sfg == null || sfg instanceof UIResource) {
list.setSelectionForeground(UIManager.getColor("List.selectionForeground"));
}
Long l = (Long)UIManager.get("List.timeFactor");
timeFactor = (l!=null) ? l.longValue() : 1000L;
updateIsFileList();
}
private void updateIsFileList() {
boolean b = Boolean.TRUE.equals(list.getClientProperty("List.isFileList"));
if (b != isFileList) {
isFileList = b;
Font oldFont = list.getFont();
if (oldFont == null || oldFont instanceof UIResource) {
Font newFont = UIManager.getFont(b ? "FileChooser.listFont" : "List.font");
if (newFont != null && newFont != oldFont) {
list.setFont(newFont);
}
}
}
}
/**
* Sets the list properties that have not been explicitly overridden to
* {@code null}. A property is considered overridden if its current value
* is not a {@code UIResource}.
*
* @see #installDefaults
* @see #uninstallUI
* @see CellRendererPane
*/
protected void uninstallDefaults()
{
LookAndFeel.uninstallBorder(list);
if (list.getFont() instanceof UIResource) {
list.setFont(null);
}
if (list.getForeground() instanceof UIResource) {
list.setForeground(null);
}
if (list.getBackground() instanceof UIResource) {
list.setBackground(null);
}
if (list.getSelectionBackground() instanceof UIResource) {
list.setSelectionBackground(null);
}
if (list.getSelectionForeground() instanceof UIResource) {
list.setSelectionForeground(null);
}
if (list.getCellRenderer() instanceof UIResource) {
list.setCellRenderer(null);
}
if (list.getTransferHandler() instanceof UIResource) {
list.setTransferHandler(null);
}
}
/**
* Initializes <code>this.list by calling