558 case MouseEvent.MOUSE_PRESSED:
559 mousePressed(e);
560 break;
561 case MouseEvent.MOUSE_RELEASED:
562 mouseReleased(e);
563 break;
564 case MouseEvent.MOUSE_DRAGGED:
565 mouseDragged(e);
566 break;
567 }
568 }
569
570 void handleJavaMouseWheelEvent(MouseWheelEvent e) {
571 if (ListHelper.doWheelScroll(vsbVis ? vsb : null,
572 hsbVis ? hsb : null, e)) {
573 repaint();
574 }
575 }
576
577 void mousePressed(MouseEvent mouseEvent) {
578 if (log.isLoggable(PlatformLogger.FINER)) {
579 log.finer(mouseEvent.toString() + ", hsb " + hsbVis + ", vsb " + vsbVis);
580 }
581 if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
582 if (inWindow(mouseEvent.getX(), mouseEvent.getY())) {
583 if (log.isLoggable(PlatformLogger.FINE)) {
584 log.fine("Mouse press in items area");
585 }
586 active = WINDOW;
587 int i = y2index(mouseEvent.getY());
588 if (i >= 0) {
589 if (multipleSelections) {
590 if (isSelected(i)) {
591 // See 6243382 for more information
592 deselectItem(i);
593 eventIndex = i;
594 eventType = ItemEvent.DESELECTED;
595 }
596 else {
597 selectItem(i);
598 eventIndex = i;
599 eventType = ItemEvent.SELECTED;
600 }
601 }
602 // Backward-compatible bug: even if a single-select
603 // item is already selected, we send an ITEM_STATE_CHANGED/
604 // SELECTED event. Engineer's Toolbox appears to rely on
605 // this.
606 //else if (!isSelected(i)) {
607 else {
608 selectItem(i);
609 eventIndex = i;
610 eventType = ItemEvent.SELECTED;
611 }
612 // Restoring Windows behaviour
613 // We should update focus index after "mouse pressed" event
614 setFocusIndex(i);
615 repaint(PAINT_FOCUS);
616 } else {
617 // 6426186: reset variable to prevent action event
618 // if user clicks on unoccupied area of list
619 currentIndex = -1;
620 }
621 } else if (inVerticalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
622 if (log.isLoggable(PlatformLogger.FINE)) {
623 log.fine("Mouse press in vertical scrollbar");
624 }
625 active = VERSCROLLBAR;
626 vsb.handleMouseEvent(mouseEvent.getID(),
627 mouseEvent.getModifiers(),
628 mouseEvent.getX() - (width - SCROLLBAR_WIDTH),
629 mouseEvent.getY());
630 } else if (inHorizontalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
631 if (log.isLoggable(PlatformLogger.FINE)) {
632 log.fine("Mouse press in horizontal scrollbar");
633 }
634 active = HORSCROLLBAR;
635 hsb.handleMouseEvent(mouseEvent.getID(),
636 mouseEvent.getModifiers(),
637 mouseEvent.getX(),
638 mouseEvent.getY() - (height - SCROLLBAR_WIDTH));
639
640 }
641 isMousePressed = true;
642 }
643 }
644 void mouseReleased(MouseEvent mouseEvent) {
645 if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
646 //winReleaseCursorFocus();
647 int clickCount = mouseEvent.getClickCount();
648 if (active == VERSCROLLBAR) {
649 vsb.handleMouseEvent(mouseEvent.getID(),
650 mouseEvent.getModifiers(),
651 mouseEvent.getX()-(width-SCROLLBAR_WIDTH),
796 }
797
798 if (mouseDraggedOutHorizontally){
799 mouseDraggedOutHorizontally = false;
800 hsb.stopScrollingInstance();
801 }
802 }
803
804 void handleJavaKeyEvent(KeyEvent e) {
805 switch(e.getID()) {
806 case KeyEvent.KEY_PRESSED:
807 if (!isMousePressed){
808 keyPressed(e);
809 }
810 break;
811 }
812 }
813
814 void keyPressed(KeyEvent e) {
815 int keyCode = e.getKeyCode();
816 if (log.isLoggable(PlatformLogger.FINE)) {
817 log.fine(e.toString());
818 }
819 switch(keyCode) {
820 case KeyEvent.VK_UP:
821 case KeyEvent.VK_KP_UP: // TODO: I assume we also want this, too
822 if (getFocusIndex() > 0) {
823 setFocusIndex(getFocusIndex()-1);
824 repaint(PAINT_HIDEFOCUS);
825 // If single-select, select the item
826 if (!multipleSelections) {
827 selectItem(getFocusIndex());
828 postEvent(new ItemEvent((List)target,
829 ItemEvent.ITEM_STATE_CHANGED,
830 Integer.valueOf(getFocusIndex()),
831 ItemEvent.SELECTED));
832 }
833 if (isItemHidden(getFocusIndex())) {
834 makeVisible(getFocusIndex());
835 }
836 else {
983 // So for now in XAWT, I'm going to simply go by what the List docs
984 // say: "AWT also generates an action event when the user presses
985 // the return key while an item in the list is selected."
986 if (selected.length > 0) {
987 postEvent(new ActionEvent((List)target,
988 ActionEvent.ACTION_PERFORMED,
989 (String)items.elementAt(getFocusIndex()),
990 e.getWhen(),
991 e.getModifiers())); // ActionEvent doesn't have
992 // extended modifiers.
993 }
994 break;
995 }
996 }
997
998 /**
999 * return value from the scrollbar
1000 */
1001 public void notifyValue(XScrollbar obj, int type, int v, boolean isAdjusting) {
1002
1003 if (log.isLoggable(PlatformLogger.FINE)) {
1004 log.fine("Notify value changed on " + obj + " to " + v);
1005 }
1006 int value = obj.getValue();
1007 if (obj == vsb) {
1008 scrollVertical(v - value);
1009
1010 // See 6243382 for more information
1011 int oldSel = eventIndex;
1012 int newSel = eventIndex+v-value;
1013 if (mouseDraggedOutVertically && !isSelected(newSel)){
1014 selectItem(newSel);
1015 eventIndex = newSel;
1016 repaint(oldSel, eventIndex, PAINT_ITEMS);
1017 // Scrolling select() should also set the focus index
1018 // Otherwise, the updating of the 'focusIndex' variable will be incorrect
1019 // if user drag mouse out of the area of the list
1020 setFocusIndex(newSel);
1021 repaint(PAINT_FOCUS);
1022 }
1023
1068
1069 // Why we set this variable to -1 in spite of the fact that selected[] is changed in other way?
1070 // It's not clear how to reproduce incorrect behaviour based on this assignment
1071 // since before using this variable (mouseReleased) we certainly update it to correct value
1072 // So we don't modify this behaviour now
1073 currentIndex = -1;
1074
1075 if (i == -1) {
1076 items.addElement(item);
1077 i = 0; // fix the math for the paintItems test
1078 addedIndex = items.size() - 1;
1079 } else {
1080 items.insertElementAt(item, i);
1081 addedIndex = i;
1082 for (int j = 0 ; j < selected.length ; j++) {
1083 if (selected[j] >= i) {
1084 selected[j] += 1;
1085 }
1086 }
1087 }
1088 if (log.isLoggable(PlatformLogger.FINER)) {
1089 log.finer("Adding item '" + item + "' to " + addedIndex);
1090 }
1091
1092 // Update maxLength
1093 boolean repaintItems = !isItemHidden(addedIndex);
1094 maxLength = Math.max(maxLength, getItemWidth(addedIndex));
1095 layout();
1096
1097 int options = 0;
1098 if (vsbVis != vsbWasVis || hsbVis != hsbWasVis) {
1099 // Scrollbars are being added or removed, so we must repaint all
1100 options = PAINT_ALL;
1101 }
1102 else {
1103 options = (repaintItems ? (PAINT_ITEMS):0)
1104 | ((maxLength != oldMaxLength || (hsbWasVis ^ hsbVis))?(PAINT_HSCROLL):0)
1105 | ((vsb.needsRepaint())?(PAINT_VSCROLL):0);
1106
1107 }
1108 if (log.isLoggable(PlatformLogger.FINEST)) {
1109 log.finest("Last visible: " + getLastVisibleItem() +
1110 ", hsb changed : " + (hsbWasVis ^ hsbVis) + ", items changed " + repaintItems);
1111 }
1112 repaint(addedIndex, getLastVisibleItem(), options);
1113 }
1114
1115 /**
1116 * delete items starting with s (start position) to e (end position) including s and e
1117 * if s < 0 then s = 0
1118 * if e >= items.size() then e = items.size() - 1
1119 */
1120 public void delItems(int s, int e) {
1121 // save the current state of the scrollbars
1122 boolean hsbWasVisible = hsbVis;
1123 boolean vsbWasVisible = vsbVis;
1124 int oldLastDisplayed = lastItemDisplayed();
1125
1126 if (log.isLoggable(PlatformLogger.FINE)) {
1127 log.fine("Deleting from " + s + " to " + e);
1128 }
1129
1130 if (log.isLoggable(PlatformLogger.FINEST)) {
1131 log.finest("Last displayed item: " + oldLastDisplayed + ", items in window " + itemsInWindow() +
1132 ", size " + items.size());
1133 }
1134
1135 if (items.size() == 0) {
1136 return;
1137 }
1138
1139 // if user passed in flipped args, reverse them
1140 if (s > e) {
1141 int tmp = s;
1142 s = e;
1143 e = tmp;
1144 }
1145
1146 // check for starting point less than zero
1147 if (s < 0) {
1148 s = 0;
1149 }
1150
1180 for (int i = 0 ; i < selected.length ; i++) {
1181 if (selected[i] > e) {
1182 selected[i] -= diff;
1183 }
1184 }
1185
1186 int options = PAINT_VSCROLL;
1187 // focusedIndex updating according to native (Window, Motif) behaviour
1188 if (getFocusIndex() > e) {
1189 setFocusIndex(getFocusIndex() - (e - s + 1));
1190 options |= PAINT_FOCUS;
1191 } else if (getFocusIndex() >= s && getFocusIndex() <= e) {
1192 // Fixed 6299858: PIT. Focused border not shown on List if selected item is removed, XToolkit
1193 // We should set focus to new first item if the current first item was removed
1194 // except if the list is empty
1195 int focusBound = (items.size() > 0) ? 0 : -1;
1196 setFocusIndex(Math.max(s-1, focusBound));
1197 options |= PAINT_FOCUS;
1198 }
1199
1200 if (log.isLoggable(PlatformLogger.FINEST)) {
1201 log.finest("Multiple selections: " + multipleSelections);
1202 }
1203
1204 // update vsb.val
1205 if (vsb.getValue() >= s) {
1206 if (vsb.getValue() <= e) {
1207 vsb.setValue(e+1 - diff);
1208 } else {
1209 vsb.setValue(vsb.getValue() - diff);
1210 }
1211 }
1212
1213 int oldMaxLength = maxLength;
1214 maxLength = maxLength();
1215 if (maxLength != oldMaxLength) {
1216 // Width of the items changed affecting the range of
1217 // horizontal scrollbar
1218 options |= PAINT_HSCROLL;
1219 }
1220 layout();
1435 * presence of vertical scrollbar)
1436 */
1437 int getListWidth() {
1438 return vsbVis ? width - SCROLLBAR_AREA : width;
1439 }
1440
1441 /**
1442 * returns number of items actually displayed in the List
1443 */
1444 int itemsDisplayed() {
1445
1446 return (Math.min(items.size()-vsb.getValue(), itemsInWindow()));
1447
1448 }
1449
1450 /**
1451 * scrollVertical
1452 * y is the number of items to scroll
1453 */
1454 void scrollVertical(int y) {
1455 if (log.isLoggable(PlatformLogger.FINE)) {
1456 log.fine("Scrolling vertically by " + y);
1457 }
1458 int itemsInWin = itemsInWindow();
1459 int h = getItemHeight();
1460 int pixelsToScroll = y * h;
1461
1462 if (vsb.getValue() < -y) {
1463 y = -vsb.getValue();
1464 }
1465 vsb.setValue(vsb.getValue() + y);
1466
1467 Rectangle source = null;
1468 Point distance = null;
1469 int firstItem = 0, lastItem = 0;
1470 int options = PAINT_HIDEFOCUS | PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS;
1471 if (y > 0) {
1472 if (y < itemsInWin) {
1473 source = new Rectangle(MARGIN, MARGIN + pixelsToScroll, width - SCROLLBAR_AREA, h * (itemsInWin - y - 1)-1);
1474 distance = new Point(0, -pixelsToScroll);
1475 options |= COPY_AREA;
1477 firstItem = vsb.getValue() + itemsInWin - y - 1;
1478 lastItem = vsb.getValue() + itemsInWin - 1;
1479
1480 } else if (y < 0) {
1481 if (y + itemsInWindow() > 0) {
1482 source = new Rectangle(MARGIN, MARGIN, width - SCROLLBAR_AREA, h * (itemsInWin + y));
1483 distance = new Point(0, -pixelsToScroll);
1484 options |= COPY_AREA;
1485 }
1486 firstItem = vsb.getValue();
1487 lastItem = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
1488 }
1489 repaint(firstItem, lastItem, options, source, distance);
1490 }
1491
1492 /**
1493 * scrollHorizontal
1494 * x is the number of pixels to scroll
1495 */
1496 void scrollHorizontal(int x) {
1497 if (log.isLoggable(PlatformLogger.FINE)) {
1498 log.fine("Scrolling horizontally by " + y);
1499 }
1500 int w = getListWidth();
1501 w -= ((2 * SPACE) + (2 * MARGIN));
1502 int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
1503 hsb.setValue(hsb.getValue() + x);
1504
1505 int options = PAINT_ITEMS | PAINT_HSCROLL;
1506
1507 Rectangle source = null;
1508 Point distance = null;
1509 if (x < 0) {
1510 source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h);
1511 distance = new Point(-x, 0);
1512 options |= COPY_AREA;
1513 } else if (x > 0) {
1514 source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h);
1515 distance = new Point(-x, 0);
1516 options |= COPY_AREA;
1517 }
1715 return SystemColor.text;
1716 }
1717 }
1718
1719 private Color getDisabledColor() {
1720 Color backgroundColor = getListBackground();
1721 Color foregroundColor = getListForeground();
1722 return (backgroundColor.equals(Color.BLACK)) ? foregroundColor.darker() : backgroundColor.darker();
1723 }
1724
1725 private boolean createBuffer() {
1726 VolatileImage localBuffer = null;
1727 XToolkit.awtLock();
1728 try {
1729 localBuffer = buffer;
1730 } finally {
1731 XToolkit.awtUnlock();
1732 }
1733
1734 if (localBuffer == null) {
1735 if (log.isLoggable(PlatformLogger.FINE)) {
1736 log.fine("Creating buffer " + width + "x" + height);
1737 }
1738 // use GraphicsConfig.cCVI() instead of Component.cVI(),
1739 // because the latter may cause a deadlock with the tree lock
1740 localBuffer =
1741 graphicsConfig.createCompatibleVolatileImage(width+1,
1742 height+1);
1743 }
1744 XToolkit.awtLock();
1745 try {
1746 if (buffer == null) {
1747 buffer = localBuffer;
1748 return true;
1749 }
1750 } finally {
1751 XToolkit.awtUnlock();
1752 }
1753 return false;
1754 }
1755
1756 public void invalidate() {
1757 XToolkit.awtLock();
1758 try {
1759 if (buffer != null) {
1760 buffer.flush();
1761 }
1762 buffer = null;
1763 } finally {
1764 XToolkit.awtUnlock();
1765 }
1766 }
1767
1768 private void paint(Graphics listG, int firstItem, int lastItem, int options) {
1769 paint(listG, firstItem, lastItem, options, null, null);
1770 }
1771
1772 private void paint(Graphics listG, int firstItem, int lastItem, int options,
1773 Rectangle source, Point distance) {
1774 if (log.isLoggable(PlatformLogger.FINER)) {
1775 log.finer("Repaint from " + firstItem + " to " + lastItem + " options " + options);
1776 }
1777 if (firstItem > lastItem) {
1778 int t = lastItem;
1779 lastItem = firstItem;
1780 firstItem = t;
1781 }
1782 if (firstItem < 0) {
1783 firstItem = 0;
1784 }
1785 colors = getGUIcolors();
1786 VolatileImage localBuffer = null;
1787 do {
1788 XToolkit.awtLock();
1789 try {
1790 if (createBuffer()) {
1791 // First time created buffer should be painted over at full.
1792 options = PAINT_ALL;
1793 }
1794 localBuffer = buffer;
1845 }
1846 if ((options & (PAINT_FOCUS)) != 0) {
1847 paintFocus(g, PAINT_FOCUS);
1848 }
1849 } finally {
1850 g.dispose();
1851 }
1852 } while (localBuffer.contentsLost());
1853 listG.drawImage(localBuffer, 0, 0, null);
1854 }
1855
1856 private void paintBackground(Graphics g) {
1857 g.setColor(SystemColor.window);
1858 g.fillRect(0, 0, width, height);
1859 g.setColor(getListBackground());
1860 g.fillRect(0, 0, listWidth, listHeight);
1861 draw3DRect(g, getSystemColors(), 0, 0, listWidth - 1, listHeight - 1, false);
1862 }
1863
1864 private void paintItems(Graphics g, int firstItem, int lastItem, int options) {
1865 if (log.isLoggable(PlatformLogger.FINER)) {
1866 log.finer("Painting items from " + firstItem + " to " + lastItem + ", focused " + focusIndex + ", first " + getFirstVisibleItem() + ", last " + getLastVisibleItem());
1867 }
1868
1869 firstItem = Math.max(getFirstVisibleItem(), firstItem);
1870 if (firstItem > lastItem) {
1871 int t = lastItem;
1872 lastItem = firstItem;
1873 firstItem = t;
1874 }
1875 firstItem = Math.max(getFirstVisibleItem(), firstItem);
1876 lastItem = Math.min(lastItem, items.size()-1);
1877
1878 if (log.isLoggable(PlatformLogger.FINER)) {
1879 log.finer("Actually painting items from " + firstItem + " to " + lastItem +
1880 ", items in window " + itemsInWindow());
1881 }
1882 for (int i = firstItem; i <= lastItem; i++) {
1883 paintItem(g, i);
1884 }
1885 }
1886
1887 private void paintItem(Graphics g, int index) {
1888 if (log.isLoggable(PlatformLogger.FINEST)) {
1889 log.finest("Painting item " + index);
1890 }
1891 // 4895367 - only paint items which are visible
1892 if (!isItemHidden(index)) {
1893 Shape clip = g.getClip();
1894 int w = getItemWidth();
1895 int h = getItemHeight();
1896 int y = getItemY(index);
1897 int x = getItemX();
1898 if (log.isLoggable(PlatformLogger.FINEST)) {
1899 log.finest("Setting clip " + new Rectangle(x, y, w - (SPACE*2), h-(SPACE*2)));
1900 }
1901 g.setClip(x, y, w - (SPACE*2), h-(SPACE*2));
1902
1903 // Always paint the background so that focus is unpainted in
1904 // multiselect mode
1905 if (isSelected(index)) {
1906 if (log.isLoggable(PlatformLogger.FINEST)) {
1907 log.finest("Painted item is selected");
1908 }
1909 g.setColor(getListForeground());
1910 } else {
1911 g.setColor(getListBackground());
1912 }
1913 if (log.isLoggable(PlatformLogger.FINEST)) {
1914 log.finest("Filling " + new Rectangle(x, y, w, h));
1915 }
1916 g.fillRect(x, y, w, h);
1917
1918 if (index <= getLastVisibleItem() && index < items.size()) {
1919 if (!isEnabled()){
1920 g.setColor(getDisabledColor());
1921 } else if (isSelected(index)) {
1922 g.setColor(getListBackground());
1923 } else {
1924 g.setColor(getListForeground());
1925 }
1926 String str = (String)items.elementAt(index);
1927 g.drawString(str, x - hsb.getValue(), y + fontAscent);
1928 } else {
1929 // Clear the remaining area around the item - focus area and the rest of border
1930 g.setClip(x, y, listWidth, h);
1931 g.setColor(getListBackground());
1932 g.fillRect(x, y, listWidth, h);
1933 }
1934 g.setClip(clip);
1935 }
1936 }
1937
1938 void paintScrollBar(XScrollbar scr, Graphics g, int x, int y, int width, int height, boolean paintAll) {
1939 if (log.isLoggable(PlatformLogger.FINEST)) {
1940 log.finest("Painting scrollbar " + scr + " width " +
1941 width + " height " + height + ", paintAll " + paintAll);
1942 }
1943 g.translate(x, y);
1944 scr.paint(g, getSystemColors(), paintAll);
1945 g.translate(-x, -y);
1946 }
1947
1948 /**
1949 * Paint the horizontal scrollbar to the screen
1950 *
1951 * @param g the graphics context to draw into
1952 * @param colors the colors used to draw the scrollbar
1953 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1954 */
1955 void paintHorScrollbar(Graphics g, boolean paintAll) {
1956 int w = getListWidth();
1957 paintScrollBar(hsb, g, 0, height - (SCROLLBAR_WIDTH), w, SCROLLBAR_WIDTH, paintAll);
1958 }
1959
1960 /**
1961 * Paint the vertical scrollbar to the screen
1962 *
1963 * @param g the graphics context to draw into
1964 * @param colors the colors used to draw the scrollbar
1965 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1966 */
1967 void paintVerScrollbar(Graphics g, boolean paintAll) {
1968 int h = height - (hsbVis ? (SCROLLBAR_AREA-2) : 0);
1969 paintScrollBar(vsb, g, width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH - 2, h, paintAll);
1970 }
1971
1972
1973 private Rectangle prevFocusRect;
1974 private void paintFocus(Graphics g, int options) {
1975 boolean paintFocus = (options & PAINT_FOCUS) != 0;
1976 if (paintFocus && !hasFocus()) {
1977 paintFocus = false;
1978 }
1979 if (log.isLoggable(PlatformLogger.FINE)) {
1980 log.fine("Painting focus, focus index " + getFocusIndex() + ", focus is " +
1981 (isItemHidden(getFocusIndex())?("invisible"):("visible")) + ", paint focus is " + paintFocus);
1982 }
1983 Shape clip = g.getClip();
1984 g.setClip(0, 0, listWidth, listHeight);
1985 if (log.isLoggable(PlatformLogger.FINEST)) {
1986 log.finest("Setting focus clip " + new Rectangle(0, 0, listWidth, listHeight));
1987 }
1988 Rectangle rect = getFocusRect();
1989 if (prevFocusRect != null) {
1990 // Erase focus rect
1991 if (log.isLoggable(PlatformLogger.FINEST)) {
1992 log.finest("Erasing previous focus rect " + prevFocusRect);
1993 }
1994 g.setColor(getListBackground());
1995 g.drawRect(prevFocusRect.x, prevFocusRect.y, prevFocusRect.width, prevFocusRect.height);
1996 prevFocusRect = null;
1997 }
1998 if (paintFocus) {
1999 // Paint new
2000 if (log.isLoggable(PlatformLogger.FINEST)) {
2001 log.finest("Painting focus rect " + rect);
2002 }
2003 g.setColor(getListForeground()); // Focus color is always black on Linux
2004 g.drawRect(rect.x, rect.y, rect.width, rect.height);
2005 prevFocusRect = rect;
2006 }
2007 g.setClip(clip);
2008 }
2009 }
2010 }
|
558 case MouseEvent.MOUSE_PRESSED:
559 mousePressed(e);
560 break;
561 case MouseEvent.MOUSE_RELEASED:
562 mouseReleased(e);
563 break;
564 case MouseEvent.MOUSE_DRAGGED:
565 mouseDragged(e);
566 break;
567 }
568 }
569
570 void handleJavaMouseWheelEvent(MouseWheelEvent e) {
571 if (ListHelper.doWheelScroll(vsbVis ? vsb : null,
572 hsbVis ? hsb : null, e)) {
573 repaint();
574 }
575 }
576
577 void mousePressed(MouseEvent mouseEvent) {
578 if (log.isLoggable(PlatformLogger.Level.FINER)) {
579 log.finer(mouseEvent.toString() + ", hsb " + hsbVis + ", vsb " + vsbVis);
580 }
581 if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
582 if (inWindow(mouseEvent.getX(), mouseEvent.getY())) {
583 if (log.isLoggable(PlatformLogger.Level.FINE)) {
584 log.fine("Mouse press in items area");
585 }
586 active = WINDOW;
587 int i = y2index(mouseEvent.getY());
588 if (i >= 0) {
589 if (multipleSelections) {
590 if (isSelected(i)) {
591 // See 6243382 for more information
592 deselectItem(i);
593 eventIndex = i;
594 eventType = ItemEvent.DESELECTED;
595 }
596 else {
597 selectItem(i);
598 eventIndex = i;
599 eventType = ItemEvent.SELECTED;
600 }
601 }
602 // Backward-compatible bug: even if a single-select
603 // item is already selected, we send an ITEM_STATE_CHANGED/
604 // SELECTED event. Engineer's Toolbox appears to rely on
605 // this.
606 //else if (!isSelected(i)) {
607 else {
608 selectItem(i);
609 eventIndex = i;
610 eventType = ItemEvent.SELECTED;
611 }
612 // Restoring Windows behaviour
613 // We should update focus index after "mouse pressed" event
614 setFocusIndex(i);
615 repaint(PAINT_FOCUS);
616 } else {
617 // 6426186: reset variable to prevent action event
618 // if user clicks on unoccupied area of list
619 currentIndex = -1;
620 }
621 } else if (inVerticalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
622 if (log.isLoggable(PlatformLogger.Level.FINE)) {
623 log.fine("Mouse press in vertical scrollbar");
624 }
625 active = VERSCROLLBAR;
626 vsb.handleMouseEvent(mouseEvent.getID(),
627 mouseEvent.getModifiers(),
628 mouseEvent.getX() - (width - SCROLLBAR_WIDTH),
629 mouseEvent.getY());
630 } else if (inHorizontalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
631 if (log.isLoggable(PlatformLogger.Level.FINE)) {
632 log.fine("Mouse press in horizontal scrollbar");
633 }
634 active = HORSCROLLBAR;
635 hsb.handleMouseEvent(mouseEvent.getID(),
636 mouseEvent.getModifiers(),
637 mouseEvent.getX(),
638 mouseEvent.getY() - (height - SCROLLBAR_WIDTH));
639
640 }
641 isMousePressed = true;
642 }
643 }
644 void mouseReleased(MouseEvent mouseEvent) {
645 if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
646 //winReleaseCursorFocus();
647 int clickCount = mouseEvent.getClickCount();
648 if (active == VERSCROLLBAR) {
649 vsb.handleMouseEvent(mouseEvent.getID(),
650 mouseEvent.getModifiers(),
651 mouseEvent.getX()-(width-SCROLLBAR_WIDTH),
796 }
797
798 if (mouseDraggedOutHorizontally){
799 mouseDraggedOutHorizontally = false;
800 hsb.stopScrollingInstance();
801 }
802 }
803
804 void handleJavaKeyEvent(KeyEvent e) {
805 switch(e.getID()) {
806 case KeyEvent.KEY_PRESSED:
807 if (!isMousePressed){
808 keyPressed(e);
809 }
810 break;
811 }
812 }
813
814 void keyPressed(KeyEvent e) {
815 int keyCode = e.getKeyCode();
816 if (log.isLoggable(PlatformLogger.Level.FINE)) {
817 log.fine(e.toString());
818 }
819 switch(keyCode) {
820 case KeyEvent.VK_UP:
821 case KeyEvent.VK_KP_UP: // TODO: I assume we also want this, too
822 if (getFocusIndex() > 0) {
823 setFocusIndex(getFocusIndex()-1);
824 repaint(PAINT_HIDEFOCUS);
825 // If single-select, select the item
826 if (!multipleSelections) {
827 selectItem(getFocusIndex());
828 postEvent(new ItemEvent((List)target,
829 ItemEvent.ITEM_STATE_CHANGED,
830 Integer.valueOf(getFocusIndex()),
831 ItemEvent.SELECTED));
832 }
833 if (isItemHidden(getFocusIndex())) {
834 makeVisible(getFocusIndex());
835 }
836 else {
983 // So for now in XAWT, I'm going to simply go by what the List docs
984 // say: "AWT also generates an action event when the user presses
985 // the return key while an item in the list is selected."
986 if (selected.length > 0) {
987 postEvent(new ActionEvent((List)target,
988 ActionEvent.ACTION_PERFORMED,
989 (String)items.elementAt(getFocusIndex()),
990 e.getWhen(),
991 e.getModifiers())); // ActionEvent doesn't have
992 // extended modifiers.
993 }
994 break;
995 }
996 }
997
998 /**
999 * return value from the scrollbar
1000 */
1001 public void notifyValue(XScrollbar obj, int type, int v, boolean isAdjusting) {
1002
1003 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1004 log.fine("Notify value changed on " + obj + " to " + v);
1005 }
1006 int value = obj.getValue();
1007 if (obj == vsb) {
1008 scrollVertical(v - value);
1009
1010 // See 6243382 for more information
1011 int oldSel = eventIndex;
1012 int newSel = eventIndex+v-value;
1013 if (mouseDraggedOutVertically && !isSelected(newSel)){
1014 selectItem(newSel);
1015 eventIndex = newSel;
1016 repaint(oldSel, eventIndex, PAINT_ITEMS);
1017 // Scrolling select() should also set the focus index
1018 // Otherwise, the updating of the 'focusIndex' variable will be incorrect
1019 // if user drag mouse out of the area of the list
1020 setFocusIndex(newSel);
1021 repaint(PAINT_FOCUS);
1022 }
1023
1068
1069 // Why we set this variable to -1 in spite of the fact that selected[] is changed in other way?
1070 // It's not clear how to reproduce incorrect behaviour based on this assignment
1071 // since before using this variable (mouseReleased) we certainly update it to correct value
1072 // So we don't modify this behaviour now
1073 currentIndex = -1;
1074
1075 if (i == -1) {
1076 items.addElement(item);
1077 i = 0; // fix the math for the paintItems test
1078 addedIndex = items.size() - 1;
1079 } else {
1080 items.insertElementAt(item, i);
1081 addedIndex = i;
1082 for (int j = 0 ; j < selected.length ; j++) {
1083 if (selected[j] >= i) {
1084 selected[j] += 1;
1085 }
1086 }
1087 }
1088 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1089 log.finer("Adding item '" + item + "' to " + addedIndex);
1090 }
1091
1092 // Update maxLength
1093 boolean repaintItems = !isItemHidden(addedIndex);
1094 maxLength = Math.max(maxLength, getItemWidth(addedIndex));
1095 layout();
1096
1097 int options = 0;
1098 if (vsbVis != vsbWasVis || hsbVis != hsbWasVis) {
1099 // Scrollbars are being added or removed, so we must repaint all
1100 options = PAINT_ALL;
1101 }
1102 else {
1103 options = (repaintItems ? (PAINT_ITEMS):0)
1104 | ((maxLength != oldMaxLength || (hsbWasVis ^ hsbVis))?(PAINT_HSCROLL):0)
1105 | ((vsb.needsRepaint())?(PAINT_VSCROLL):0);
1106
1107 }
1108 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1109 log.finest("Last visible: " + getLastVisibleItem() +
1110 ", hsb changed : " + (hsbWasVis ^ hsbVis) + ", items changed " + repaintItems);
1111 }
1112 repaint(addedIndex, getLastVisibleItem(), options);
1113 }
1114
1115 /**
1116 * delete items starting with s (start position) to e (end position) including s and e
1117 * if s < 0 then s = 0
1118 * if e >= items.size() then e = items.size() - 1
1119 */
1120 public void delItems(int s, int e) {
1121 // save the current state of the scrollbars
1122 boolean hsbWasVisible = hsbVis;
1123 boolean vsbWasVisible = vsbVis;
1124 int oldLastDisplayed = lastItemDisplayed();
1125
1126 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1127 log.fine("Deleting from " + s + " to " + e);
1128 }
1129
1130 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1131 log.finest("Last displayed item: " + oldLastDisplayed + ", items in window " + itemsInWindow() +
1132 ", size " + items.size());
1133 }
1134
1135 if (items.size() == 0) {
1136 return;
1137 }
1138
1139 // if user passed in flipped args, reverse them
1140 if (s > e) {
1141 int tmp = s;
1142 s = e;
1143 e = tmp;
1144 }
1145
1146 // check for starting point less than zero
1147 if (s < 0) {
1148 s = 0;
1149 }
1150
1180 for (int i = 0 ; i < selected.length ; i++) {
1181 if (selected[i] > e) {
1182 selected[i] -= diff;
1183 }
1184 }
1185
1186 int options = PAINT_VSCROLL;
1187 // focusedIndex updating according to native (Window, Motif) behaviour
1188 if (getFocusIndex() > e) {
1189 setFocusIndex(getFocusIndex() - (e - s + 1));
1190 options |= PAINT_FOCUS;
1191 } else if (getFocusIndex() >= s && getFocusIndex() <= e) {
1192 // Fixed 6299858: PIT. Focused border not shown on List if selected item is removed, XToolkit
1193 // We should set focus to new first item if the current first item was removed
1194 // except if the list is empty
1195 int focusBound = (items.size() > 0) ? 0 : -1;
1196 setFocusIndex(Math.max(s-1, focusBound));
1197 options |= PAINT_FOCUS;
1198 }
1199
1200 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1201 log.finest("Multiple selections: " + multipleSelections);
1202 }
1203
1204 // update vsb.val
1205 if (vsb.getValue() >= s) {
1206 if (vsb.getValue() <= e) {
1207 vsb.setValue(e+1 - diff);
1208 } else {
1209 vsb.setValue(vsb.getValue() - diff);
1210 }
1211 }
1212
1213 int oldMaxLength = maxLength;
1214 maxLength = maxLength();
1215 if (maxLength != oldMaxLength) {
1216 // Width of the items changed affecting the range of
1217 // horizontal scrollbar
1218 options |= PAINT_HSCROLL;
1219 }
1220 layout();
1435 * presence of vertical scrollbar)
1436 */
1437 int getListWidth() {
1438 return vsbVis ? width - SCROLLBAR_AREA : width;
1439 }
1440
1441 /**
1442 * returns number of items actually displayed in the List
1443 */
1444 int itemsDisplayed() {
1445
1446 return (Math.min(items.size()-vsb.getValue(), itemsInWindow()));
1447
1448 }
1449
1450 /**
1451 * scrollVertical
1452 * y is the number of items to scroll
1453 */
1454 void scrollVertical(int y) {
1455 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1456 log.fine("Scrolling vertically by " + y);
1457 }
1458 int itemsInWin = itemsInWindow();
1459 int h = getItemHeight();
1460 int pixelsToScroll = y * h;
1461
1462 if (vsb.getValue() < -y) {
1463 y = -vsb.getValue();
1464 }
1465 vsb.setValue(vsb.getValue() + y);
1466
1467 Rectangle source = null;
1468 Point distance = null;
1469 int firstItem = 0, lastItem = 0;
1470 int options = PAINT_HIDEFOCUS | PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS;
1471 if (y > 0) {
1472 if (y < itemsInWin) {
1473 source = new Rectangle(MARGIN, MARGIN + pixelsToScroll, width - SCROLLBAR_AREA, h * (itemsInWin - y - 1)-1);
1474 distance = new Point(0, -pixelsToScroll);
1475 options |= COPY_AREA;
1477 firstItem = vsb.getValue() + itemsInWin - y - 1;
1478 lastItem = vsb.getValue() + itemsInWin - 1;
1479
1480 } else if (y < 0) {
1481 if (y + itemsInWindow() > 0) {
1482 source = new Rectangle(MARGIN, MARGIN, width - SCROLLBAR_AREA, h * (itemsInWin + y));
1483 distance = new Point(0, -pixelsToScroll);
1484 options |= COPY_AREA;
1485 }
1486 firstItem = vsb.getValue();
1487 lastItem = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
1488 }
1489 repaint(firstItem, lastItem, options, source, distance);
1490 }
1491
1492 /**
1493 * scrollHorizontal
1494 * x is the number of pixels to scroll
1495 */
1496 void scrollHorizontal(int x) {
1497 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1498 log.fine("Scrolling horizontally by " + y);
1499 }
1500 int w = getListWidth();
1501 w -= ((2 * SPACE) + (2 * MARGIN));
1502 int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
1503 hsb.setValue(hsb.getValue() + x);
1504
1505 int options = PAINT_ITEMS | PAINT_HSCROLL;
1506
1507 Rectangle source = null;
1508 Point distance = null;
1509 if (x < 0) {
1510 source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h);
1511 distance = new Point(-x, 0);
1512 options |= COPY_AREA;
1513 } else if (x > 0) {
1514 source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h);
1515 distance = new Point(-x, 0);
1516 options |= COPY_AREA;
1517 }
1715 return SystemColor.text;
1716 }
1717 }
1718
1719 private Color getDisabledColor() {
1720 Color backgroundColor = getListBackground();
1721 Color foregroundColor = getListForeground();
1722 return (backgroundColor.equals(Color.BLACK)) ? foregroundColor.darker() : backgroundColor.darker();
1723 }
1724
1725 private boolean createBuffer() {
1726 VolatileImage localBuffer = null;
1727 XToolkit.awtLock();
1728 try {
1729 localBuffer = buffer;
1730 } finally {
1731 XToolkit.awtUnlock();
1732 }
1733
1734 if (localBuffer == null) {
1735 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1736 log.fine("Creating buffer " + width + "x" + height);
1737 }
1738 // use GraphicsConfig.cCVI() instead of Component.cVI(),
1739 // because the latter may cause a deadlock with the tree lock
1740 localBuffer =
1741 graphicsConfig.createCompatibleVolatileImage(width+1,
1742 height+1);
1743 }
1744 XToolkit.awtLock();
1745 try {
1746 if (buffer == null) {
1747 buffer = localBuffer;
1748 return true;
1749 }
1750 } finally {
1751 XToolkit.awtUnlock();
1752 }
1753 return false;
1754 }
1755
1756 public void invalidate() {
1757 XToolkit.awtLock();
1758 try {
1759 if (buffer != null) {
1760 buffer.flush();
1761 }
1762 buffer = null;
1763 } finally {
1764 XToolkit.awtUnlock();
1765 }
1766 }
1767
1768 private void paint(Graphics listG, int firstItem, int lastItem, int options) {
1769 paint(listG, firstItem, lastItem, options, null, null);
1770 }
1771
1772 private void paint(Graphics listG, int firstItem, int lastItem, int options,
1773 Rectangle source, Point distance) {
1774 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1775 log.finer("Repaint from " + firstItem + " to " + lastItem + " options " + options);
1776 }
1777 if (firstItem > lastItem) {
1778 int t = lastItem;
1779 lastItem = firstItem;
1780 firstItem = t;
1781 }
1782 if (firstItem < 0) {
1783 firstItem = 0;
1784 }
1785 colors = getGUIcolors();
1786 VolatileImage localBuffer = null;
1787 do {
1788 XToolkit.awtLock();
1789 try {
1790 if (createBuffer()) {
1791 // First time created buffer should be painted over at full.
1792 options = PAINT_ALL;
1793 }
1794 localBuffer = buffer;
1845 }
1846 if ((options & (PAINT_FOCUS)) != 0) {
1847 paintFocus(g, PAINT_FOCUS);
1848 }
1849 } finally {
1850 g.dispose();
1851 }
1852 } while (localBuffer.contentsLost());
1853 listG.drawImage(localBuffer, 0, 0, null);
1854 }
1855
1856 private void paintBackground(Graphics g) {
1857 g.setColor(SystemColor.window);
1858 g.fillRect(0, 0, width, height);
1859 g.setColor(getListBackground());
1860 g.fillRect(0, 0, listWidth, listHeight);
1861 draw3DRect(g, getSystemColors(), 0, 0, listWidth - 1, listHeight - 1, false);
1862 }
1863
1864 private void paintItems(Graphics g, int firstItem, int lastItem, int options) {
1865 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1866 log.finer("Painting items from " + firstItem + " to " + lastItem + ", focused " + focusIndex + ", first " + getFirstVisibleItem() + ", last " + getLastVisibleItem());
1867 }
1868
1869 firstItem = Math.max(getFirstVisibleItem(), firstItem);
1870 if (firstItem > lastItem) {
1871 int t = lastItem;
1872 lastItem = firstItem;
1873 firstItem = t;
1874 }
1875 firstItem = Math.max(getFirstVisibleItem(), firstItem);
1876 lastItem = Math.min(lastItem, items.size()-1);
1877
1878 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1879 log.finer("Actually painting items from " + firstItem + " to " + lastItem +
1880 ", items in window " + itemsInWindow());
1881 }
1882 for (int i = firstItem; i <= lastItem; i++) {
1883 paintItem(g, i);
1884 }
1885 }
1886
1887 private void paintItem(Graphics g, int index) {
1888 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1889 log.finest("Painting item " + index);
1890 }
1891 // 4895367 - only paint items which are visible
1892 if (!isItemHidden(index)) {
1893 Shape clip = g.getClip();
1894 int w = getItemWidth();
1895 int h = getItemHeight();
1896 int y = getItemY(index);
1897 int x = getItemX();
1898 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1899 log.finest("Setting clip " + new Rectangle(x, y, w - (SPACE*2), h-(SPACE*2)));
1900 }
1901 g.setClip(x, y, w - (SPACE*2), h-(SPACE*2));
1902
1903 // Always paint the background so that focus is unpainted in
1904 // multiselect mode
1905 if (isSelected(index)) {
1906 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1907 log.finest("Painted item is selected");
1908 }
1909 g.setColor(getListForeground());
1910 } else {
1911 g.setColor(getListBackground());
1912 }
1913 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1914 log.finest("Filling " + new Rectangle(x, y, w, h));
1915 }
1916 g.fillRect(x, y, w, h);
1917
1918 if (index <= getLastVisibleItem() && index < items.size()) {
1919 if (!isEnabled()){
1920 g.setColor(getDisabledColor());
1921 } else if (isSelected(index)) {
1922 g.setColor(getListBackground());
1923 } else {
1924 g.setColor(getListForeground());
1925 }
1926 String str = (String)items.elementAt(index);
1927 g.drawString(str, x - hsb.getValue(), y + fontAscent);
1928 } else {
1929 // Clear the remaining area around the item - focus area and the rest of border
1930 g.setClip(x, y, listWidth, h);
1931 g.setColor(getListBackground());
1932 g.fillRect(x, y, listWidth, h);
1933 }
1934 g.setClip(clip);
1935 }
1936 }
1937
1938 void paintScrollBar(XScrollbar scr, Graphics g, int x, int y, int width, int height, boolean paintAll) {
1939 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1940 log.finest("Painting scrollbar " + scr + " width " +
1941 width + " height " + height + ", paintAll " + paintAll);
1942 }
1943 g.translate(x, y);
1944 scr.paint(g, getSystemColors(), paintAll);
1945 g.translate(-x, -y);
1946 }
1947
1948 /**
1949 * Paint the horizontal scrollbar to the screen
1950 *
1951 * @param g the graphics context to draw into
1952 * @param colors the colors used to draw the scrollbar
1953 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1954 */
1955 void paintHorScrollbar(Graphics g, boolean paintAll) {
1956 int w = getListWidth();
1957 paintScrollBar(hsb, g, 0, height - (SCROLLBAR_WIDTH), w, SCROLLBAR_WIDTH, paintAll);
1958 }
1959
1960 /**
1961 * Paint the vertical scrollbar to the screen
1962 *
1963 * @param g the graphics context to draw into
1964 * @param colors the colors used to draw the scrollbar
1965 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1966 */
1967 void paintVerScrollbar(Graphics g, boolean paintAll) {
1968 int h = height - (hsbVis ? (SCROLLBAR_AREA-2) : 0);
1969 paintScrollBar(vsb, g, width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH - 2, h, paintAll);
1970 }
1971
1972
1973 private Rectangle prevFocusRect;
1974 private void paintFocus(Graphics g, int options) {
1975 boolean paintFocus = (options & PAINT_FOCUS) != 0;
1976 if (paintFocus && !hasFocus()) {
1977 paintFocus = false;
1978 }
1979 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1980 log.fine("Painting focus, focus index " + getFocusIndex() + ", focus is " +
1981 (isItemHidden(getFocusIndex())?("invisible"):("visible")) + ", paint focus is " + paintFocus);
1982 }
1983 Shape clip = g.getClip();
1984 g.setClip(0, 0, listWidth, listHeight);
1985 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1986 log.finest("Setting focus clip " + new Rectangle(0, 0, listWidth, listHeight));
1987 }
1988 Rectangle rect = getFocusRect();
1989 if (prevFocusRect != null) {
1990 // Erase focus rect
1991 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
1992 log.finest("Erasing previous focus rect " + prevFocusRect);
1993 }
1994 g.setColor(getListBackground());
1995 g.drawRect(prevFocusRect.x, prevFocusRect.y, prevFocusRect.width, prevFocusRect.height);
1996 prevFocusRect = null;
1997 }
1998 if (paintFocus) {
1999 // Paint new
2000 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
2001 log.finest("Painting focus rect " + rect);
2002 }
2003 g.setColor(getListForeground()); // Focus color is always black on Linux
2004 g.drawRect(rect.x, rect.y, rect.width, rect.height);
2005 prevFocusRect = rect;
2006 }
2007 g.setClip(clip);
2008 }
2009 }
2010 }
|