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)) log.finer(mouseEvent.toString() + ", hsb " + hsbVis + ", vsb " + vsbVis);
579 if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
580 if (inWindow(mouseEvent.getX(), mouseEvent.getY())) {
581 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Mouse press in items area");
582 active = WINDOW;
583 int i = y2index(mouseEvent.getY());
584 if (i >= 0) {
585 if (multipleSelections) {
586 if (isSelected(i)) {
587 // See 6243382 for more information
588 deselectItem(i);
589 eventIndex = i;
590 eventType = ItemEvent.DESELECTED;
591 }
592 else {
593 selectItem(i);
594 eventIndex = i;
595 eventType = ItemEvent.SELECTED;
596 }
597 }
598 // Backward-compatible bug: even if a single-select
599 // item is already selected, we send an ITEM_STATE_CHANGED/
600 // SELECTED event. Engineer's Toolbox appears to rely on
601 // this.
602 //else if (!isSelected(i)) {
603 else {
604 selectItem(i);
605 eventIndex = i;
606 eventType = ItemEvent.SELECTED;
607 }
608 // Restoring Windows behaviour
609 // We should update focus index after "mouse pressed" event
610 setFocusIndex(i);
611 repaint(PAINT_FOCUS);
612 } else {
613 // 6426186: reset variable to prevent action event
614 // if user clicks on unoccupied area of list
615 currentIndex = -1;
616 }
617 } else if (inVerticalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
618 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Mouse press in vertical scrollbar");
619 active = VERSCROLLBAR;
620 vsb.handleMouseEvent(mouseEvent.getID(),
621 mouseEvent.getModifiers(),
622 mouseEvent.getX() - (width - SCROLLBAR_WIDTH),
623 mouseEvent.getY());
624 } else if (inHorizontalScrollbar(mouseEvent.getX(), mouseEvent.getY())) {
625 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Mouse press in horizontal scrollbar");
626 active = HORSCROLLBAR;
627 hsb.handleMouseEvent(mouseEvent.getID(),
628 mouseEvent.getModifiers(),
629 mouseEvent.getX(),
630 mouseEvent.getY() - (height - SCROLLBAR_WIDTH));
631
632 }
633 isMousePressed = true;
634 }
635 }
636 void mouseReleased(MouseEvent mouseEvent) {
637 if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
638 //winReleaseCursorFocus();
639 int clickCount = mouseEvent.getClickCount();
640 if (active == VERSCROLLBAR) {
641 vsb.handleMouseEvent(mouseEvent.getID(),
642 mouseEvent.getModifiers(),
643 mouseEvent.getX()-(width-SCROLLBAR_WIDTH),
644 mouseEvent.getY());
645 } else if(active == HORSCROLLBAR) {
788 }
789
790 if (mouseDraggedOutHorizontally){
791 mouseDraggedOutHorizontally = false;
792 hsb.stopScrollingInstance();
793 }
794 }
795
796 void handleJavaKeyEvent(KeyEvent e) {
797 switch(e.getID()) {
798 case KeyEvent.KEY_PRESSED:
799 if (!isMousePressed){
800 keyPressed(e);
801 }
802 break;
803 }
804 }
805
806 void keyPressed(KeyEvent e) {
807 int keyCode = e.getKeyCode();
808 if (log.isLoggable(PlatformLogger.FINE)) log.fine(e.toString());
809 switch(keyCode) {
810 case KeyEvent.VK_UP:
811 case KeyEvent.VK_KP_UP: // TODO: I assume we also want this, too
812 if (getFocusIndex() > 0) {
813 setFocusIndex(getFocusIndex()-1);
814 repaint(PAINT_HIDEFOCUS);
815 // If single-select, select the item
816 if (!multipleSelections) {
817 selectItem(getFocusIndex());
818 postEvent(new ItemEvent((List)target,
819 ItemEvent.ITEM_STATE_CHANGED,
820 Integer.valueOf(getFocusIndex()),
821 ItemEvent.SELECTED));
822 }
823 if (isItemHidden(getFocusIndex())) {
824 makeVisible(getFocusIndex());
825 }
826 else {
827 repaint(PAINT_FOCUS);
828 }
973 // So for now in XAWT, I'm going to simply go by what the List docs
974 // say: "AWT also generates an action event when the user presses
975 // the return key while an item in the list is selected."
976 if (selected.length > 0) {
977 postEvent(new ActionEvent((List)target,
978 ActionEvent.ACTION_PERFORMED,
979 (String)items.elementAt(getFocusIndex()),
980 e.getWhen(),
981 e.getModifiers())); // ActionEvent doesn't have
982 // extended modifiers.
983 }
984 break;
985 }
986 }
987
988 /**
989 * return value from the scrollbar
990 */
991 public void notifyValue(XScrollbar obj, int type, int v, boolean isAdjusting) {
992
993 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Notify value changed on " + obj + " to " + v);
994 int value = obj.getValue();
995 if (obj == vsb) {
996 scrollVertical(v - value);
997
998 // See 6243382 for more information
999 int oldSel = eventIndex;
1000 int newSel = eventIndex+v-value;
1001 if (mouseDraggedOutVertically && !isSelected(newSel)){
1002 selectItem(newSel);
1003 eventIndex = newSel;
1004 repaint(oldSel, eventIndex, PAINT_ITEMS);
1005 // Scrolling select() should also set the focus index
1006 // Otherwise, the updating of the 'focusIndex' variable will be incorrect
1007 // if user drag mouse out of the area of the list
1008 setFocusIndex(newSel);
1009 repaint(PAINT_FOCUS);
1010 }
1011
1012 } else if ((XHorizontalScrollbar)obj == hsb) {
1013 scrollHorizontal(v - value);
1056
1057 // Why we set this variable to -1 in spite of the fact that selected[] is changed in other way?
1058 // It's not clear how to reproduce incorrect behaviour based on this assignment
1059 // since before using this variable (mouseReleased) we certainly update it to correct value
1060 // So we don't modify this behaviour now
1061 currentIndex = -1;
1062
1063 if (i == -1) {
1064 items.addElement(item);
1065 i = 0; // fix the math for the paintItems test
1066 addedIndex = items.size() - 1;
1067 } else {
1068 items.insertElementAt(item, i);
1069 addedIndex = i;
1070 for (int j = 0 ; j < selected.length ; j++) {
1071 if (selected[j] >= i) {
1072 selected[j] += 1;
1073 }
1074 }
1075 }
1076 if (log.isLoggable(PlatformLogger.FINER)) log.finer("Adding item '" + item + "' to " + addedIndex);
1077
1078 // Update maxLength
1079 boolean repaintItems = !isItemHidden(addedIndex);
1080 maxLength = Math.max(maxLength, getItemWidth(addedIndex));
1081 layout();
1082
1083 int options = 0;
1084 if (vsbVis != vsbWasVis || hsbVis != hsbWasVis) {
1085 // Scrollbars are being added or removed, so we must repaint all
1086 options = PAINT_ALL;
1087 }
1088 else {
1089 options = (repaintItems ? (PAINT_ITEMS):0)
1090 | ((maxLength != oldMaxLength || (hsbWasVis ^ hsbVis))?(PAINT_HSCROLL):0)
1091 | ((vsb.needsRepaint())?(PAINT_VSCROLL):0);
1092
1093 }
1094 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Last visible: " + getLastVisibleItem() +
1095 ", hsb changed : " + (hsbWasVis ^ hsbVis) + ", items changed " + repaintItems);
1096 repaint(addedIndex, getLastVisibleItem(), options);
1097 }
1098
1099 /**
1100 * delete items starting with s (start position) to e (end position) including s and e
1101 * if s < 0 then s = 0
1102 * if e >= items.size() then e = items.size() - 1
1103 */
1104 public void delItems(int s, int e) {
1105 // save the current state of the scrollbars
1106 boolean hsbWasVisible = hsbVis;
1107 boolean vsbWasVisible = vsbVis;
1108 int oldLastDisplayed = lastItemDisplayed();
1109
1110 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Deleting from " + s + " to " + e);
1111
1112 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Last displayed item: " + oldLastDisplayed + ", items in window " + itemsInWindow() +
1113 ", size " + items.size());
1114
1115 if (items.size() == 0) {
1116 return;
1117 }
1118
1119 // if user passed in flipped args, reverse them
1120 if (s > e) {
1121 int tmp = s;
1122 s = e;
1123 e = tmp;
1124 }
1125
1126 // check for starting point less than zero
1127 if (s < 0) {
1128 s = 0;
1129 }
1130
1131 // check for end point greater than the size of the list
1132 if (e >= items.size()) {
1133 e = items.size() - 1;
1160 for (int i = 0 ; i < selected.length ; i++) {
1161 if (selected[i] > e) {
1162 selected[i] -= diff;
1163 }
1164 }
1165
1166 int options = PAINT_VSCROLL;
1167 // focusedIndex updating according to native (Window, Motif) behaviour
1168 if (getFocusIndex() > e) {
1169 setFocusIndex(getFocusIndex() - (e - s + 1));
1170 options |= PAINT_FOCUS;
1171 } else if (getFocusIndex() >= s && getFocusIndex() <= e) {
1172 // Fixed 6299858: PIT. Focused border not shown on List if selected item is removed, XToolkit
1173 // We should set focus to new first item if the current first item was removed
1174 // except if the list is empty
1175 int focusBound = (items.size() > 0) ? 0 : -1;
1176 setFocusIndex(Math.max(s-1, focusBound));
1177 options |= PAINT_FOCUS;
1178 }
1179
1180 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Multiple selections: " + multipleSelections);
1181
1182 // update vsb.val
1183 if (vsb.getValue() >= s) {
1184 if (vsb.getValue() <= e) {
1185 vsb.setValue(e+1 - diff);
1186 } else {
1187 vsb.setValue(vsb.getValue() - diff);
1188 }
1189 }
1190
1191 int oldMaxLength = maxLength;
1192 maxLength = maxLength();
1193 if (maxLength != oldMaxLength) {
1194 // Width of the items changed affecting the range of
1195 // horizontal scrollbar
1196 options |= PAINT_HSCROLL;
1197 }
1198 layout();
1199 repaintNeeded |= (vsbWasVisible ^ vsbVis) || (hsbWasVisible ^ hsbVis); // If scrollbars visibility changed
1200 if (repaintNeeded) {
1413 * presence of vertical scrollbar)
1414 */
1415 int getListWidth() {
1416 return vsbVis ? width - SCROLLBAR_AREA : width;
1417 }
1418
1419 /**
1420 * returns number of items actually displayed in the List
1421 */
1422 int itemsDisplayed() {
1423
1424 return (Math.min(items.size()-vsb.getValue(), itemsInWindow()));
1425
1426 }
1427
1428 /**
1429 * scrollVertical
1430 * y is the number of items to scroll
1431 */
1432 void scrollVertical(int y) {
1433 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Scrolling vertically by " + y);
1434 int itemsInWin = itemsInWindow();
1435 int h = getItemHeight();
1436 int pixelsToScroll = y * h;
1437
1438 if (vsb.getValue() < -y) {
1439 y = -vsb.getValue();
1440 }
1441 vsb.setValue(vsb.getValue() + y);
1442
1443 Rectangle source = null;
1444 Point distance = null;
1445 int firstItem = 0, lastItem = 0;
1446 int options = PAINT_HIDEFOCUS | PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS;
1447 if (y > 0) {
1448 if (y < itemsInWin) {
1449 source = new Rectangle(MARGIN, MARGIN + pixelsToScroll, width - SCROLLBAR_AREA, h * (itemsInWin - y - 1)-1);
1450 distance = new Point(0, -pixelsToScroll);
1451 options |= COPY_AREA;
1452 }
1453 firstItem = vsb.getValue() + itemsInWin - y - 1;
1454 lastItem = vsb.getValue() + itemsInWin - 1;
1455
1456 } else if (y < 0) {
1457 if (y + itemsInWindow() > 0) {
1458 source = new Rectangle(MARGIN, MARGIN, width - SCROLLBAR_AREA, h * (itemsInWin + y));
1459 distance = new Point(0, -pixelsToScroll);
1460 options |= COPY_AREA;
1461 }
1462 firstItem = vsb.getValue();
1463 lastItem = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
1464 }
1465 repaint(firstItem, lastItem, options, source, distance);
1466 }
1467
1468 /**
1469 * scrollHorizontal
1470 * x is the number of pixels to scroll
1471 */
1472 void scrollHorizontal(int x) {
1473 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Scrolling horizontally by " + y);
1474 int w = getListWidth();
1475 w -= ((2 * SPACE) + (2 * MARGIN));
1476 int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
1477 hsb.setValue(hsb.getValue() + x);
1478
1479 int options = PAINT_ITEMS | PAINT_HSCROLL;
1480
1481 Rectangle source = null;
1482 Point distance = null;
1483 if (x < 0) {
1484 source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h);
1485 distance = new Point(-x, 0);
1486 options |= COPY_AREA;
1487 } else if (x > 0) {
1488 source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h);
1489 distance = new Point(-x, 0);
1490 options |= COPY_AREA;
1491 }
1492 repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance);
1493 }
1689 return SystemColor.text;
1690 }
1691 }
1692
1693 private Color getDisabledColor() {
1694 Color backgroundColor = getListBackground();
1695 Color foregroundColor = getListForeground();
1696 return (backgroundColor.equals(Color.BLACK)) ? foregroundColor.darker() : backgroundColor.darker();
1697 }
1698
1699 private boolean createBuffer() {
1700 VolatileImage localBuffer = null;
1701 XToolkit.awtLock();
1702 try {
1703 localBuffer = buffer;
1704 } finally {
1705 XToolkit.awtUnlock();
1706 }
1707
1708 if (localBuffer == null) {
1709 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Creating buffer " + width + "x" + height);
1710 // use GraphicsConfig.cCVI() instead of Component.cVI(),
1711 // because the latter may cause a deadlock with the tree lock
1712 localBuffer =
1713 graphicsConfig.createCompatibleVolatileImage(width+1,
1714 height+1);
1715 }
1716 XToolkit.awtLock();
1717 try {
1718 if (buffer == null) {
1719 buffer = localBuffer;
1720 return true;
1721 }
1722 } finally {
1723 XToolkit.awtUnlock();
1724 }
1725 return false;
1726 }
1727
1728 public void invalidate() {
1729 XToolkit.awtLock();
1730 try {
1731 if (buffer != null) {
1732 buffer.flush();
1733 }
1734 buffer = null;
1735 } finally {
1736 XToolkit.awtUnlock();
1737 }
1738 }
1739
1740 private void paint(Graphics listG, int firstItem, int lastItem, int options) {
1741 paint(listG, firstItem, lastItem, options, null, null);
1742 }
1743
1744 private void paint(Graphics listG, int firstItem, int lastItem, int options,
1745 Rectangle source, Point distance) {
1746 if (log.isLoggable(PlatformLogger.FINER)) log.finer("Repaint from " + firstItem + " to " + lastItem + " options " + options);
1747 if (firstItem > lastItem) {
1748 int t = lastItem;
1749 lastItem = firstItem;
1750 firstItem = t;
1751 }
1752 if (firstItem < 0) {
1753 firstItem = 0;
1754 }
1755 colors = getGUIcolors();
1756 VolatileImage localBuffer = null;
1757 do {
1758 XToolkit.awtLock();
1759 try {
1760 if (createBuffer()) {
1761 // First time created buffer should be painted over at full.
1762 options = PAINT_ALL;
1763 }
1764 localBuffer = buffer;
1765 } finally {
1766 XToolkit.awtUnlock();
1815 }
1816 if ((options & (PAINT_FOCUS)) != 0) {
1817 paintFocus(g, PAINT_FOCUS);
1818 }
1819 } finally {
1820 g.dispose();
1821 }
1822 } while (localBuffer.contentsLost());
1823 listG.drawImage(localBuffer, 0, 0, null);
1824 }
1825
1826 private void paintBackground(Graphics g) {
1827 g.setColor(SystemColor.window);
1828 g.fillRect(0, 0, width, height);
1829 g.setColor(getListBackground());
1830 g.fillRect(0, 0, listWidth, listHeight);
1831 draw3DRect(g, getSystemColors(), 0, 0, listWidth - 1, listHeight - 1, false);
1832 }
1833
1834 private void paintItems(Graphics g, int firstItem, int lastItem, int options) {
1835 if (log.isLoggable(PlatformLogger.FINER)) log.finer("Painting items from " + firstItem + " to " + lastItem + ", focused " + focusIndex + ", first " + getFirstVisibleItem() + ", last " + getLastVisibleItem());
1836
1837 firstItem = Math.max(getFirstVisibleItem(), firstItem);
1838 if (firstItem > lastItem) {
1839 int t = lastItem;
1840 lastItem = firstItem;
1841 firstItem = t;
1842 }
1843 firstItem = Math.max(getFirstVisibleItem(), firstItem);
1844 lastItem = Math.min(lastItem, items.size()-1);
1845
1846 if (log.isLoggable(PlatformLogger.FINER)) log.finer("Actually painting items from " + firstItem + " to " + lastItem +
1847 ", items in window " + itemsInWindow());
1848 for (int i = firstItem; i <= lastItem; i++) {
1849 paintItem(g, i);
1850 }
1851 }
1852
1853 private void paintItem(Graphics g, int index) {
1854 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painting item " + index);
1855 // 4895367 - only paint items which are visible
1856 if (!isItemHidden(index)) {
1857 Shape clip = g.getClip();
1858 int w = getItemWidth();
1859 int h = getItemHeight();
1860 int y = getItemY(index);
1861 int x = getItemX();
1862 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Setting clip " + new Rectangle(x, y, w - (SPACE*2), h-(SPACE*2)));
1863 g.setClip(x, y, w - (SPACE*2), h-(SPACE*2));
1864
1865 // Always paint the background so that focus is unpainted in
1866 // multiselect mode
1867 if (isSelected(index)) {
1868 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painted item is selected");
1869 g.setColor(getListForeground());
1870 } else {
1871 g.setColor(getListBackground());
1872 }
1873 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Filling " + new Rectangle(x, y, w, h));
1874 g.fillRect(x, y, w, h);
1875
1876 if (index <= getLastVisibleItem() && index < items.size()) {
1877 if (!isEnabled()){
1878 g.setColor(getDisabledColor());
1879 } else if (isSelected(index)) {
1880 g.setColor(getListBackground());
1881 } else {
1882 g.setColor(getListForeground());
1883 }
1884 String str = (String)items.elementAt(index);
1885 g.drawString(str, x - hsb.getValue(), y + fontAscent);
1886 } else {
1887 // Clear the remaining area around the item - focus area and the rest of border
1888 g.setClip(x, y, listWidth, h);
1889 g.setColor(getListBackground());
1890 g.fillRect(x, y, listWidth, h);
1891 }
1892 g.setClip(clip);
1893 }
1894 }
1895
1896 void paintScrollBar(XScrollbar scr, Graphics g, int x, int y, int width, int height, boolean paintAll) {
1897 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painting scrollbar " + scr + " width " +
1898 width + " height " + height + ", paintAll " + paintAll);
1899 g.translate(x, y);
1900 scr.paint(g, getSystemColors(), paintAll);
1901 g.translate(-x, -y);
1902 }
1903
1904 /**
1905 * Paint the horizontal scrollbar to the screen
1906 *
1907 * @param g the graphics context to draw into
1908 * @param colors the colors used to draw the scrollbar
1909 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1910 */
1911 void paintHorScrollbar(Graphics g, boolean paintAll) {
1912 int w = getListWidth();
1913 paintScrollBar(hsb, g, 0, height - (SCROLLBAR_WIDTH), w, SCROLLBAR_WIDTH, paintAll);
1914 }
1915
1916 /**
1917 * Paint the vertical scrollbar to the screen
1918 *
1919 * @param g the graphics context to draw into
1920 * @param colors the colors used to draw the scrollbar
1921 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1922 */
1923 void paintVerScrollbar(Graphics g, boolean paintAll) {
1924 int h = height - (hsbVis ? (SCROLLBAR_AREA-2) : 0);
1925 paintScrollBar(vsb, g, width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH - 2, h, paintAll);
1926 }
1927
1928
1929 private Rectangle prevFocusRect;
1930 private void paintFocus(Graphics g, int options) {
1931 boolean paintFocus = (options & PAINT_FOCUS) != 0;
1932 if (paintFocus && !hasFocus()) {
1933 paintFocus = false;
1934 }
1935 if (log.isLoggable(PlatformLogger.FINE)) log.fine("Painting focus, focus index " + getFocusIndex() + ", focus is " +
1936 (isItemHidden(getFocusIndex())?("invisible"):("visible")) + ", paint focus is " + paintFocus);
1937 Shape clip = g.getClip();
1938 g.setClip(0, 0, listWidth, listHeight);
1939 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Setting focus clip " + new Rectangle(0, 0, listWidth, listHeight));
1940 Rectangle rect = getFocusRect();
1941 if (prevFocusRect != null) {
1942 // Erase focus rect
1943 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Erasing previous focus rect " + prevFocusRect);
1944 g.setColor(getListBackground());
1945 g.drawRect(prevFocusRect.x, prevFocusRect.y, prevFocusRect.width, prevFocusRect.height);
1946 prevFocusRect = null;
1947 }
1948 if (paintFocus) {
1949 // Paint new
1950 if (log.isLoggable(PlatformLogger.FINEST)) log.finest("Painting focus rect " + rect);
1951 g.setColor(getListForeground()); // Focus color is always black on Linux
1952 g.drawRect(rect.x, rect.y, rect.width, rect.height);
1953 prevFocusRect = rect;
1954 }
1955 g.setClip(clip);
1956 }
1957 }
1958 }
|
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),
652 mouseEvent.getY());
653 } else if(active == HORSCROLLBAR) {
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 {
837 repaint(PAINT_FOCUS);
838 }
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
1024 } else if ((XHorizontalScrollbar)obj == hsb) {
1025 scrollHorizontal(v - value);
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
1151 // check for end point greater than the size of the list
1152 if (e >= items.size()) {
1153 e = items.size() - 1;
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();
1221 repaintNeeded |= (vsbWasVisible ^ vsbVis) || (hsbWasVisible ^ hsbVis); // If scrollbars visibility changed
1222 if (repaintNeeded) {
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;
1476 }
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 }
1518 repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance);
1519 }
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;
1795 } finally {
1796 XToolkit.awtUnlock();
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 log.finest("Painted item is selected");
1907 g.setColor(getListForeground());
1908 } else {
1909 g.setColor(getListBackground());
1910 }
1911 if (log.isLoggable(PlatformLogger.FINEST)) {
1912 log.finest("Filling " + new Rectangle(x, y, w, h));
1913 }
1914 g.fillRect(x, y, w, h);
1915
1916 if (index <= getLastVisibleItem() && index < items.size()) {
1917 if (!isEnabled()){
1918 g.setColor(getDisabledColor());
1919 } else if (isSelected(index)) {
1920 g.setColor(getListBackground());
1921 } else {
1922 g.setColor(getListForeground());
1923 }
1924 String str = (String)items.elementAt(index);
1925 g.drawString(str, x - hsb.getValue(), y + fontAscent);
1926 } else {
1927 // Clear the remaining area around the item - focus area and the rest of border
1928 g.setClip(x, y, listWidth, h);
1929 g.setColor(getListBackground());
1930 g.fillRect(x, y, listWidth, h);
1931 }
1932 g.setClip(clip);
1933 }
1934 }
1935
1936 void paintScrollBar(XScrollbar scr, Graphics g, int x, int y, int width, int height, boolean paintAll) {
1937 if (log.isLoggable(PlatformLogger.FINEST)) {
1938 log.finest("Painting scrollbar " + scr + " width " +
1939 width + " height " + height + ", paintAll " + paintAll);
1940 }
1941 g.translate(x, y);
1942 scr.paint(g, getSystemColors(), paintAll);
1943 g.translate(-x, -y);
1944 }
1945
1946 /**
1947 * Paint the horizontal scrollbar to the screen
1948 *
1949 * @param g the graphics context to draw into
1950 * @param colors the colors used to draw the scrollbar
1951 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1952 */
1953 void paintHorScrollbar(Graphics g, boolean paintAll) {
1954 int w = getListWidth();
1955 paintScrollBar(hsb, g, 0, height - (SCROLLBAR_WIDTH), w, SCROLLBAR_WIDTH, paintAll);
1956 }
1957
1958 /**
1959 * Paint the vertical scrollbar to the screen
1960 *
1961 * @param g the graphics context to draw into
1962 * @param colors the colors used to draw the scrollbar
1963 * @param paintAll paint the whole scrollbar if true, just the thumb if false
1964 */
1965 void paintVerScrollbar(Graphics g, boolean paintAll) {
1966 int h = height - (hsbVis ? (SCROLLBAR_AREA-2) : 0);
1967 paintScrollBar(vsb, g, width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH - 2, h, paintAll);
1968 }
1969
1970
1971 private Rectangle prevFocusRect;
1972 private void paintFocus(Graphics g, int options) {
1973 boolean paintFocus = (options & PAINT_FOCUS) != 0;
1974 if (paintFocus && !hasFocus()) {
1975 paintFocus = false;
1976 }
1977 if (log.isLoggable(PlatformLogger.FINE)) {
1978 log.fine("Painting focus, focus index " + getFocusIndex() + ", focus is " +
1979 (isItemHidden(getFocusIndex())?("invisible"):("visible")) + ", paint focus is " + paintFocus);
1980 }
1981 Shape clip = g.getClip();
1982 g.setClip(0, 0, listWidth, listHeight);
1983 if (log.isLoggable(PlatformLogger.FINEST)) {
1984 log.finest("Setting focus clip " + new Rectangle(0, 0, listWidth, listHeight));
1985 }
1986 Rectangle rect = getFocusRect();
1987 if (prevFocusRect != null) {
1988 // Erase focus rect
1989 if (log.isLoggable(PlatformLogger.FINEST)) {
1990 log.finest("Erasing previous focus rect " + prevFocusRect);
1991 }
1992 g.setColor(getListBackground());
1993 g.drawRect(prevFocusRect.x, prevFocusRect.y, prevFocusRect.width, prevFocusRect.height);
1994 prevFocusRect = null;
1995 }
1996 if (paintFocus) {
1997 // Paint new
1998 if (log.isLoggable(PlatformLogger.FINEST)) {
1999 log.finest("Painting focus rect " + rect);
2000 }
2001 g.setColor(getListForeground()); // Focus color is always black on Linux
2002 g.drawRect(rect.x, rect.y, rect.width, rect.height);
2003 prevFocusRect = rect;
2004 }
2005 g.setClip(clip);
2006 }
2007 }
2008 }
|