0N/A/*
6441N/A * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A
0N/A// Very much based on XListPeer from javaos
0N/A
0N/Apackage sun.awt.X11;
0N/A
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.awt.peer.*;
0N/Aimport java.util.Vector;
0N/Aimport java.awt.geom.*;
0N/Aimport java.awt.image.*;
1696N/Aimport sun.util.logging.PlatformLogger;
0N/A
0N/A// TODO: some input actions should do nothing if Shift or Control are down
0N/A
0N/Aclass XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient {
0N/A
1696N/A private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XListPeer");
0N/A
0N/A public final static int MARGIN = 2;
0N/A public final static int SPACE = 1;
0N/A public final static int SCROLLBAR_AREA = 17; // Area reserved for the
0N/A // scrollbar
0N/A public final static int SCROLLBAR_WIDTH = 13; // Actual width of the
0N/A // scrollbar
0N/A public final static int NONE = -1;
0N/A public final static int WINDOW = 0;
0N/A public final static int VERSCROLLBAR = 1;
0N/A public final static int HORSCROLLBAR = 2;
0N/A public final static int DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,
0N/A public final static int HORIZ_SCROLL_AMT = 10;
0N/A
222N/A private final static int PAINT_VSCROLL = 2;
222N/A private final static int PAINT_HSCROLL = 4;
222N/A private final static int PAINT_ITEMS = 8;
222N/A private final static int PAINT_FOCUS = 16;
222N/A private final static int PAINT_BACKGROUND = 32;
222N/A private final static int PAINT_HIDEFOCUS = 64;
222N/A private final static int PAINT_ALL =
222N/A PAINT_VSCROLL | PAINT_HSCROLL | PAINT_ITEMS | PAINT_FOCUS | PAINT_BACKGROUND;
222N/A private final static int COPY_AREA = 128;
0N/A
0N/A XVerticalScrollbar vsb;
0N/A XHorizontalScrollbar hsb;
0N/A ListPainter painter;
0N/A
0N/A // TODO: ick - Vector?
0N/A Vector items;
0N/A boolean multipleSelections;
0N/A int active = NONE;
0N/A
0N/A // Holds the array of the indexes of the elements which is selected
0N/A // This array should be kept sorted, low to high.
0N/A int selected[];
0N/A int fontHeight;
0N/A int fontAscent;
0N/A int fontLeading;
0N/A
0N/A // Holds the index of the item used in the previous operation (selectItem, deselectItem)
0N/A // Adding of an item or clearing of the list sets this index to -1
0N/A // The index is used at the moment of the post of ACTION_PERFORMED event after the mouse double click event.
0N/A int currentIndex = -1;
0N/A
0N/A // Used for tracking selection/deselection between mousePress/Release
0N/A // and for ItemEvents
0N/A int eventIndex = -1;
0N/A int eventType = NONE;
0N/A
0N/A // Holds the index of the item that receive focus
0N/A // This variable is reasonable only for multiple list
0N/A // since 'focusIndex' and 'selected[0]' are equal for single-selection list
0N/A int focusIndex;
0N/A
0N/A int maxLength;
0N/A boolean vsbVis; // visibility of scrollbars
0N/A boolean hsbVis;
0N/A int listWidth; // Width of list portion of List
0N/A int listHeight; // Height of list portion of List
0N/A // (i.e. without scrollbars)
0N/A
0N/A private int firstTimeVisibleIndex = 0;
0N/A
0N/A // Motif Lists don't seem to inherit the background color from their
0N/A // parent when an app is first started up. So, we track if the colors have
0N/A // been set. See getListBackground()/getListForeground().
0N/A boolean bgColorSet;
0N/A boolean fgColorSet;
0N/A
0N/A // Holds the true if mouse is dragging outside of the area of the list
0N/A // The flag is used at the moment of the dragging and releasing mouse
0N/A // See 6243382 for more information
0N/A boolean mouseDraggedOutHorizontally = false;
0N/A boolean mouseDraggedOutVertically = false;
0N/A
0N/A // Holds the true if a mouse event was originated on the scrollbar
0N/A // See 6300527 for more information
0N/A boolean isScrollBarOriginated = false;
0N/A
0N/A // This variable is set to true after the "mouse pressed" event and to false after the "mouse released" event
0N/A // Fixed 6293432: Key events ('SPACE', 'UP', 'DOWN') aren't blocked if mouse is kept in 'PRESSED' state for List, XAWT
0N/A boolean isMousePressed = false;
0N/A
0N/A /**
0N/A * Create a list
0N/A */
0N/A XListPeer(List target) {
0N/A super(target);
0N/A }
0N/A
0N/A /**
0N/A * Overridden from XWindow
0N/A */
0N/A public void preInit(XCreateWindowParams params) {
0N/A super.preInit(params);
0N/A
0N/A // Stuff that must be initialized before layout() is called
0N/A items = new Vector();
0N/A createVerScrollbar();
0N/A createHorScrollbar();
0N/A
0N/A painter = new ListPainter();
0N/A
0N/A // See 6246467 for more information
0N/A bgColorSet = target.isBackgroundSet();
0N/A fgColorSet = target.isForegroundSet();
0N/A }
0N/A
0N/A public void postInit(XCreateWindowParams params) {
0N/A super.postInit(params);
0N/A initFontMetrics();
0N/A // TODO: more efficient way?
0N/A // do we really want/need a copy of all the items?
0N/A // get all items from target
0N/A List l = (List)target;
0N/A int stop = l.getItemCount();
0N/A for (int i = 0 ; i < stop; i++) {
0N/A items.addElement(l.getItem(i));
0N/A }
0N/A
0N/A /* make the visible position visible. */
0N/A int index = l.getVisibleIndex();
0N/A if (index >= 0) {
0N/A // Can't call makeVisible since it check scroll bar,
0N/A // initialize scroll bar instead
0N/A vsb.setValues(index, 0, 0, items.size());
0N/A }
0N/A
0N/A // NOTE: needs to have target set
0N/A maxLength = maxLength();
0N/A
0N/A // get the index containing all indexes to selected items
0N/A int sel[] = l.getSelectedIndexes();
0N/A selected = new int[sel.length];
0N/A // TODO: shouldn't this be arraycopy()?
0N/A for (int i = 0 ; i < sel.length ; i ++) {
0N/A selected[i] = sel[i];
0N/A }
0N/A // The select()ed item should become the focused item, but we don't
0N/A // get the select() call because the peer generally hasn't yet been
0N/A // created during app initialization.
0N/A // TODO: For multi-select lists, it should be the highest selected index
0N/A if (sel.length > 0) {
0N/A setFocusIndex(sel[sel.length - 1]);
0N/A }
0N/A else {
0N/A setFocusIndex(0);
0N/A }
0N/A
0N/A multipleSelections = l.isMultipleMode();
0N/A }
0N/A
0N/A
0N/A /**
0N/A * add Vertical Scrollbar
0N/A */
0N/A void createVerScrollbar() {
0N/A vsb = new XVerticalScrollbar(this);
0N/A vsb.setValues(0, 0, 0, 0, 1, 1);
0N/A }
0N/A
0N/A
0N/A /**
0N/A * add Horizontal scrollbar
0N/A */
0N/A void createHorScrollbar() {
0N/A hsb = new XHorizontalScrollbar(this);
0N/A hsb.setValues(0, 0, 0, 0, HORIZ_SCROLL_AMT, HORIZ_SCROLL_AMT);
0N/A }
0N/A
0N/A /* New method name for 1.1 */
0N/A public void add(String item, int index) {
0N/A addItem(item, index);
0N/A }
0N/A
0N/A /* New method name for 1.1 */
0N/A public void removeAll() {
0N/A clear();
0N/A maxLength = 0;
0N/A }
0N/A
0N/A /* New method name for 1.1 */
0N/A public void setMultipleMode (boolean b) {
0N/A setMultipleSelections(b);
0N/A }
0N/A
0N/A /* New method name for 1.1 */
0N/A public Dimension getPreferredSize(int rows) {
0N/A return preferredSize(rows);
0N/A }
0N/A
0N/A /* New method name for 1.1 */
0N/A public Dimension getMinimumSize(int rows) {
0N/A return minimumSize(rows);
0N/A }
0N/A
0N/A /**
0N/A * Minimum size.
0N/A */
0N/A public Dimension minimumSize() {
0N/A return minimumSize(DEFAULT_VISIBLE_ROWS);
0N/A }
0N/A
0N/A /**
0N/A * return the preferredSize
0N/A */
0N/A public Dimension preferredSize(int v) {
0N/A return minimumSize(v);
0N/A }
0N/A
0N/A /**
0N/A * return the minimumsize
0N/A */
0N/A public Dimension minimumSize(int v) {
0N/A FontMetrics fm = getFontMetrics(getFont());
0N/A initFontMetrics();
0N/A return new Dimension(20 + fm.stringWidth("0123456789abcde"),
0N/A getItemHeight() * v + (2*MARGIN));
0N/A }
0N/A
0N/A /**
0N/A * Calculate font metrics
0N/A */
0N/A void initFontMetrics() {
0N/A FontMetrics fm = getFontMetrics(getFont());
0N/A fontHeight = fm.getHeight();
0N/A fontAscent = fm.getAscent();
0N/A fontLeading = fm.getLeading();
0N/A }
0N/A
0N/A
0N/A /**
0N/A * return the length of the largest item in the list
0N/A */
0N/A int maxLength() {
0N/A FontMetrics fm = getFontMetrics(getFont());
0N/A int m = 0;
0N/A int end = items.size();
0N/A for(int i = 0 ; i < end ; i++) {
0N/A int l = fm.stringWidth(((String)items.elementAt(i)));
0N/A m = Math.max(m, l);
0N/A }
0N/A return m;
0N/A }
0N/A
0N/A /**
0N/A * Calculates the width of item's label
0N/A */
0N/A int getItemWidth(int i) {
0N/A FontMetrics fm = getFontMetrics(getFont());
0N/A return fm.stringWidth((String)items.elementAt(i));
0N/A }
0N/A
0N/A /**
0N/A * return the on-screen width of the given string "str"
0N/A */
0N/A int stringLength(String str) {
0N/A FontMetrics fm = getFontMetrics(target.getFont());
0N/A return fm.stringWidth(str);
0N/A }
0N/A
0N/A public void setForeground(Color c) {
0N/A fgColorSet = true;
0N/A super.setForeground(c);
0N/A }
0N/A
0N/A public void setBackground(Color c) {
0N/A bgColorSet = true;
0N/A super.setBackground(c);
0N/A }
0N/A
0N/A /**
0N/A * Returns the color that should be used to paint the background of
0N/A * the list of items. Note that this is not the same as
0N/A * target.getBackground() which is the color of the scrollbars, and the
0N/A * lower-right corner of the Component when the scrollbars are displayed.
0N/A */
0N/A private Color getListBackground(Color[] colors) {
0N/A if (bgColorSet) {
0N/A return colors[BACKGROUND_COLOR];
0N/A }
0N/A else {
0N/A return SystemColor.text;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the color that should be used to paint the list item text.
0N/A */
0N/A private Color getListForeground(Color[] colors) {
0N/A if (fgColorSet) {
0N/A return colors[FOREGROUND_COLOR];
0N/A }
0N/A else {
0N/A return SystemColor.textText;
0N/A }
0N/A }
0N/A
0N/A Rectangle getVScrollBarRec() {
0N/A return new Rectangle(width - (SCROLLBAR_WIDTH), 0, SCROLLBAR_WIDTH+1, height);
0N/A }
0N/A
0N/A Rectangle getHScrollBarRec() {
0N/A return new Rectangle(0, height - SCROLLBAR_WIDTH, width, SCROLLBAR_WIDTH);
0N/A }
0N/A
0N/A int getFirstVisibleItem() {
0N/A if (vsbVis) {
0N/A return vsb.getValue();
0N/A } else {
0N/A return 0;
0N/A }
0N/A }
0N/A
0N/A int getLastVisibleItem() {
0N/A if (vsbVis) {
0N/A return Math.min(items.size()-1, vsb.getValue() + itemsInWindow() -1);
0N/A } else {
0N/A return Math.min(items.size()-1, itemsInWindow()-1);
0N/A }
0N/A }
0N/A
0N/A public void repaintScrollbarRequest(XScrollbar scrollbar) {
0N/A Graphics g = getGraphics();
0N/A if (scrollbar == hsb) {
0N/A repaint(PAINT_HSCROLL);
0N/A }
0N/A else if (scrollbar == vsb) {
0N/A repaint(PAINT_VSCROLL);
0N/A }
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Overridden for performance
0N/A */
0N/A public void repaint() {
0N/A repaint(getFirstVisibleItem(), getLastVisibleItem(), PAINT_ALL);
0N/A }
0N/A
222N/A private void repaint(int options) {
0N/A repaint(getFirstVisibleItem(), getLastVisibleItem(), options);
0N/A }
0N/A
222N/A private void repaint(int firstItem, int lastItem, int options) {
222N/A repaint(firstItem, lastItem, options, null, null);
222N/A }
222N/A
222N/A /**
222N/A * In most cases the entire area of the component doesn't have
222N/A * to be repainted. The method repaints the particular areas of
222N/A * the component. The areas to repaint is specified by the option
222N/A * parameter. The possible values of the option parameter are:
222N/A * PAINT_VSCROLL, PAINT_HSCROLL, PAINT_ITEMS, PAINT_FOCUS,
222N/A * PAINT_HIDEFOCUS, PAINT_BACKGROUND, PAINT_ALL, COPY_AREA.
222N/A *
222N/A * Note that the COPY_AREA value initiates copy of a source area
222N/A * of the component by a distance by means of the copyArea method
222N/A * of the Graphics class.
222N/A *
222N/A * @param firstItem the position of the first item of the range to repaint
222N/A * @param lastItem the position of the last item of the range to repaint
222N/A * @param options specifies the particular area of the component to repaint
222N/A * @param source the area of the component to copy
222N/A * @param distance the distance to copy the source area
222N/A */
222N/A private void repaint(int firstItem, int lastItem, int options, Rectangle source, Point distance) {
0N/A Graphics g = getGraphics();
0N/A try {
222N/A painter.paint(g, firstItem, lastItem, options, source, distance);
0N/A } finally {
0N/A g.dispose();
0N/A }
0N/A }
0N/A
0N/A public void paint(Graphics g) {
0N/A painter.paint(g, getFirstVisibleItem(), getLastVisibleItem(), PAINT_ALL);
0N/A }
0N/A
0N/A public boolean isFocusable() { return true; }
0N/A
0N/A // TODO: share/promote the Focus methods?
0N/A public void focusGained(FocusEvent e) {
0N/A super.focusGained(e);
0N/A repaint(PAINT_FOCUS);
0N/A }
0N/A
0N/A public void focusLost(FocusEvent e) {
0N/A super.focusLost(e);
0N/A repaint(PAINT_FOCUS);
0N/A }
0N/A
0N/A /**
0N/A * Layout the sub-components of the List - that is, the scrollbars and the
0N/A * list of items.
0N/A */
0N/A public void layout() {
0N/A int vis, maximum;
0N/A boolean vsbWasVisible;
0N/A int origVSBVal;
0N/A assert(target != null);
0N/A
0N/A // Start with assumption there is not a horizontal scrollbar,
0N/A // see if we need a vertical scrollbar
0N/A
0N/A // Bug: If the list DOES have a horiz scrollbar and the value is set to
0N/A // the very bottom value, value is reset in setValues() because it isn't
0N/A // a valid value for cases when the list DOESN'T have a horiz scrollbar.
0N/A // This is currently worked-around with origVSGVal.
0N/A origVSBVal = vsb.getValue();
0N/A vis = itemsInWindow(false);
0N/A maximum = items.size() < vis ? vis : items.size();
0N/A vsb.setValues(vsb.getValue(), vis, vsb.getMinimum(), maximum);
0N/A vsbVis = vsbWasVisible = vsbIsVisible(false);
0N/A listHeight = height;
0N/A
0N/A // now see if we need a horizontal scrollbar
0N/A listWidth = getListWidth();
0N/A vis = listWidth - ((2 * SPACE) + (2 * MARGIN));
0N/A maximum = maxLength < vis ? vis : maxLength;
0N/A hsb.setValues(hsb.getValue(), vis, hsb.getMinimum(), maximum);
0N/A hsbVis = hsbIsVisible(vsbVis);
0N/A
0N/A if (hsbVis) {
0N/A // do need a horizontal scrollbar, so recalculate height of
0N/A // vertical s crollbar
0N/A listHeight = height - SCROLLBAR_AREA;
0N/A vis = itemsInWindow(true);
0N/A maximum = items.size() < vis ? vis : items.size();
0N/A vsb.setValues(origVSBVal, vis, vsb.getMinimum(), maximum);
0N/A vsbVis = vsbIsVisible(true);
0N/A }
0N/A
0N/A // now check to make sure we haven't changed need for vertical
0N/A // scrollbar - if we have, we need to
0N/A // recalculate horizontal scrollbar width - then we're done...
0N/A if (vsbWasVisible != vsbVis) {
0N/A listWidth = getListWidth();
0N/A vis = listWidth - ((2 * SPACE) + (2 * MARGIN));
0N/A maximum = maxLength < vis ? 0 : maxLength;
0N/A hsb.setValues(hsb.getValue(), vis, hsb.getMinimum(), maximum);
0N/A hsbVis = hsbIsVisible(vsbVis);
0N/A }
0N/A
0N/A vsb.setSize(SCROLLBAR_WIDTH, listHeight);
0N/A hsb.setSize(listWidth, SCROLLBAR_WIDTH);
0N/A
0N/A vsb.setBlockIncrement(itemsInWindow());
0N/A hsb.setBlockIncrement(width - ((2 * SPACE) + (2 * MARGIN) + (vsbVis ? SCROLLBAR_AREA : 0)));
0N/A }
0N/A
0N/A int getItemWidth() {
0N/A return width - ((2 * MARGIN) + (vsbVis ? SCROLLBAR_AREA : 0));
0N/A }
0N/A
0N/A /* Returns height of an item in the list */
0N/A int getItemHeight() {
0N/A return (fontHeight - fontLeading) + (2*SPACE);
0N/A }
0N/A
0N/A int getItemX() {
0N/A return MARGIN + SPACE;
0N/A }
0N/A
0N/A int getItemY(int item) {
0N/A return index2y(item);
0N/A }
0N/A
0N/A int getFocusIndex() {
0N/A return focusIndex;
0N/A }
0N/A
0N/A void setFocusIndex(int value) {
0N/A focusIndex = value;
0N/A }
0N/A
0N/A /**
0N/A * Update and return the focus rectangle.
0N/A * Focus is around the focused item, if it is visible, or
0N/A * around the border of the list if the focused item is scrolled off the top
0N/A * or bottom of the list.
0N/A */
0N/A Rectangle getFocusRect() {
0N/A Rectangle focusRect = new Rectangle();
0N/A // width is always only based on presence of vert sb
0N/A focusRect.x = 1;
0N/A focusRect.width = getListWidth() - 3;
0N/A // if focused item is not currently displayed in the list, paint
0N/A // focus around entire list (not including scrollbars)
0N/A if (isIndexDisplayed(getFocusIndex())) {
0N/A // focus rect is around the item
0N/A focusRect.y = index2y(getFocusIndex()) - 2;
0N/A focusRect.height = getItemHeight()+1;
0N/A } else {
0N/A // focus rect is around the list
0N/A focusRect.y = 1;
0N/A focusRect.height = hsbVis ? height - SCROLLBAR_AREA : height;
0N/A focusRect.height -= 3;
0N/A }
0N/A return focusRect;
0N/A }
0N/A
0N/A public void handleConfigureNotifyEvent(XEvent xev) {
0N/A super.handleConfigureNotifyEvent(xev);
0N/A
0N/A // Update buffer
0N/A painter.invalidate();
0N/A }
0N/A public boolean handlesWheelScrolling() { return true; }
0N/A
0N/A // FIXME: need to support MouseWheel scrolling, too
0N/A void handleJavaMouseEvent(MouseEvent e) {
0N/A super.handleJavaMouseEvent(e);
0N/A int i = e.getID();
0N/A switch (i) {
0N/A case MouseEvent.MOUSE_PRESSED:
0N/A mousePressed(e);
0N/A break;
0N/A case MouseEvent.MOUSE_RELEASED:
0N/A mouseReleased(e);
0N/A break;
0N/A case MouseEvent.MOUSE_DRAGGED:
0N/A mouseDragged(e);
0N/A break;
0N/A }
0N/A }
0N/A
0N/A void handleJavaMouseWheelEvent(MouseWheelEvent e) {
0N/A if (ListHelper.doWheelScroll(vsbVis ? vsb : null,
0N/A hsbVis ? hsb : null, e)) {
0N/A repaint();
0N/A }
0N/A }
0N/A
0N/A void mousePressed(MouseEvent mouseEvent) {
1696N/A if (log.isLoggable(PlatformLogger.FINER)) log.finer(mouseEvent.toString() + ", hsb " + hsbVis + ", vsb " + vsbVis);
0N/A if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
0N/A if (inWindow(mouseEvent.getX(), mouseEvent.getY())) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Mouse press in items area");
0N/A active = WINDOW;
0N/A int i = y2index(mouseEvent.getY());
0N/A if (i >= 0) {
0N/A if (multipleSelections) {
0N/A if (isSelected(i)) {
0N/A // See 6243382 for more information
0N/A deselectItem(i);
0N/A eventIndex = i;
0N/A eventType = ItemEvent.DESELECTED;
0N/A }
0N/A else {
0N/A selectItem(i);
0N/A eventIndex = i;
0N/A eventType = ItemEvent.SELECTED;
0N/A }
0N/A }
0N/A // Backward-compatible bug: even if a single-select
0N/A // item is already selected, we send an ITEM_STATE_CHANGED/
0N/A // SELECTED event. Engineer's Toolbox appears to rely on
0N/A // this.
0N/A //else if (!isSelected(i)) {
0N/A else {
0N/A selectItem(i);
0N/A eventIndex = i;
0N/A eventType = ItemEvent.SELECTED;
0N/A }
0N/A // Restoring Windows behaviour
0N/A // We should update focus index after "mouse pressed" event
0N/A setFocusIndex(i);
0N/A repaint(PAINT_FOCUS);
0N/A } else {
0N/A // 6426186: reset variable to prevent action event
0N/A // if user clicks on unoccupied area of list
0N/A currentIndex = -1;
0N/A }
0N/A } else if (inVerticalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Mouse press in vertical scrollbar");
0N/A active = VERSCROLLBAR;
0N/A vsb.handleMouseEvent(mouseEvent.getID(),
0N/A mouseEvent.getModifiers(),
0N/A mouseEvent.getX() - (width - SCROLLBAR_WIDTH),
0N/A mouseEvent.getY());
0N/A } else if (inHorizontalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Mouse press in horizontal scrollbar");
0N/A active = HORSCROLLBAR;
0N/A hsb.handleMouseEvent(mouseEvent.getID(),
0N/A mouseEvent.getModifiers(),
0N/A mouseEvent.getX(),
0N/A mouseEvent.getY() - (height - SCROLLBAR_WIDTH));
0N/A
0N/A }
0N/A isMousePressed = true;
0N/A }
0N/A }
0N/A void mouseReleased(MouseEvent mouseEvent) {
0N/A if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
0N/A //winReleaseCursorFocus();
0N/A int clickCount = mouseEvent.getClickCount();
0N/A if (active == VERSCROLLBAR) {
0N/A vsb.handleMouseEvent(mouseEvent.getID(),
0N/A mouseEvent.getModifiers(),
0N/A mouseEvent.getX()-(width-SCROLLBAR_WIDTH),
0N/A mouseEvent.getY());
0N/A } else if(active == HORSCROLLBAR) {
0N/A hsb.handleMouseEvent(mouseEvent.getID(),
0N/A mouseEvent.getModifiers(),
0N/A mouseEvent.getX(),
0N/A mouseEvent.getY()-(height-SCROLLBAR_WIDTH));
0N/A } else if ( ( currentIndex >= 0 ) && ( clickCount >= 2 ) &&
0N/A ( clickCount % 2 == 0 ) ) {
0N/A postEvent(new ActionEvent(target,
0N/A ActionEvent.ACTION_PERFORMED,
0N/A (String)items.elementAt(currentIndex),
0N/A mouseEvent.getWhen(),
0N/A mouseEvent.getModifiers())); // No ext mods
0N/A } else if (active == WINDOW) {
0N/A // See 6243382 for more information
0N/A trackMouseReleasedScroll();
0N/A
0N/A if (eventType == ItemEvent.DESELECTED) {
0N/A assert multipleSelections : "Shouldn't get a deselect for a single-select List";
0N/A // Paint deselection the release
0N/A deselectItem(eventIndex);
0N/A }
0N/A if (eventType != NONE) {
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(eventIndex),
0N/A eventType));
0N/A }
0N/A }
0N/A active = NONE;
0N/A eventIndex = -1;
0N/A eventType = NONE;
0N/A isMousePressed = false;
0N/A }
0N/A }
0N/A
0N/A void mouseDragged(MouseEvent mouseEvent) {
0N/A // TODO: can you drag w/ any other buttons? what about multiple buttons?
0N/A if (isEnabled() &&
0N/A (mouseEvent.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) {
0N/A if ((active == VERSCROLLBAR)) {
0N/A vsb.handleMouseEvent(mouseEvent.getID(),
0N/A mouseEvent.getModifiers(),
0N/A mouseEvent.getX()-(width-SCROLLBAR_WIDTH),
0N/A mouseEvent.getY());
0N/A } else if ((active == HORSCROLLBAR)) {
0N/A hsb.handleMouseEvent(mouseEvent.getID(),
0N/A mouseEvent.getModifiers(),
0N/A mouseEvent.getX(),
0N/A mouseEvent.getY()-(height-SCROLLBAR_WIDTH));
0N/A } else if (active == WINDOW) {
0N/A int i = y2index(mouseEvent.getY());
0N/A if (multipleSelections) {
0N/A // Multi-select only:
0N/A // If a selected item was pressed on and then dragged off
0N/A // of, cancel the pending deselect.
0N/A if (eventType == ItemEvent.DESELECTED) {
0N/A if (i != eventIndex) {
0N/A eventType = NONE;
0N/A eventIndex = -1;
0N/A }
0N/A }
0N/A }
0N/A else if (eventType == ItemEvent.SELECTED) {
0N/A // Single-select only:
0N/A // If an unselected item was pressed on, track the drag
0N/A // and select the item under the mouse
0N/A
0N/A // See 6243382 for more information
0N/A trackMouseDraggedScroll(mouseEvent);
0N/A
0N/A if (i >= 0 && !isSelected(i)) {
0N/A int oldSel = eventIndex;
0N/A selectItem(i);
0N/A eventIndex = i;
0N/A repaint(oldSel, eventIndex, PAINT_ITEMS);
0N/A }
0N/A }
0N/A // Restoring Windows behaviour
0N/A // We should update focus index after "mouse dragged" event
0N/A if (i >= 0) {
0N/A setFocusIndex(i);
0N/A repaint(PAINT_FOCUS);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Helper method for XListPeer with integrated vertical scrollbar.
0N/A * Start or stop vertical scrolling when mouse dragged in / out the area of the list if it's required
0N/A * Restoring Motif behavior
0N/A * See 6243382 for more information
0N/A */
0N/A void trackMouseDraggedScroll(MouseEvent mouseEvent){
0N/A
0N/A if (vsb.beforeThumb(mouseEvent.getX(), mouseEvent.getY())) {
0N/A vsb.setMode(AdjustmentEvent.UNIT_DECREMENT);
0N/A } else {
0N/A vsb.setMode(AdjustmentEvent.UNIT_INCREMENT);
0N/A }
0N/A
0N/A if(mouseEvent.getY() < 0 || mouseEvent.getY() >= listHeight){
0N/A if (!mouseDraggedOutVertically){
0N/A mouseDraggedOutVertically = true;
0N/A vsb.startScrollingInstance();
0N/A }
0N/A }else{
0N/A if (mouseDraggedOutVertically){
0N/A mouseDraggedOutVertically = false;
0N/A vsb.stopScrollingInstance();
0N/A }
0N/A }
0N/A
0N/A if (hsb.beforeThumb(mouseEvent.getX(), mouseEvent.getY())) {
0N/A hsb.setMode(AdjustmentEvent.UNIT_DECREMENT);
0N/A } else {
0N/A hsb.setMode(AdjustmentEvent.UNIT_INCREMENT);
0N/A }
0N/A
0N/A if (mouseEvent.getX() < 0 || mouseEvent.getX() >= listWidth) {
0N/A if (!mouseDraggedOutHorizontally){
0N/A mouseDraggedOutHorizontally = true;
0N/A hsb.startScrollingInstance();
0N/A }
0N/A }else{
0N/A if (mouseDraggedOutHorizontally){
0N/A mouseDraggedOutHorizontally = false;
0N/A hsb.stopScrollingInstance();
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Helper method for XListPeer with integrated vertical scrollbar.
0N/A * Stop vertical scrolling when mouse released in / out the area of the list if it's required
0N/A * Restoring Motif behavior
0N/A * see 6243382 for more information
0N/A */
0N/A void trackMouseReleasedScroll(){
0N/A
0N/A if (mouseDraggedOutVertically){
0N/A mouseDraggedOutVertically = false;
0N/A vsb.stopScrollingInstance();
0N/A }
0N/A
0N/A if (mouseDraggedOutHorizontally){
0N/A mouseDraggedOutHorizontally = false;
0N/A hsb.stopScrollingInstance();
0N/A }
0N/A }
0N/A
0N/A void handleJavaKeyEvent(KeyEvent e) {
0N/A switch(e.getID()) {
0N/A case KeyEvent.KEY_PRESSED:
0N/A if (!isMousePressed){
0N/A keyPressed(e);
0N/A }
0N/A break;
0N/A }
0N/A }
0N/A
0N/A void keyPressed(KeyEvent e) {
0N/A int keyCode = e.getKeyCode();
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine(e.toString());
0N/A switch(keyCode) {
0N/A case KeyEvent.VK_UP:
0N/A case KeyEvent.VK_KP_UP: // TODO: I assume we also want this, too
0N/A if (getFocusIndex() > 0) {
0N/A setFocusIndex(getFocusIndex()-1);
0N/A repaint(PAINT_HIDEFOCUS);
0N/A // If single-select, select the item
0N/A if (!multipleSelections) {
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A if (isItemHidden(getFocusIndex())) {
0N/A makeVisible(getFocusIndex());
0N/A }
0N/A else {
0N/A repaint(PAINT_FOCUS);
0N/A }
0N/A }
0N/A break;
0N/A case KeyEvent.VK_DOWN:
0N/A case KeyEvent.VK_KP_DOWN: // TODO: I assume we also want this, too
0N/A if (getFocusIndex() < items.size() - 1) {
0N/A setFocusIndex(getFocusIndex()+1);
0N/A repaint(PAINT_HIDEFOCUS);
0N/A // If single-select, select the item
0N/A if (!multipleSelections) {
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A if (isItemHidden(getFocusIndex())) {
0N/A makeVisible(getFocusIndex());
0N/A }
0N/A else {
0N/A repaint(PAINT_FOCUS);
0N/A }
0N/A }
0N/A break;
0N/A case KeyEvent.VK_PAGE_UP: {
0N/A // Assumes that scrollbar does its own bounds-checking
0N/A int previousValue = vsb.getValue();
0N/A vsb.setValue(vsb.getValue() - vsb.getBlockIncrement());
0N/A int currentValue = vsb.getValue();
0N/A // 6190768 pressing pg-up on AWT multiple selection lists the items but no item event is triggered, on XToolkit
0N/A // Restoring Motif behavior
0N/A if (previousValue!=currentValue) {
0N/A setFocusIndex(Math.max(getFocusIndex()-itemsInWindow(), 0));
0N/A if (!multipleSelections){
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A }
0N/A repaint();
0N/A break;
0N/A }
0N/A case KeyEvent.VK_PAGE_DOWN: {
0N/A // Assumes that scrollbar does its own bounds-checking
0N/A int previousValue = vsb.getValue();
0N/A vsb.setValue(vsb.getValue() + vsb.getBlockIncrement());
0N/A int currentValue = vsb.getValue();
0N/A // 6190768 pressing pg-down on AWT multiple selection list selects the items but no item event is triggered, on XToolkit
0N/A // Restoring Motif behavior
0N/A if (previousValue!=currentValue) {
0N/A setFocusIndex(Math.min(getFocusIndex() + itemsInWindow(), items.size()-1));
0N/A if (!multipleSelections){
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A }
0N/A repaint();
0N/A break;
0N/A }
0N/A case KeyEvent.VK_LEFT:
0N/A case KeyEvent.VK_KP_LEFT:
0N/A if (hsbVis & hsb.getValue() > 0) {
0N/A hsb.setValue(hsb.getValue() - HORIZ_SCROLL_AMT);
0N/A repaint();
0N/A }
0N/A break;
0N/A case KeyEvent.VK_RIGHT:
0N/A case KeyEvent.VK_KP_RIGHT:
0N/A if (hsbVis) { // Should check if already at end
0N/A hsb.setValue(hsb.getValue() + HORIZ_SCROLL_AMT);
0N/A repaint();
0N/A }
0N/A break;
0N/A // 6190778 CTRL + HOME, CTRL + END keys do not work properly for list on XToolkit
0N/A // Restoring Motif behavior
0N/A case KeyEvent.VK_HOME:
0N/A if (!e.isControlDown() || ((List)target).getItemCount() <= 0)
0N/A break;
0N/A if (vsbVis) {
0N/A vsb.setValue(vsb.getMinimum());
0N/A }
0N/A setFocusIndex(0);
0N/A if (!multipleSelections) {
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A repaint();
0N/A break;
0N/A case KeyEvent.VK_END:
0N/A if (!e.isControlDown() || ((List)target).getItemCount() <= 0)
0N/A break;
0N/A if (vsbVis) {
0N/A vsb.setValue(vsb.getMaximum());
0N/A }
0N/A setFocusIndex(items.size()-1);
0N/A if (!multipleSelections) {
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A repaint();
0N/A break;
0N/A case KeyEvent.VK_SPACE:
0N/A // Fixed 6299853: XToolkit: Pressing space triggers ItemStateChanged event after List.removeAll called
0N/A // If getFocusIndex() is less than 0, the event will not be triggered when space pressed
0N/A if (getFocusIndex() < 0 || ((List)target).getItemCount() <= 0) {
0N/A break;
0N/A }
0N/A
0N/A boolean isSelected = isSelected(getFocusIndex());
0N/A
0N/A // Spacebar only deselects for multi-select Lists
0N/A if (multipleSelections && isSelected) {
0N/A deselectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.DESELECTED));
0N/A }
0N/A else if (!isSelected) { // Note: this changes the Solaris/Linux
0N/A // behavior to match that of win32.
0N/A // That is, pressing space bar on a
0N/A // single-select list when the focused
0N/A // item is already selected does NOT
0N/A // send an ItemEvent.SELECTED event.
0N/A selectItem(getFocusIndex());
0N/A postEvent(new ItemEvent((List)target,
0N/A ItemEvent.ITEM_STATE_CHANGED,
0N/A Integer.valueOf(getFocusIndex()),
0N/A ItemEvent.SELECTED));
0N/A }
0N/A break;
0N/A case KeyEvent.VK_ENTER:
0N/A // It looks to me like there are bugs as well as inconsistencies
0N/A // in the way the Enter key is handled by both Solaris and Windows.
0N/A // So for now in XAWT, I'm going to simply go by what the List docs
0N/A // say: "AWT also generates an action event when the user presses
0N/A // the return key while an item in the list is selected."
0N/A if (selected.length > 0) {
0N/A postEvent(new ActionEvent((List)target,
0N/A ActionEvent.ACTION_PERFORMED,
0N/A (String)items.elementAt(getFocusIndex()),
0N/A e.getWhen(),
0N/A e.getModifiers())); // ActionEvent doesn't have
0N/A // extended modifiers.
0N/A }
0N/A break;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * return value from the scrollbar
0N/A */
0N/A public void notifyValue(XScrollbar obj, int type, int v, boolean isAdjusting) {
0N/A
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Notify value changed on " + obj + " to " + v);
0N/A int value = obj.getValue();
0N/A if (obj == vsb) {
0N/A scrollVertical(v - value);
0N/A
0N/A // See 6243382 for more information
0N/A int oldSel = eventIndex;
0N/A int newSel = eventIndex+v-value;
0N/A if (mouseDraggedOutVertically && !isSelected(newSel)){
0N/A selectItem(newSel);
0N/A eventIndex = newSel;
0N/A repaint(oldSel, eventIndex, PAINT_ITEMS);
0N/A // Scrolling select() should also set the focus index
0N/A // Otherwise, the updating of the 'focusIndex' variable will be incorrect
0N/A // if user drag mouse out of the area of the list
0N/A setFocusIndex(newSel);
0N/A repaint(PAINT_FOCUS);
0N/A }
0N/A
0N/A } else if ((XHorizontalScrollbar)obj == hsb) {
0N/A scrollHorizontal(v - value);
0N/A }
0N/A
0N/A }
0N/A
0N/A /**
0N/A * deselect all items in List
0N/A */
0N/A private void deselectAllItems() {
0N/A selected = new int [0];
0N/A repaint(PAINT_ITEMS);
0N/A }
0N/A
0N/A /**
0N/A * set multiple selections
0N/A */
0N/A public void setMultipleSelections(boolean v) {
0N/A if (multipleSelections != v) {
0N/A if ( !v) {
0N/A int selPos = ( isSelected( focusIndex )) ? focusIndex: -1;
0N/A deselectAllItems();
0N/A if (selPos != -1){
0N/A selectItem(selPos);
0N/A }
0N/A }
0N/A multipleSelections = v;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * add an item
0N/A * if the index of the item is < 0 or >= than items.size()
0N/A * then add the item to the end of the list
0N/A */
0N/A public void addItem(String item, int i) {
0N/A int oldMaxLength = maxLength;
0N/A boolean hsbWasVis = hsbVis;
0N/A boolean vsbWasVis = vsbVis;
0N/A
0N/A int addedIndex = 0; // Index where the new item ended up
0N/A if (i < 0 || i >= items.size()) {
0N/A i = -1;
0N/A }
0N/A
0N/A // Why we set this variable to -1 in spite of the fact that selected[] is changed in other way?
0N/A // It's not clear how to reproduce incorrect behaviour based on this assignment
0N/A // since before using this variable (mouseReleased) we certainly update it to correct value
0N/A // So we don't modify this behaviour now
0N/A currentIndex = -1;
0N/A
0N/A if (i == -1) {
0N/A items.addElement(item);
0N/A i = 0; // fix the math for the paintItems test
0N/A addedIndex = items.size() - 1;
0N/A } else {
0N/A items.insertElementAt(item, i);
0N/A addedIndex = i;
0N/A for (int j = 0 ; j < selected.length ; j++) {
0N/A if (selected[j] >= i) {
0N/A selected[j] += 1;
0N/A }
0N/A }
0N/A }
1696N/A if (log.isLoggable(PlatformLogger.FINER)) log.finer("Adding item '" + item + "' to " + addedIndex);
0N/A
0N/A // Update maxLength
0N/A boolean repaintItems = !isItemHidden(addedIndex);
0N/A maxLength = Math.max(maxLength, getItemWidth(addedIndex));
0N/A layout();
0N/A
0N/A int options = 0;
0N/A if (vsbVis != vsbWasVis || hsbVis != hsbWasVis) {
0N/A // Scrollbars are being added or removed, so we must repaint all
0N/A options = PAINT_ALL;
0N/A }
0N/A else {
0N/A options = (repaintItems ? (PAINT_ITEMS):0)
0N/A | ((maxLength != oldMaxLength || (hsbWasVis ^ hsbVis))?(PAINT_HSCROLL):0)
0N/A | ((vsb.needsRepaint())?(PAINT_VSCROLL):0);
0N/A
0N/A }
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Last visible: " + getLastVisibleItem() +
0N/A ", hsb changed : " + (hsbWasVis ^ hsbVis) + ", items changed " + repaintItems);
0N/A repaint(addedIndex, getLastVisibleItem(), options);
0N/A }
0N/A
0N/A /**
0N/A * delete items starting with s (start position) to e (end position) including s and e
0N/A * if s < 0 then s = 0
0N/A * if e >= items.size() then e = items.size() - 1
0N/A */
0N/A public void delItems(int s, int e) {
0N/A // save the current state of the scrollbars
0N/A boolean hsbWasVisible = hsbVis;
0N/A boolean vsbWasVisible = vsbVis;
0N/A int oldLastDisplayed = lastItemDisplayed();
0N/A
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Deleting from " + s + " to " + e);
0N/A
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Last displayed item: " + oldLastDisplayed + ", items in window " + itemsInWindow() +
0N/A ", size " + items.size());
0N/A
0N/A if (items.size() == 0) {
0N/A return;
0N/A }
0N/A
0N/A // if user passed in flipped args, reverse them
0N/A if (s > e) {
0N/A int tmp = s;
0N/A s = e;
0N/A e = tmp;
0N/A }
0N/A
0N/A // check for starting point less than zero
0N/A if (s < 0) {
0N/A s = 0;
0N/A }
0N/A
0N/A // check for end point greater than the size of the list
0N/A if (e >= items.size()) {
0N/A e = items.size() - 1;
0N/A }
0N/A
0N/A // determine whether we're going to delete any visible elements
0N/A // repaint must also be done if scrollbars appear/disappear, which
0N/A // can happen from removing a non-showing list item
0N/A /*
0N/A boolean repaintNeeded =
0N/A ((s <= lastItemDisplayed()) && (e >= vsb.getValue()));
0N/A */
0N/A boolean repaintNeeded = (s >= getFirstVisibleItem() && s <= getLastVisibleItem());
0N/A
0N/A // delete the items out of the items list and out of the selected list
0N/A for (int i = s ; i <= e ; i++) {
0N/A items.removeElementAt(s);
0N/A int j = posInSel(i);
0N/A if (j != -1) {
0N/A int newsel[] = new int[selected.length - 1];
0N/A System.arraycopy(selected, 0, newsel, 0, j);
0N/A System.arraycopy(selected, j + 1, newsel, j, selected.length - (j + 1));
0N/A selected = newsel;
0N/A }
0N/A
0N/A }
0N/A
0N/A // update the indexes in the selected array
0N/A int diff = (e - s) + 1;
0N/A for (int i = 0 ; i < selected.length ; i++) {
0N/A if (selected[i] > e) {
0N/A selected[i] -= diff;
0N/A }
0N/A }
0N/A
0N/A int options = PAINT_VSCROLL;
0N/A // focusedIndex updating according to native (Window, Motif) behaviour
0N/A if (getFocusIndex() > e) {
0N/A setFocusIndex(getFocusIndex() - (e - s + 1));
0N/A options |= PAINT_FOCUS;
0N/A } else if (getFocusIndex() >= s && getFocusIndex() <= e) {
0N/A // Fixed 6299858: PIT. Focused border not shown on List if selected item is removed, XToolkit
0N/A // We should set focus to new first item if the current first item was removed
0N/A // except if the list is empty
0N/A int focusBound = (items.size() > 0) ? 0 : -1;
0N/A setFocusIndex(Math.max(s-1, focusBound));
0N/A options |= PAINT_FOCUS;
0N/A }
0N/A
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Multiple selections: " + multipleSelections);
0N/A
0N/A // update vsb.val
0N/A if (vsb.getValue() >= s) {
0N/A if (vsb.getValue() <= e) {
0N/A vsb.setValue(e+1 - diff);
0N/A } else {
0N/A vsb.setValue(vsb.getValue() - diff);
0N/A }
0N/A }
0N/A
0N/A int oldMaxLength = maxLength;
0N/A maxLength = maxLength();
0N/A if (maxLength != oldMaxLength) {
0N/A // Width of the items changed affecting the range of
0N/A // horizontal scrollbar
0N/A options |= PAINT_HSCROLL;
0N/A }
0N/A layout();
0N/A repaintNeeded |= (vsbWasVisible ^ vsbVis) || (hsbWasVisible ^ hsbVis); // If scrollbars visibility changed
0N/A if (repaintNeeded) {
0N/A options |= PAINT_ALL;
0N/A }
0N/A repaint(s, oldLastDisplayed, options);
0N/A }
0N/A
0N/A /**
0N/A * ListPeer method
0N/A */
0N/A public void select(int index) {
0N/A // Programmatic select() should also set the focus index
0N/A setFocusIndex(index);
0N/A repaint(PAINT_FOCUS);
0N/A selectItem(index);
0N/A }
0N/A
0N/A /**
0N/A * select the index
0N/A * redraw the list to the screen
0N/A */
0N/A void selectItem(int index) {
0N/A // NOTE: instead of recalculating and the calling repaint(), painting
0N/A // is done immediately
0N/A
0N/A // 6190746 List does not trigger ActionEvent when double clicking a programmatically selected item, XToolkit
0N/A // If we invoke select(int) before setVisible(boolean), then variable currentIndex will equals -1. At the same time isSelected may be true.
0N/A // Restoring Motif behavior
0N/A currentIndex = index;
0N/A
0N/A if (isSelected(index)) {
0N/A return;
0N/A }
0N/A if (!multipleSelections) {
0N/A if (selected.length == 0) { // No current selection
0N/A selected = new int[1];
0N/A selected[0] = index;
0N/A }
0N/A else {
0N/A int oldSel = selected[0];
0N/A selected[0] = index;
0N/A if (!isItemHidden(oldSel)) {
0N/A // Only bother painting if item is visible (4895367)
0N/A repaint(oldSel, oldSel, PAINT_ITEMS);
0N/A }
0N/A }
0N/A } else {
0N/A // insert "index" into the selection array
0N/A int newsel[] = new int[selected.length + 1];
0N/A int i = 0;
0N/A while (i < selected.length && index > selected[i]) {
0N/A newsel[i] = selected[i];
0N/A i++;
0N/A }
0N/A newsel[i] = index;
0N/A System.arraycopy(selected, i, newsel, i+1, selected.length - i);
0N/A selected = newsel;
0N/A }
0N/A if (!isItemHidden(index)) {
0N/A // Only bother painting if item is visible (4895367)
0N/A repaint(index, index, PAINT_ITEMS);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * ListPeer method
0N/A * focusedIndex isn't updated according to native (Window, Motif) behaviour
0N/A */
0N/A public void deselect(int index) {
0N/A deselectItem(index);
0N/A }
0N/A
0N/A /**
0N/A * deselect the index
0N/A * redraw the list to the screen
0N/A */
0N/A void deselectItem(int index) {
0N/A if (!isSelected(index)) {
0N/A return;
0N/A }
0N/A if (!multipleSelections) {
0N/A // TODO: keep an int[0] and int[1] around and just use them instead
0N/A // creating new ones all the time
0N/A selected = new int[0];
0N/A } else {
0N/A int i = posInSel(index);
0N/A int newsel[] = new int[selected.length - 1];
0N/A System.arraycopy(selected, 0, newsel, 0, i);
0N/A System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
0N/A selected = newsel;
0N/A }
0N/A currentIndex = index;
0N/A if (!isItemHidden(index)) {
0N/A // Only bother repainting if item is visible
0N/A repaint(index, index, PAINT_ITEMS);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * ensure that the given index is visible, scrolling the List
0N/A * if necessary, or doing nothing if the item is already visible.
0N/A * The List must be repainted for changes to be visible.
0N/A */
0N/A public void makeVisible(int index) {
0N/A if (index < 0 || index >= items.size()) {
0N/A return;
0N/A }
0N/A if (isItemHidden(index)) { // Do I really need to call this?
0N/A // If index is above the top, scroll up
0N/A if (index < vsb.getValue()) {
0N/A scrollVertical(index - vsb.getValue());
0N/A }
0N/A // If index is below the bottom, scroll down
0N/A else if (index > lastItemDisplayed()) {
0N/A int val = index - lastItemDisplayed();
0N/A scrollVertical(val);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * clear
0N/A */
0N/A public void clear() {
0N/A selected = new int[0];
0N/A items = new Vector();
0N/A currentIndex = -1;
0N/A // Fixed 6291736: ITEM_STATE_CHANGED triggered after List.removeAll(), XToolkit
0N/A // We should update 'focusIndex' variable more carefully
0N/A setFocusIndex(-1);
0N/A vsb.setValue(0);
0N/A maxLength = 0;
0N/A layout();
0N/A repaint();
0N/A }
0N/A
0N/A /**
0N/A * return the selected indexes
0N/A */
0N/A public int[] getSelectedIndexes() {
0N/A return selected;
0N/A }
0N/A
0N/A /**
0N/A * return the y value of the given index "i".
0N/A * the y value represents the top of the text
0N/A * NOTE: index can be larger than items.size as long
0N/A * as it can fit the window
0N/A */
0N/A int index2y(int index) {
0N/A int h = getItemHeight();
0N/A
0N/A //if (index < vsb.getValue() || index > vsb.getValue() + itemsInWindow()) {
0N/A return MARGIN + ((index - vsb.getValue()) * h) + SPACE;
0N/A }
0N/A
0N/A /* return true if the y is a valid y coordinate for
0N/A * a VISIBLE list item, otherwise returns false
0N/A */
0N/A boolean validY(int y) {
0N/A
0N/A int shown = itemsDisplayed();
0N/A int lastY = shown * getItemHeight() + MARGIN;
0N/A
0N/A if (shown == itemsInWindow()) {
0N/A lastY += MARGIN;
0N/A }
0N/A
0N/A if (y < 0 || y >= lastY) {
0N/A return false;
0N/A }
0N/A
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * return the position of the index in the selected array
0N/A * if the index isn't in the array selected return -1;
0N/A */
0N/A int posInSel(int index) {
0N/A for (int i = 0 ; i < selected.length ; i++) {
0N/A if (index == selected[i]) {
0N/A return i;
0N/A }
0N/A }
0N/A return -1;
0N/A }
0N/A
0N/A boolean isIndexDisplayed(int idx) {
0N/A int lastDisplayed = lastItemDisplayed();
0N/A
0N/A return idx <= lastDisplayed &&
0N/A idx >= Math.max(0, lastDisplayed - itemsInWindow() + 1);
0N/A }
0N/A
0N/A /**
0N/A * returns index of last item displayed in the List
0N/A */
0N/A int lastItemDisplayed() {
0N/A int n = itemsInWindow();
0N/A return (Math.min(items.size() - 1, (vsb.getValue() + n) - 1));
0N/A }
0N/A
0N/A /**
0N/A * returns whether the given index is currently scrolled off the top or
0N/A * bottom of the List.
0N/A */
0N/A boolean isItemHidden(int index) {
0N/A return index < vsb.getValue() ||
0N/A index >= vsb.getValue() + itemsInWindow();
0N/A }
0N/A
0N/A /**
0N/A * returns the width of the list portion of the component (accounts for
0N/A * presence of vertical scrollbar)
0N/A */
0N/A int getListWidth() {
0N/A return vsbVis ? width - SCROLLBAR_AREA : width;
0N/A }
0N/A
0N/A /**
0N/A * returns number of items actually displayed in the List
0N/A */
0N/A int itemsDisplayed() {
0N/A
0N/A return (Math.min(items.size()-vsb.getValue(), itemsInWindow()));
0N/A
0N/A }
0N/A
0N/A /**
0N/A * scrollVertical
0N/A * y is the number of items to scroll
0N/A */
0N/A void scrollVertical(int y) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Scrolling vertically by " + y);
0N/A int itemsInWin = itemsInWindow();
0N/A int h = getItemHeight();
0N/A int pixelsToScroll = y * h;
0N/A
0N/A if (vsb.getValue() < -y) {
0N/A y = -vsb.getValue();
0N/A }
0N/A vsb.setValue(vsb.getValue() + y);
0N/A
222N/A Rectangle source = null;
222N/A Point distance = null;
222N/A int firstItem = 0, lastItem = 0;
222N/A int options = PAINT_HIDEFOCUS | PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS;
0N/A if (y > 0) {
222N/A if (y < itemsInWin) {
222N/A source = new Rectangle(MARGIN, MARGIN + pixelsToScroll, width - SCROLLBAR_AREA, h * (itemsInWin - y - 1)-1);
222N/A distance = new Point(0, -pixelsToScroll);
222N/A options |= COPY_AREA;
0N/A }
222N/A firstItem = vsb.getValue() + itemsInWin - y - 1;
222N/A lastItem = vsb.getValue() + itemsInWin - 1;
222N/A
222N/A } else if (y < 0) {
0N/A if (y + itemsInWindow() > 0) {
222N/A source = new Rectangle(MARGIN, MARGIN, width - SCROLLBAR_AREA, h * (itemsInWin + y));
222N/A distance = new Point(0, -pixelsToScroll);
222N/A options |= COPY_AREA;
0N/A }
222N/A firstItem = vsb.getValue();
222N/A lastItem = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
0N/A }
222N/A repaint(firstItem, lastItem, options, source, distance);
0N/A }
0N/A
0N/A /**
0N/A * scrollHorizontal
0N/A * x is the number of pixels to scroll
0N/A */
0N/A void scrollHorizontal(int x) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Scrolling horizontally by " + y);
0N/A int w = getListWidth();
0N/A w -= ((2 * SPACE) + (2 * MARGIN));
0N/A int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
0N/A hsb.setValue(hsb.getValue() + x);
0N/A
4075N/A int options = PAINT_ITEMS | PAINT_HSCROLL;
4075N/A
222N/A Rectangle source = null;
222N/A Point distance = null;
222N/A if (x < 0) {
222N/A source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h);
222N/A distance = new Point(-x, 0);
4075N/A options |= COPY_AREA;
222N/A } else if (x > 0) {
222N/A source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h);
222N/A distance = new Point(-x, 0);
4075N/A options |= COPY_AREA;
0N/A }
222N/A repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance);
0N/A }
0N/A
0N/A /**
0N/A * return the index
0N/A */
0N/A int y2index(int y) {
0N/A if (!validY(y)) {
0N/A return -1;
0N/A }
0N/A
0N/A int i = (y - MARGIN) / getItemHeight() + vsb.getValue();
0N/A int last = lastItemDisplayed();
0N/A
0N/A if (i > last) {
0N/A i = last;
0N/A }
0N/A
0N/A return i;
0N/A
0N/A }
0N/A
0N/A /**
0N/A * is the index "index" selected
0N/A */
0N/A boolean isSelected(int index) {
0N/A if (eventType == ItemEvent.SELECTED && index == eventIndex) {
0N/A return true;
0N/A }
0N/A for (int i = 0 ; i < selected.length ; i++) {
0N/A if (selected[i] == index) {
0N/A return true;
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A /**
0N/A * return the number of items that can fit
0N/A * in the current window
0N/A */
0N/A int itemsInWindow(boolean scrollbarVisible) {
0N/A int h;
0N/A if (scrollbarVisible) {
0N/A h = height - ((2 * MARGIN) + SCROLLBAR_AREA);
0N/A } else {
0N/A h = height - 2*MARGIN;
0N/A }
0N/A return (h / getItemHeight());
0N/A }
0N/A
0N/A int itemsInWindow() {
0N/A return itemsInWindow(hsbVis);
0N/A }
0N/A
0N/A /**
0N/A * return true if the x and y position is in the horizontal scrollbar
0N/A */
0N/A boolean inHorizontalScrollbar(int x, int y) {
0N/A int w = getListWidth();
0N/A int h = height - SCROLLBAR_WIDTH;
0N/A return (hsbVis && (x >= 0) && (x <= w) && (y > h));
0N/A }
0N/A
0N/A /**
0N/A * return true if the x and y position is in the verticalscrollbar
0N/A */
0N/A boolean inVerticalScrollbar(int x, int y) {
0N/A int w = width - SCROLLBAR_WIDTH;
0N/A int h = hsbVis ? height - SCROLLBAR_AREA : height;
0N/A return (vsbVis && (x > w) && (y >= 0) && (y <= h));
0N/A }
0N/A
0N/A /**
0N/A * return true if the x and y position is in the window
0N/A */
0N/A boolean inWindow(int x, int y) {
0N/A int w = getListWidth();
0N/A int h = hsbVis ? height - SCROLLBAR_AREA : height;
0N/A return ((x >= 0) && (x <= w)) && ((y >= 0) && (y <= h));
0N/A }
0N/A
0N/A /**
0N/A * return true if vertical scrollbar is visible and false otherwise;
0N/A * hsbVisible is the visibility of the horizontal scrollbar
0N/A */
0N/A boolean vsbIsVisible(boolean hsbVisible){
0N/A return (items.size() > itemsInWindow(hsbVisible));
0N/A }
0N/A
0N/A /**
0N/A * return true if horizontal scrollbar is visible and false otherwise;
0N/A * vsbVisible is the visibility of the vertical scrollbar
0N/A */
0N/A boolean hsbIsVisible(boolean vsbVisible){
0N/A int w = width - ((2*SPACE) + (2*MARGIN) + (vsbVisible ? SCROLLBAR_AREA : 0));
0N/A return (maxLength > w);
0N/A }
0N/A
0N/A /*
0N/A * Returns true if the event has been handled and should not be
0N/A * posted to Java
0N/A */
0N/A boolean prePostEvent(final AWTEvent e) {
0N/A if (e instanceof MouseEvent) {
0N/A return prePostMouseEvent((MouseEvent)e);
0N/A }
0N/A return super.prePostEvent(e);
0N/A }
0N/A
0N/A /*
0N/A * Fixed 6240151: XToolkit: Dragging the List scrollbar initiates DnD
0N/A * To be compatible with Motif, MouseEvent originated on the scrollbar
0N/A * should be sent into Java in this way:
0N/A * - post: MOUSE_ENTERED, MOUSE_EXITED, MOUSE_MOVED
0N/A * - don't post: MOUSE_PRESSED, MOUSE_RELEASED, MOUSE_CLICKED, MOUSE_DRAGGED
0N/A */
0N/A boolean prePostMouseEvent(final MouseEvent me){
0N/A if (getToplevelXWindow().isModalBlocked()) {
0N/A return false;
0N/A }
0N/A
0N/A int eventId = me.getID();
0N/A
0N/A if (eventId == MouseEvent.MOUSE_MOVED)
0N/A {
0N/A // only for performance improvement
0N/A }else if((eventId == MouseEvent.MOUSE_DRAGGED ||
0N/A eventId == MouseEvent.MOUSE_RELEASED) &&
0N/A isScrollBarOriginated)
0N/A {
0N/A if (eventId == MouseEvent.MOUSE_RELEASED) {
0N/A isScrollBarOriginated = false;
0N/A }
0N/A handleJavaMouseEventOnEDT(me);
0N/A return true;
0N/A }else if ((eventId == MouseEvent.MOUSE_PRESSED ||
0N/A eventId == MouseEvent.MOUSE_CLICKED) &&
0N/A (inVerticalScrollbar(me.getX(), me.getY()) ||
0N/A inHorizontalScrollbar(me.getX(), me.getY())))
0N/A {
0N/A if (eventId == MouseEvent.MOUSE_PRESSED) {
0N/A isScrollBarOriginated = true;
0N/A }
0N/A handleJavaMouseEventOnEDT(me);
0N/A return true;
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A /*
0N/A * Do handleJavaMouseEvent on EDT
0N/A */
0N/A void handleJavaMouseEventOnEDT(final MouseEvent me){
6441N/A InvocationEvent ev = new InvocationEvent(target, new Runnable() {
6441N/A public void run() {
6441N/A handleJavaMouseEvent(me);
6441N/A }
6441N/A });
6441N/A postEvent(ev);
0N/A }
0N/A
0N/A /*
0N/A * Fixed 5010944: List's rows overlap one another
0N/A * The bug is due to incorrent caching of the list item size
0N/A * So we should recalculate font metrics on setFont
0N/A */
0N/A public void setFont(Font f){
0N/A super.setFont(f);
0N/A initFontMetrics();
0N/A layout();
0N/A repaint();
0N/A }
0N/A
0N/A /**
0N/A * Sometimes painter is called on Toolkit thread, so the lock sequence is:
0N/A * awtLock -> Painter -> awtLock
0N/A * Sometimes it is called on other threads:
0N/A * Painter -> awtLock
0N/A * Since we can't guarantee the sequence, use awtLock.
0N/A */
0N/A class ListPainter {
0N/A VolatileImage buffer;
0N/A Color[] colors;
0N/A
0N/A private Color getListForeground() {
0N/A if (fgColorSet) {
0N/A return colors[FOREGROUND_COLOR];
0N/A }
0N/A else {
0N/A return SystemColor.textText;
0N/A }
0N/A }
0N/A private Color getListBackground() {
0N/A if (bgColorSet) {
0N/A return colors[BACKGROUND_COLOR];
0N/A }
0N/A else {
0N/A return SystemColor.text;
0N/A }
0N/A }
0N/A
0N/A private Color getDisabledColor() {
0N/A Color backgroundColor = getListBackground();
0N/A Color foregroundColor = getListForeground();
0N/A return (backgroundColor.equals(Color.BLACK)) ? foregroundColor.darker() : backgroundColor.darker();
0N/A }
0N/A
0N/A private boolean createBuffer() {
0N/A VolatileImage localBuffer = null;
0N/A XToolkit.awtLock();
0N/A try {
0N/A localBuffer = buffer;
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A
0N/A if (localBuffer == null) {
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Creating buffer " + width + "x" + height);
0N/A // use GraphicsConfig.cCVI() instead of Component.cVI(),
0N/A // because the latter may cause a deadlock with the tree lock
0N/A localBuffer =
0N/A graphicsConfig.createCompatibleVolatileImage(width+1,
0N/A height+1);
0N/A }
0N/A XToolkit.awtLock();
0N/A try {
0N/A if (buffer == null) {
0N/A buffer = localBuffer;
0N/A return true;
0N/A }
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A public void invalidate() {
0N/A XToolkit.awtLock();
0N/A try {
0N/A if (buffer != null) {
0N/A buffer.flush();
0N/A }
0N/A buffer = null;
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A }
0N/A
0N/A private void paint(Graphics listG, int firstItem, int lastItem, int options) {
222N/A paint(listG, firstItem, lastItem, options, null, null);
222N/A }
222N/A
222N/A private void paint(Graphics listG, int firstItem, int lastItem, int options,
222N/A Rectangle source, Point distance) {
1696N/A if (log.isLoggable(PlatformLogger.FINER)) log.finer("Repaint from " + firstItem + " to " + lastItem + " options " + options);
0N/A if (firstItem > lastItem) {
0N/A int t = lastItem;
0N/A lastItem = firstItem;
0N/A firstItem = t;
0N/A }
0N/A if (firstItem < 0) {
0N/A firstItem = 0;
0N/A }
0N/A colors = getGUIcolors();
0N/A VolatileImage localBuffer = null;
0N/A do {
0N/A XToolkit.awtLock();
0N/A try {
0N/A if (createBuffer()) {
0N/A // First time created buffer should be painted over at full.
0N/A options = PAINT_ALL;
0N/A }
0N/A localBuffer = buffer;
0N/A } finally {
0N/A XToolkit.awtUnlock();
0N/A }
0N/A switch (localBuffer.validate(getGraphicsConfiguration())) {
0N/A case VolatileImage.IMAGE_INCOMPATIBLE:
0N/A invalidate();
0N/A options = PAINT_ALL;
0N/A continue;
222N/A case VolatileImage.IMAGE_RESTORED:
222N/A options = PAINT_ALL;
0N/A }
0N/A Graphics g = localBuffer.createGraphics();
0N/A
222N/A // Note that the order of the following painting operations
222N/A // should not be modified
0N/A try {
0N/A g.setFont(getFont());
222N/A
222N/A // hiding the focus rectangle must be done prior to copying
222N/A // area and so this is the first action to be performed
222N/A if ((options & (PAINT_HIDEFOCUS)) != 0) {
222N/A paintFocus(g, PAINT_HIDEFOCUS);
222N/A }
222N/A /*
222N/A * The shift of the component contents occurs while someone
222N/A * scrolls the component, the only purpose of the shift is to
222N/A * increase the painting performance. The shift should be done
222N/A * prior to painting any area (except hiding focus) and actually
222N/A * it should never be done jointly with erase background.
222N/A */
222N/A if ((options & COPY_AREA) != 0) {
222N/A g.copyArea(source.x, source.y, source.width, source.height,
222N/A distance.x, distance.y);
222N/A }
0N/A if ((options & PAINT_BACKGROUND) != 0) {
222N/A paintBackground(g);
0N/A // Since we made full erase update items
0N/A firstItem = getFirstVisibleItem();
0N/A lastItem = getLastVisibleItem();
0N/A }
0N/A if ((options & PAINT_ITEMS) != 0) {
0N/A paintItems(g, firstItem, lastItem, options);
0N/A }
0N/A if ((options & PAINT_VSCROLL) != 0 && vsbVis) {
0N/A g.setClip(getVScrollBarRec());
0N/A paintVerScrollbar(g, true);
0N/A }
0N/A if ((options & PAINT_HSCROLL) != 0 && hsbVis) {
0N/A g.setClip(getHScrollBarRec());
0N/A paintHorScrollbar(g, true);
0N/A }
222N/A if ((options & (PAINT_FOCUS)) != 0) {
222N/A paintFocus(g, PAINT_FOCUS);
0N/A }
0N/A } finally {
0N/A g.dispose();
0N/A }
0N/A } while (localBuffer.contentsLost());
0N/A listG.drawImage(localBuffer, 0, 0, null);
0N/A }
0N/A
222N/A private void paintBackground(Graphics g) {
222N/A g.setColor(SystemColor.window);
222N/A g.fillRect(0, 0, width, height);
222N/A g.setColor(getListBackground());
222N/A g.fillRect(0, 0, listWidth, listHeight);
222N/A draw3DRect(g, getSystemColors(), 0, 0, listWidth - 1, listHeight - 1, false);
222N/A }
222N/A
0N/A private void paintItems(Graphics g, int firstItem, int lastItem, int options) {
1696N/A if (log.isLoggable(PlatformLogger.FINER)) log.finer("Painting items from " + firstItem + " to " + lastItem + ", focused " + focusIndex + ", first " + getFirstVisibleItem() + ", last " + getLastVisibleItem());
0N/A
0N/A firstItem = Math.max(getFirstVisibleItem(), firstItem);
0N/A if (firstItem > lastItem) {
0N/A int t = lastItem;
0N/A lastItem = firstItem;
0N/A firstItem = t;
0N/A }
0N/A firstItem = Math.max(getFirstVisibleItem(), firstItem);
0N/A lastItem = Math.min(lastItem, items.size()-1);
0N/A
1696N/A if (log.isLoggable(PlatformLogger.FINER)) log.finer("Actually painting items from " + firstItem + " to " + lastItem +
0N/A ", items in window " + itemsInWindow());
0N/A for (int i = firstItem; i <= lastItem; i++) {
0N/A paintItem(g, i);
0N/A }
0N/A }
0N/A
0N/A private void paintItem(Graphics g, int index) {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painting item " + index);
0N/A // 4895367 - only paint items which are visible
0N/A if (!isItemHidden(index)) {
0N/A Shape clip = g.getClip();
0N/A int w = getItemWidth();
0N/A int h = getItemHeight();
0N/A int y = getItemY(index);
0N/A int x = getItemX();
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Setting clip " + new Rectangle(x, y, w - (SPACE*2), h-(SPACE*2)));
0N/A g.setClip(x, y, w - (SPACE*2), h-(SPACE*2));
0N/A
0N/A // Always paint the background so that focus is unpainted in
0N/A // multiselect mode
0N/A if (isSelected(index)) {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painted item is selected");
0N/A g.setColor(getListForeground());
0N/A } else {
0N/A g.setColor(getListBackground());
0N/A }
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Filling " + new Rectangle(x, y, w, h));
0N/A g.fillRect(x, y, w, h);
0N/A
0N/A if (index <= getLastVisibleItem() && index < items.size()) {
0N/A if (!isEnabled()){
0N/A g.setColor(getDisabledColor());
0N/A } else if (isSelected(index)) {
0N/A g.setColor(getListBackground());
0N/A } else {
0N/A g.setColor(getListForeground());
0N/A }
0N/A String str = (String)items.elementAt(index);
0N/A g.drawString(str, x - hsb.getValue(), y + fontAscent);
0N/A } else {
0N/A // Clear the remaining area around the item - focus area and the rest of border
0N/A g.setClip(x, y, listWidth, h);
0N/A g.setColor(getListBackground());
0N/A g.fillRect(x, y, listWidth, h);
0N/A }
0N/A g.setClip(clip);
0N/A }
0N/A }
0N/A
0N/A void paintScrollBar(XScrollbar scr, Graphics g, int x, int y, int width, int height, boolean paintAll) {
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painting scrollbar " + scr + " width " +
0N/A width + " height " + height + ", paintAll " + paintAll);
0N/A g.translate(x, y);
0N/A scr.paint(g, getSystemColors(), paintAll);
0N/A g.translate(-x, -y);
0N/A }
0N/A
0N/A /**
0N/A * Paint the horizontal scrollbar to the screen
0N/A *
0N/A * @param g the graphics context to draw into
0N/A * @param colors the colors used to draw the scrollbar
0N/A * @param paintAll paint the whole scrollbar if true, just the thumb if false
0N/A */
0N/A void paintHorScrollbar(Graphics g, boolean paintAll) {
0N/A int w = getListWidth();
0N/A paintScrollBar(hsb, g, 0, height - (SCROLLBAR_WIDTH), w, SCROLLBAR_WIDTH, paintAll);
0N/A }
0N/A
0N/A /**
0N/A * Paint the vertical scrollbar to the screen
0N/A *
0N/A * @param g the graphics context to draw into
0N/A * @param colors the colors used to draw the scrollbar
0N/A * @param paintAll paint the whole scrollbar if true, just the thumb if false
0N/A */
0N/A void paintVerScrollbar(Graphics g, boolean paintAll) {
0N/A int h = height - (hsbVis ? (SCROLLBAR_AREA-2) : 0);
0N/A paintScrollBar(vsb, g, width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH - 2, h, paintAll);
0N/A }
0N/A
0N/A
0N/A private Rectangle prevFocusRect;
0N/A private void paintFocus(Graphics g, int options) {
0N/A boolean paintFocus = (options & PAINT_FOCUS) != 0;
0N/A if (paintFocus && !hasFocus()) {
0N/A paintFocus = false;
0N/A }
1696N/A if (log.isLoggable(PlatformLogger.FINE)) log.fine("Painting focus, focus index " + getFocusIndex() + ", focus is " +
0N/A (isItemHidden(getFocusIndex())?("invisible"):("visible")) + ", paint focus is " + paintFocus);
0N/A Shape clip = g.getClip();
0N/A g.setClip(0, 0, listWidth, listHeight);
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Setting focus clip " + new Rectangle(0, 0, listWidth, listHeight));
0N/A Rectangle rect = getFocusRect();
0N/A if (prevFocusRect != null) {
0N/A // Erase focus rect
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Erasing previous focus rect " + prevFocusRect);
0N/A g.setColor(getListBackground());
0N/A g.drawRect(prevFocusRect.x, prevFocusRect.y, prevFocusRect.width, prevFocusRect.height);
0N/A prevFocusRect = null;
0N/A }
0N/A if (paintFocus) {
0N/A // Paint new
1696N/A if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painting focus rect " + rect);
0N/A g.setColor(getListForeground()); // Focus color is always black on Linux
0N/A g.drawRect(rect.x, rect.y, rect.width, rect.height);
0N/A prevFocusRect = rect;
0N/A }
0N/A g.setClip(clip);
0N/A }
0N/A }
0N/A}