jdk/src/solaris/classes/sun/awt/motif/MListPeer.java
changeset 1203 3e5496df0d2b
parent 1202 5a725d2f0daa
parent 1201 e87f9c042699
child 1211 b659a7cee935
equal deleted inserted replaced
1202:5a725d2f0daa 1203:3e5496df0d2b
     1 /*
       
     2  * Copyright 1995-2004 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 package sun.awt.motif;
       
    26 
       
    27 import java.awt.*;
       
    28 import java.awt.peer.*;
       
    29 import java.awt.event.ActionEvent;
       
    30 import java.awt.event.ItemEvent;
       
    31 import java.awt.event.MouseEvent;
       
    32 import java.awt.event.MouseWheelEvent;
       
    33 
       
    34 class MListPeer extends MComponentPeer implements ListPeer {
       
    35     native void create(MComponentPeer parent);
       
    36 
       
    37     void initialize() {
       
    38         List li = (List)target;
       
    39 
       
    40         /* add any items that were already inserted in the target. */
       
    41         int  nitems = li.countItems();
       
    42         for (int i = 0; i < nitems; i++) {
       
    43             addItem(li.getItem(i), -1);
       
    44         }
       
    45 
       
    46         /* set whether this list should allow multiple selections. */
       
    47         setMultipleSelections(li.allowsMultipleSelections());
       
    48 
       
    49         /* make the visible position visible. */
       
    50         int index = li.getVisibleIndex();
       
    51         if (index >= 0) {
       
    52             makeVisible(index);
       
    53         }
       
    54 
       
    55         /* select the item if necessary. */
       
    56         int sel[] = li.getSelectedIndexes();
       
    57         for (int i = 0 ; i < sel.length ; i++) {
       
    58             select(sel[i]);
       
    59         }
       
    60 
       
    61         /* BugID 4060345 to avoid showing scrollbar in empty List */
       
    62         if (nitems == 0) {
       
    63             addItem(" ", 0);
       
    64             delItems(0, 0);
       
    65         }
       
    66         super.pSetScrollbarBackground(getParent_NoClientCode(li).getBackground());
       
    67 
       
    68         if (!target.isBackgroundSet()) {
       
    69             target.setBackground(SystemColor.text);
       
    70         }
       
    71         if (!target.isForegroundSet()) {
       
    72             target.setForeground(SystemColor.textText);
       
    73         }
       
    74 
       
    75         super.initialize();
       
    76     }
       
    77 
       
    78     MListPeer(List target) {
       
    79         super(target);
       
    80     }
       
    81 
       
    82     /* New method name for 1.1 */
       
    83     public void add(String item, int index) {
       
    84         addItem(item, index);
       
    85     }
       
    86 
       
    87     /* New method name for 1.1 */
       
    88     public void removeAll() {
       
    89         clear();
       
    90     }
       
    91 
       
    92     /* New method name for 1.1 */
       
    93     public void setMultipleMode (boolean b) {
       
    94         setMultipleSelections(b);
       
    95     }
       
    96 
       
    97     /* New method name for 1.1 */
       
    98     public Dimension getPreferredSize(int rows) {
       
    99         return preferredSize(rows);
       
   100     }
       
   101 
       
   102     /* New method name for 1.1 */
       
   103     public Dimension getMinimumSize(int rows) {
       
   104         return minimumSize(rows);
       
   105     }
       
   106 
       
   107     public void setForeground(Color c) {
       
   108         pSetInnerForeground(c);
       
   109     }
       
   110 
       
   111     public native void setBackground(Color c);
       
   112     public native void setMultipleSelections(boolean v);
       
   113     public native boolean isSelected(int index);
       
   114     public native void addItem(String item, int index);
       
   115     public native void delItems(int start, int end);
       
   116     public native void select(int index);
       
   117     public native void deselect(int index);
       
   118     public native void makeVisible(int index);
       
   119 
       
   120     public void clear() {
       
   121         List l = (List)target;
       
   122         int count = l.countItems();
       
   123         if (count > 0) {
       
   124             delItems(0, count-1);
       
   125         }
       
   126     }
       
   127 
       
   128     public int[] getSelectedIndexes() {
       
   129         List l = (List)target;
       
   130         int len = l.countItems();
       
   131         int sel[] = new int[len];
       
   132         int nsel = 0;
       
   133         for (int i = 0 ; i < len ; i++) {
       
   134             if (isSelected(i)) {
       
   135                 sel[nsel++] = i;
       
   136             }
       
   137         }
       
   138         int selected[] = new int[nsel];
       
   139         System.arraycopy(sel, 0, selected, 0, nsel);
       
   140         return selected;
       
   141     }
       
   142 
       
   143     // NOTE: This method may be called by privileged threads.
       
   144     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
       
   145     public void action(int index, final long when, final int modifiers) {
       
   146         final List list = (List)target;
       
   147         final int selectIndex = index;
       
   148 
       
   149         MToolkit.executeOnEventHandlerThread(list, new Runnable() {
       
   150             public void run() {
       
   151                 list.select(selectIndex);
       
   152                 postEvent(new ActionEvent(target, ActionEvent.ACTION_PERFORMED,
       
   153                                           list.getItem(selectIndex), when,
       
   154                                           modifiers));
       
   155             }
       
   156         });
       
   157     } // action()
       
   158 
       
   159     // NOTE: This method may be called by privileged threads.
       
   160     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
       
   161     public void handleListChanged(int index) {
       
   162         final MListPeer listPeer = this;
       
   163         final List list = (List)target;
       
   164         final int listIndex = index;
       
   165 
       
   166         MToolkit.executeOnEventHandlerThread(list, new Runnable() {
       
   167             public void run() {
       
   168                 int selected[] = listPeer.getSelectedIndexes();
       
   169                 boolean isSelected = false;
       
   170 
       
   171                 for (int i=0; i < selected.length; i++) {
       
   172                     if (listIndex == selected[i]) {
       
   173                         isSelected = true;
       
   174                         break;
       
   175                     }
       
   176                 }
       
   177                 postEvent(new ItemEvent(list, ItemEvent.ITEM_STATE_CHANGED,
       
   178                                 Integer.valueOf(listIndex),
       
   179                                 isSelected? ItemEvent.SELECTED : ItemEvent.DESELECTED));
       
   180 
       
   181             }
       
   182         });
       
   183     } // handleListChanged()
       
   184 
       
   185     public Dimension minimumSize() {
       
   186         return minimumSize(4);
       
   187     }
       
   188 
       
   189     public Dimension preferredSize(int v) {
       
   190         return minimumSize(v);
       
   191     }
       
   192 
       
   193     public Dimension minimumSize(int v) {
       
   194         FontMetrics fm = getFontMetrics(((List)target).getFont());
       
   195         return new Dimension(SCROLLBAR + 2*MARGIN +
       
   196                              fm.stringWidth("0123456789abcde"),
       
   197                              ((fm.getHeight()+2*SPACE) * v) +
       
   198                              2*MARGIN);
       
   199     }
       
   200 
       
   201     public boolean isFocusable() {
       
   202         return true;
       
   203     }
       
   204 
       
   205     /*
       
   206      * Print the native component by rendering the Motif look ourselves.
       
   207      * ToDo(aim): needs to query native motif for more accurate size and
       
   208      * color information, selected items, and item offset.
       
   209      */
       
   210     final static int    MARGIN = 2;
       
   211     final static int    SPACE = 1;
       
   212     final static int    SCROLLBAR = 16;
       
   213     int fontHeight;
       
   214     int fontAscent;
       
   215     int fontLeading;
       
   216     int vval;
       
   217     int hval;
       
   218     int vmax;
       
   219     int hmax;
       
   220 
       
   221     public void print(Graphics g) {
       
   222         List l = (List)target;
       
   223         Dimension d = l.size();
       
   224         Color bg = l.getBackground();
       
   225         Color fg = l.getForeground();
       
   226         int numItems = l.getItemCount();
       
   227         FontMetrics fm = getFontMetrics(l.getFont());
       
   228         int w, h;
       
   229         int vvis, hvis, vmin, hmin;
       
   230         int max = 0;
       
   231 
       
   232         for (int i = 0; i < numItems; i++) {
       
   233             int len = fm.stringWidth(l.getItem(i));
       
   234             max = Math.max(max, len);
       
   235         }
       
   236 
       
   237         fontHeight = fm.getHeight();
       
   238         fontAscent = fm.getAscent();
       
   239         fontLeading = fm.getLeading();
       
   240 
       
   241         hmin = vmin = 0;
       
   242 
       
   243         vvis = itemsInWindow(true);
       
   244         vmax = Math.max(numItems - vvis, 0);
       
   245         h = d.height - SCROLLBAR;
       
   246 
       
   247         if (vmax != 0) {
       
   248             w = d.width - SCROLLBAR;
       
   249             hvis = w - ((2 * SPACE) + (2 * MARGIN));
       
   250             hmax = Math.max(max - hvis, 0);
       
   251         } else {
       
   252             w = d.width;
       
   253             hvis = w - ((2 * SPACE) + (2 * MARGIN));
       
   254             hmax = Math.max(max - hvis, 0);
       
   255         }
       
   256         if (hmax == 0) {
       
   257             h = d.height;
       
   258             vvis = itemsInWindow(false);
       
   259             vmax = Math.max(numItems - vvis, 0);
       
   260         }
       
   261         if (vmax == 0) {
       
   262             w = d.width;
       
   263             hvis = w - ((2 * SPACE) + (2 * MARGIN));
       
   264             hmax = Math.max(max - hvis, 0);
       
   265         }
       
   266 
       
   267         hval = 0;
       
   268         vval = 0;
       
   269         /*
       
   270 System.out.println("print List: "+d.width+"x"+d.height+" numItems="+numItems+
       
   271 "max="+max+" vsb=("+vmin+".."+vmax+","+vval+","+vvis+
       
   272 ") hsb=("+hmin+".."+hmax+","+hval+","+hvis+")");
       
   273 */
       
   274 
       
   275         g.setColor(bg);
       
   276         g.fillRect(0, 0, w, h);
       
   277 
       
   278         if (hmax != 0) {
       
   279             int sbw = d.width - ((vmax == 0) ? 0 : SCROLLBAR);
       
   280             g.fillRect(1, d.height - SCROLLBAR - 3, sbw - 1, SCROLLBAR - 3);
       
   281             Graphics ng = g.create();
       
   282             try {
       
   283                 ng.translate(0, d.height - (SCROLLBAR - 2));
       
   284                 drawScrollbar(ng, bg, SCROLLBAR - 2, sbw,
       
   285                                hmin, hmax, hval, hvis, true);
       
   286             } finally {
       
   287                 ng.dispose();
       
   288             }
       
   289         }
       
   290         if (vmax != 0) {
       
   291             int sbh = d.height - ((hmax == 0) ? 0 : SCROLLBAR);
       
   292             g.fillRect(d.width - SCROLLBAR - 3, 1, SCROLLBAR - 3, sbh - 1);
       
   293             Graphics ng = g.create();
       
   294             try {
       
   295                 ng.translate(d.width - (SCROLLBAR - 2), 0);
       
   296                 drawScrollbar(ng, bg, SCROLLBAR - 2, sbh,
       
   297                                vmin, vmax, vval, vvis, false);
       
   298             } finally {
       
   299                 ng.dispose();
       
   300             }
       
   301         }
       
   302 
       
   303         draw3DRect(g, bg, 0, 0, w - 1, h - 1, false);
       
   304 
       
   305         if (numItems > 0) {
       
   306             int n = itemsInWindow(hmax != 0);
       
   307             int e = Math.min(numItems - 1, (vval + n) - 1);
       
   308             paintItems(g, bg, fg, vval, e);
       
   309         }
       
   310 
       
   311         target.print(g);
       
   312     }
       
   313 
       
   314     int itemsInWindow(boolean scrollbarVisible) {
       
   315         Dimension d = target.size();
       
   316         int h;
       
   317         if (scrollbarVisible) {
       
   318             h = d.height - ((2 * MARGIN) + SCROLLBAR);
       
   319         } else {
       
   320             h = d.height - 2*MARGIN;
       
   321         }
       
   322         int i = fontHeight - fontLeading;
       
   323         return h / (i + (2 * SPACE));
       
   324     }
       
   325 
       
   326     void paintItem(Graphics g, Color bg, Color fg, int index, boolean isSelected) {
       
   327         List l = (List)target;
       
   328         Dimension d = l.size();
       
   329         int numItems = l.getItemCount();
       
   330         Color shadow = bg.darker();
       
   331 
       
   332         if ((index < vval) || (index >= (vval + itemsInWindow(hmax != 0)))) {
       
   333             return;
       
   334         }
       
   335         int w = d.width - ((2 * MARGIN) + ((vmax != 0)? SCROLLBAR : 0));
       
   336         int h = (fontHeight - fontLeading);
       
   337         int htotal = h + (2 * SPACE);
       
   338         int index2y = MARGIN + (index * htotal) + SPACE;
       
   339         int y = index2y - (vval * htotal);
       
   340         int x = MARGIN + SPACE;
       
   341         Graphics ng = g.create();
       
   342         try {
       
   343             if (index > numItems - 1) {
       
   344                 ng.setColor(bg);
       
   345                 ng.fillRect(x - 2, y - 2, w, h + 4);
       
   346                 return;
       
   347             }
       
   348             if (isSelected) {
       
   349                 ng.setColor(shadow);
       
   350                 ng.fillRect(x - 1, y - 1, w - 2, h + 2);
       
   351             } else {
       
   352                 ng.setColor(bg);
       
   353                 ng.fillRect(x - 1, y - 1, w - 2, h + 2);
       
   354             }
       
   355             ng.setColor(bg);
       
   356 
       
   357             ng.drawRect(x - 2, y - 2, w - 1, h + 3);
       
   358             ng.setColor(fg);
       
   359             String str = (String)l.getItem(index);
       
   360             ng.clipRect(x, y, w - (2 * SPACE), h);
       
   361             ng.drawString(str, x - hval, y + fontAscent);
       
   362         } finally {
       
   363             ng.dispose();
       
   364         }
       
   365     }
       
   366 
       
   367     void paintItems(Graphics g, Color bg, Color fg, int s, int e) {
       
   368         for (int i = s ; i <= e ; i++) {
       
   369           paintItem(g, bg, fg, i, false);
       
   370         }
       
   371     }
       
   372 
       
   373     public boolean handlesWheelScrolling() {return true;}
       
   374 
       
   375     public void handleEvent(AWTEvent e) {
       
   376         if (e.getID() == MouseEvent.MOUSE_WHEEL) {
       
   377             MouseWheelEvent mwe = (MouseWheelEvent)e;
       
   378             nativeHandleMouseWheel(mwe.getScrollType(),
       
   379                                    mwe.getScrollAmount(),
       
   380                                    mwe.getWheelRotation());
       
   381         }
       
   382         else {
       
   383             super.handleEvent(e);
       
   384         }
       
   385     }
       
   386 
       
   387     native void nativeHandleMouseWheel(int scrollType,
       
   388                                        int scrollAmount,
       
   389                                        int wheelRotation);
       
   390 }