jdk/src/solaris/classes/sun/awt/X11/XListPeer.java
changeset 445 6f717a8cacfb
parent 2 90ce3da70b43
child 3938 ef327bd847c0
equal deleted inserted replaced
444:b40ad157413b 445:6f717a8cacfb
     1 /*
     1 /*
     2  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
    53     public final static int     VERSCROLLBAR = 1;
    53     public final static int     VERSCROLLBAR = 1;
    54     public final static int     HORSCROLLBAR = 2;
    54     public final static int     HORSCROLLBAR = 2;
    55     public final static int     DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,
    55     public final static int     DEFAULT_VISIBLE_ROWS = 4; // From java.awt.List,
    56     public final static int     HORIZ_SCROLL_AMT = 10;
    56     public final static int     HORIZ_SCROLL_AMT = 10;
    57 
    57 
    58     final static int
    58     private final static int    PAINT_VSCROLL = 2;
    59         PAINT_VSCROLL = 2,
    59     private final static int    PAINT_HSCROLL = 4;
    60         PAINT_HSCROLL = 4,
    60     private final static int    PAINT_ITEMS = 8;
    61         PAINT_ITEMS = 8,
    61     private final static int    PAINT_FOCUS = 16;
    62         PAINT_FOCUS = 16,
    62     private final static int    PAINT_BACKGROUND = 32;
    63         PAINT_BACKGROUND = 32,
    63     private final static int    PAINT_HIDEFOCUS = 64;
    64         PAINT_HIDEFOCUS = 64,
    64     private final static int    PAINT_ALL =
    65         PAINT_ALL = PAINT_VSCROLL | PAINT_HSCROLL | PAINT_ITEMS | PAINT_FOCUS | PAINT_BACKGROUND;
    65         PAINT_VSCROLL | PAINT_HSCROLL | PAINT_ITEMS | PAINT_FOCUS | PAINT_BACKGROUND;
       
    66     private final static int    COPY_AREA = 128;
    66 
    67 
    67     XVerticalScrollbar       vsb;
    68     XVerticalScrollbar       vsb;
    68     XHorizontalScrollbar     hsb;
    69     XHorizontalScrollbar     hsb;
    69     ListPainter painter;
    70     ListPainter painter;
    70 
    71 
   361         } else {
   362         } else {
   362             return Math.min(items.size()-1, itemsInWindow()-1);
   363             return Math.min(items.size()-1, itemsInWindow()-1);
   363         }
   364         }
   364     }
   365     }
   365 
   366 
   366     Area getItemsArea(int firstItem, int lastItem) {
       
   367         firstItem = Math.max(getFirstVisibleItem(), firstItem);
       
   368         lastItem = Math.min(lastItem, getLastVisibleItem());
       
   369         if (lastItem < getFirstVisibleItem()) {
       
   370             return new Area();
       
   371         }
       
   372         if (firstItem <= lastItem) {
       
   373             int startY = getItemY(firstItem);
       
   374             int endY = getItemY(lastItem) + getItemHeight();
       
   375             // Account for focus rectangle, instead should be called twice - before change
       
   376             // of focusIndex and after
       
   377             startY -= 2;
       
   378             endY += 2;
       
   379             // x is 0 since we need to account for focus rectangle,
       
   380             // the same with width
       
   381             return new Area(new Rectangle(0, startY, getItemWidth() + 3, endY-startY+1));
       
   382         } else {
       
   383             return new Area();
       
   384         }
       
   385     }
       
   386 
       
   387     Rectangle getItemRect(int item) {
       
   388         return new Rectangle(MARGIN, getItemY(item), getItemWidth(), getItemHeight());
       
   389     }
       
   390 
       
   391     Area getItemArea(int item) {
       
   392         return new Area(getItemRect(item));
       
   393     }
       
   394 
       
   395     public void repaintScrollbarRequest(XScrollbar scrollbar) {
   367     public void repaintScrollbarRequest(XScrollbar scrollbar) {
   396         Graphics g = getGraphics();
   368         Graphics g = getGraphics();
   397         if (scrollbar == hsb)  {
   369         if (scrollbar == hsb)  {
   398             repaint(PAINT_HSCROLL);
   370             repaint(PAINT_HSCROLL);
   399         }
   371         }
   409      */
   381      */
   410     public void repaint() {
   382     public void repaint() {
   411         repaint(getFirstVisibleItem(), getLastVisibleItem(), PAINT_ALL);
   383         repaint(getFirstVisibleItem(), getLastVisibleItem(), PAINT_ALL);
   412     }
   384     }
   413 
   385 
   414     public void repaint(int options) {
   386     private void repaint(int options) {
   415         repaint(getFirstVisibleItem(), getLastVisibleItem(), options);
   387         repaint(getFirstVisibleItem(), getLastVisibleItem(), options);
   416     }
   388     }
   417 
   389 
   418     public void repaint(int firstItem, int lastItem, int options) {
   390     private void repaint(int firstItem, int lastItem, int options) {
       
   391         repaint(firstItem, lastItem, options, null, null);
       
   392     }
       
   393 
       
   394     /**
       
   395      * In most cases the entire area of the component doesn't have
       
   396      * to be repainted. The method repaints the particular areas of
       
   397      * the component. The areas to repaint is specified by the option
       
   398      * parameter. The possible values of the option parameter are:
       
   399      * PAINT_VSCROLL, PAINT_HSCROLL, PAINT_ITEMS, PAINT_FOCUS,
       
   400      * PAINT_HIDEFOCUS, PAINT_BACKGROUND, PAINT_ALL, COPY_AREA.
       
   401      *
       
   402      * Note that the COPY_AREA value initiates copy of a source area
       
   403      * of the component by a distance by means of the copyArea method
       
   404      * of the Graphics class.
       
   405      *
       
   406      * @param firstItem the position of the first item of the range to repaint
       
   407      * @param lastItem the position of the last item of the range to repaint
       
   408      * @param options specifies the particular area of the component to repaint
       
   409      * @param source the area of the component to copy
       
   410      * @param distance the distance to copy the source area
       
   411      */
       
   412     private void repaint(int firstItem, int lastItem, int options, Rectangle source, Point distance) {
   419         Graphics g = getGraphics();
   413         Graphics g = getGraphics();
   420         try {
   414         try {
   421             painter.paint(g, firstItem, lastItem, options);
   415             painter.paint(g, firstItem, lastItem, options, source, distance);
   422         } finally {
   416         } finally {
   423             g.dispose();
   417             g.dispose();
   424         }
   418         }
   425     }
   419     }
   426 
   420 
  1447         if (vsb.getValue() < -y) {
  1441         if (vsb.getValue() < -y) {
  1448             y = -vsb.getValue();
  1442             y = -vsb.getValue();
  1449         }
  1443         }
  1450         vsb.setValue(vsb.getValue() + y);
  1444         vsb.setValue(vsb.getValue() + y);
  1451 
  1445 
       
  1446         Rectangle source = null;
       
  1447         Point distance = null;
       
  1448         int firstItem = 0, lastItem = 0;
       
  1449         int options = PAINT_HIDEFOCUS | PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS;
  1452         if (y > 0) {
  1450         if (y > 0) {
  1453             // Fixed 6308295: XAWTduplicate list item is displayed
  1451             if (y < itemsInWin) {
  1454             // Window resizing leads to the buffer flushing
  1452                 source = new Rectangle(MARGIN, MARGIN + pixelsToScroll, width - SCROLLBAR_AREA, h * (itemsInWin - y - 1)-1);
  1455             // That's why the repainting with the PAINT_HIDEFOCUS option is the repainting with PAINT_ALL option
  1453                 distance = new Point(0, -pixelsToScroll);
  1456             // So we should do only the repainting instead of the copy area
  1454                 options |= COPY_AREA;
  1457             if (y < itemsInWin && painter.isBuffer()) {
  1455             }
  1458                 if (log.isLoggable(Level.FINEST)) {
  1456             firstItem = vsb.getValue() + itemsInWin - y - 1;
  1459                     log.finest("Copying " + "" + MARGIN + "," + ( MARGIN + pixelsToScroll)
  1457             lastItem = vsb.getValue() + itemsInWin - 1;
  1460                                + "," +  (width - SCROLLBAR_AREA) + "," +  (h * (itemsInWin - y)-1) +
  1458 
  1461                                "," + 0 + "," + (-pixelsToScroll));
  1459         } else if (y < 0) {
  1462                 }
       
  1463                 // Unpaint focus before copying
       
  1464                 repaint(PAINT_HIDEFOCUS);
       
  1465                 painter.copyArea(MARGIN, MARGIN + pixelsToScroll, width - SCROLLBAR_AREA, h * (itemsInWin - y - 1)-1, 0, -pixelsToScroll);
       
  1466             }
       
  1467             repaint(vsb.getValue() + (itemsInWin - y)-1, (vsb.getValue() + itemsInWin) - 1, PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS);
       
  1468         } else if (y < 0 && painter.isBuffer()) {
       
  1469             if (y + itemsInWindow() > 0) {
  1460             if (y + itemsInWindow() > 0) {
  1470                 if (log.isLoggable(Level.FINEST)) {
  1461                 source = new Rectangle(MARGIN, MARGIN, width - SCROLLBAR_AREA, h * (itemsInWin + y));
  1471                     log.finest("Copying " + MARGIN + "," + MARGIN +"," +
  1462                 distance = new Point(0, -pixelsToScroll);
  1472                                (width - SCROLLBAR_AREA) + "," +
  1463                 options |= COPY_AREA;
  1473                                (h * (itemsInWin + y)) + "," + "0" +"," +(-pixelsToScroll));
  1464             }
  1474                 }
  1465             firstItem = vsb.getValue();
  1475                 repaint(PAINT_HIDEFOCUS);
  1466             lastItem = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
  1476                 painter.copyArea(MARGIN, MARGIN, width - SCROLLBAR_AREA, h * (itemsInWin + y), 0, -pixelsToScroll);
  1467         }
  1477             }
  1468         repaint(firstItem, lastItem, options, source, distance);
  1478             int e = Math.min(getLastVisibleItem(), vsb.getValue() + -y);
       
  1479             repaint(vsb.getValue(), e, PAINT_ITEMS | PAINT_VSCROLL | PAINT_FOCUS);
       
  1480         }
       
  1481     }
  1469     }
  1482 
  1470 
  1483     /**
  1471     /**
  1484      * scrollHorizontal
  1472      * scrollHorizontal
  1485      * x is the number of pixels to scroll
  1473      * x is the number of pixels to scroll
  1489         int w = getListWidth();
  1477         int w = getListWidth();
  1490         w -= ((2 * SPACE) + (2 * MARGIN));
  1478         w -= ((2 * SPACE) + (2 * MARGIN));
  1491         int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
  1479         int h = height - (SCROLLBAR_AREA + (2 * MARGIN));
  1492         hsb.setValue(hsb.getValue() + x);
  1480         hsb.setValue(hsb.getValue() + x);
  1493 
  1481 
  1494         if (x < 0 && painter.isBuffer()) {
  1482         Rectangle source = null;
  1495             painter.copyArea(MARGIN + SPACE, MARGIN, w + x, h, -x, 0);
  1483         Point distance = null;
  1496         } else if (x > 0 && painter.isBuffer()) {
  1484         if (x < 0) {
  1497             painter.copyArea(MARGIN + SPACE + x, MARGIN, w - x, h, -x, 0);
  1485             source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h);
  1498         }
  1486             distance = new Point(-x, 0);
  1499         repaint(vsb.getValue(), lastItemDisplayed(), PAINT_ITEMS | PAINT_HSCROLL);
  1487         } else if (x > 0) {
       
  1488             source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h);
       
  1489             distance = new Point(-x, 0);
       
  1490         }
       
  1491         int options = COPY_AREA | PAINT_ITEMS | PAINT_HSCROLL;
       
  1492         repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance);
  1500     }
  1493     }
  1501 
  1494 
  1502     /**
  1495     /**
  1503      * return the index
  1496      * return the index
  1504      */
  1497      */
  1675      * Sometimes it is called on other threads:
  1668      * Sometimes it is called on other threads:
  1676      *     Painter -> awtLock
  1669      *     Painter -> awtLock
  1677      * Since we can't guarantee the sequence, use awtLock.
  1670      * Since we can't guarantee the sequence, use awtLock.
  1678      */
  1671      */
  1679     class ListPainter {
  1672     class ListPainter {
  1680         // TODO: use VolatileImage
       
  1681         VolatileImage buffer;
  1673         VolatileImage buffer;
  1682         Color[] colors;
  1674         Color[] colors;
  1683 
  1675 
  1684         private Color getListForeground() {
  1676         private Color getListForeground() {
  1685             if (fgColorSet) {
  1677             if (fgColorSet) {
  1744                 XToolkit.awtUnlock();
  1736                 XToolkit.awtUnlock();
  1745             }
  1737             }
  1746         }
  1738         }
  1747 
  1739 
  1748         private void paint(Graphics listG, int firstItem, int lastItem, int options) {
  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) {
  1749             if (log.isLoggable(Level.FINER)) log.finer("Repaint from " + firstItem + " to " + lastItem + " options " + options);
  1746             if (log.isLoggable(Level.FINER)) log.finer("Repaint from " + firstItem + " to " + lastItem + " options " + options);
  1750             if (firstItem > lastItem) {
  1747             if (firstItem > lastItem) {
  1751                 int t = lastItem;
  1748                 int t = lastItem;
  1752                 lastItem = firstItem;
  1749                 lastItem = firstItem;
  1753                 firstItem = t;
  1750                 firstItem = t;
  1771                 switch (localBuffer.validate(getGraphicsConfiguration())) {
  1768                 switch (localBuffer.validate(getGraphicsConfiguration())) {
  1772                   case VolatileImage.IMAGE_INCOMPATIBLE:
  1769                   case VolatileImage.IMAGE_INCOMPATIBLE:
  1773                       invalidate();
  1770                       invalidate();
  1774                       options = PAINT_ALL;
  1771                       options = PAINT_ALL;
  1775                       continue;
  1772                       continue;
       
  1773                   case VolatileImage.IMAGE_RESTORED:
       
  1774                       options = PAINT_ALL;
  1776                 }
  1775                 }
  1777                 Graphics g = localBuffer.createGraphics();
  1776                 Graphics g = localBuffer.createGraphics();
  1778 
  1777 
       
  1778                 // Note that the order of the following painting operations
       
  1779                 // should not be modified
  1779                 try {
  1780                 try {
  1780                     g.setFont(getFont());
  1781                     g.setFont(getFont());
       
  1782 
       
  1783                     // hiding the focus rectangle must be done prior to copying
       
  1784                     // area and so this is the first action to be performed
       
  1785                     if ((options & (PAINT_HIDEFOCUS)) != 0) {
       
  1786                         paintFocus(g, PAINT_HIDEFOCUS);
       
  1787                     }
       
  1788                     /*
       
  1789                      * The shift of the component contents occurs while someone
       
  1790                      * scrolls the component, the only purpose of the shift is to
       
  1791                      * increase the painting performance. The shift should be done
       
  1792                      * prior to painting any area (except hiding focus) and actually
       
  1793                      * it should never be done jointly with erase background.
       
  1794                      */
       
  1795                     if ((options & COPY_AREA) != 0) {
       
  1796                         g.copyArea(source.x, source.y, source.width, source.height,
       
  1797                             distance.x, distance.y);
       
  1798                     }
  1781                     if ((options & PAINT_BACKGROUND) != 0) {
  1799                     if ((options & PAINT_BACKGROUND) != 0) {
  1782                         g.setColor(SystemColor.window);
  1800                         paintBackground(g);
  1783                         g.fillRect(0, 0, width, height);
       
  1784                         g.setColor(getListBackground());
       
  1785                         g.fillRect(0, 0, listWidth, listHeight);
       
  1786                         draw3DRect(g, getSystemColors(), 0, 0, listWidth - 1, listHeight - 1, false);
       
  1787                         // Since we made full erase update items
  1801                         // Since we made full erase update items
  1788                         firstItem = getFirstVisibleItem();
  1802                         firstItem = getFirstVisibleItem();
  1789                         lastItem = getLastVisibleItem();
  1803                         lastItem = getLastVisibleItem();
  1790                     }
  1804                     }
  1791                     if ((options & PAINT_ITEMS) != 0) {
  1805                     if ((options & PAINT_ITEMS) != 0) {
  1797                     }
  1811                     }
  1798                     if ((options & PAINT_HSCROLL) != 0 && hsbVis) {
  1812                     if ((options & PAINT_HSCROLL) != 0 && hsbVis) {
  1799                         g.setClip(getHScrollBarRec());
  1813                         g.setClip(getHScrollBarRec());
  1800                         paintHorScrollbar(g, true);
  1814                         paintHorScrollbar(g, true);
  1801                     }
  1815                     }
  1802                     if ((options & (PAINT_FOCUS|PAINT_HIDEFOCUS)) != 0) {
  1816                     if ((options & (PAINT_FOCUS)) != 0) {
  1803                         paintFocus(g, options);
  1817                         paintFocus(g, PAINT_FOCUS);
  1804                     }
  1818                     }
  1805                 } finally {
  1819                 } finally {
  1806                     g.dispose();
  1820                     g.dispose();
  1807                 }
  1821                 }
  1808             } while (localBuffer.contentsLost());
  1822             } while (localBuffer.contentsLost());
  1809             listG.drawImage(localBuffer, 0, 0, null);
  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);
  1810         }
  1832         }
  1811 
  1833 
  1812         private void paintItems(Graphics g, int firstItem, int lastItem, int options) {
  1834         private void paintItems(Graphics g, int firstItem, int lastItem, int options) {
  1813             if (log.isLoggable(Level.FINER)) log.finer("Painting items from " + firstItem + " to " + lastItem + ", focused " + focusIndex + ", first " + getFirstVisibleItem() + ", last " + getLastVisibleItem());
  1835             if (log.isLoggable(Level.FINER)) log.finer("Painting items from " + firstItem + " to " + lastItem + ", focused " + focusIndex + ", first " + getFirstVisibleItem() + ", last " + getLastVisibleItem());
  1814 
  1836 
  1930                 g.drawRect(rect.x, rect.y, rect.width, rect.height);
  1952                 g.drawRect(rect.x, rect.y, rect.width, rect.height);
  1931                 prevFocusRect = rect;
  1953                 prevFocusRect = rect;
  1932             }
  1954             }
  1933             g.setClip(clip);
  1955             g.setClip(clip);
  1934         }
  1956         }
  1935 
       
  1936         public void copyArea(int x, int y, int width, int height, int dx, int dy) {
       
  1937             if (log.isLoggable(Level.FINER)) log.finer("Copying area " + x + ", " + y + " " + width +
       
  1938                                                        "x" + height + ", (" + dx + "," + dy + ")");
       
  1939             VolatileImage localBuffer = null;
       
  1940             do {
       
  1941                 XToolkit.awtLock();
       
  1942                 try {
       
  1943                     if (createBuffer()) {
       
  1944                         // Newly created buffer should be painted over at full
       
  1945                         repaint(PAINT_ALL);
       
  1946                         return;
       
  1947                     }
       
  1948                     localBuffer = buffer;
       
  1949                 } finally {
       
  1950                     XToolkit.awtUnlock();
       
  1951                 }
       
  1952                 switch (localBuffer.validate(getGraphicsConfiguration())) {
       
  1953                   case VolatileImage.IMAGE_INCOMPATIBLE:
       
  1954                       invalidate();
       
  1955                   case VolatileImage.IMAGE_RESTORED:
       
  1956                       // Since we've lost the content we can't just scroll - we should paint again
       
  1957                       repaint(PAINT_ALL);
       
  1958                       return;
       
  1959                 }
       
  1960                 Graphics g = localBuffer.createGraphics();
       
  1961                 try {
       
  1962                     g.copyArea(x, y, width, height, dx, dy);
       
  1963                 } finally {
       
  1964                     g.dispose();
       
  1965                 }
       
  1966             } while (localBuffer.contentsLost());
       
  1967             Graphics listG = getGraphics();
       
  1968             listG.setClip(x, y, width, height);
       
  1969             listG.drawImage(localBuffer, 0, 0, null);
       
  1970             listG.dispose();
       
  1971         }
       
  1972 
       
  1973         public boolean isBuffer() {
       
  1974             boolean isBuffer;
       
  1975             XToolkit.awtLock();
       
  1976             try {
       
  1977                 isBuffer = (buffer != null);
       
  1978             } finally {
       
  1979                 XToolkit.awtUnlock();
       
  1980             }
       
  1981             return isBuffer;
       
  1982         }
       
  1983     }
  1957     }
  1984 }
  1958 }