jdk/src/solaris/classes/sun/awt/motif/MCheckboxPeer.java
changeset 1192 715cf9378c53
parent 1051 90cf935adb35
parent 1191 f142c1da78c2
child 1193 41afb8ee8f45
equal deleted inserted replaced
1051:90cf935adb35 1192:715cf9378c53
     1 /*
       
     2  * Copyright 1995-2000 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 
       
    26 package sun.awt.motif;
       
    27 
       
    28 import java.awt.*;
       
    29 import java.awt.peer.*;
       
    30 import java.awt.event.*;
       
    31 
       
    32 public class MCheckboxPeer extends MComponentPeer implements CheckboxPeer {
       
    33     private boolean inUpCall = false;
       
    34     private boolean inInit=false;
       
    35 
       
    36     native void create(MComponentPeer parent);
       
    37     native void pSetState(boolean state);
       
    38     native boolean pGetState();
       
    39 
       
    40     public native void setLabel(String label);
       
    41     public native void setCheckboxGroup(CheckboxGroup g);
       
    42 
       
    43 
       
    44     void initialize() {
       
    45         Checkbox t = (Checkbox)target;
       
    46         inInit=true;
       
    47 
       
    48         setState(t.getState());
       
    49         setCheckboxGroup(t.getCheckboxGroup());
       
    50         super.initialize();
       
    51         inInit=false;
       
    52     }
       
    53 
       
    54     public MCheckboxPeer(Checkbox target) {
       
    55         super(target);
       
    56     }
       
    57 
       
    58     public boolean isFocusable() {
       
    59         return true;
       
    60     }
       
    61 
       
    62     public void setState(boolean state) {
       
    63         if (inInit) {
       
    64                 pSetState(state);
       
    65         } else if (!inUpCall && (state != pGetState())) {
       
    66                 pSetState(state);
       
    67                 // 4135725 : do not notify on programatic changes
       
    68                 // notifyStateChanged(state);
       
    69         }
       
    70     }
       
    71     private native int getIndicatorSize();
       
    72     private native int getSpacing();
       
    73 
       
    74     public Dimension getMinimumSize() {
       
    75         String lbl = ((Checkbox)target).getLabel();
       
    76         if (lbl == null) {
       
    77             lbl = "";
       
    78         }
       
    79         FontMetrics fm = getFontMetrics(target.getFont());
       
    80         /*
       
    81          * Spacing (number of pixels between check mark and label text) is
       
    82          * currently set to 0, but in case it ever changes we have to add
       
    83          * it. 8 is a heuristic number. Indicator size depends on font
       
    84          * height, so we don't need to include it in checkbox's height
       
    85          * calculation.
       
    86          */
       
    87         int wdth = fm.stringWidth(lbl) + getIndicatorSize() + getSpacing() + 8;
       
    88         int hght = Math.max(fm.getHeight() + 8, 15);
       
    89         return new Dimension(wdth, hght);
       
    90     }
       
    91 
       
    92 
       
    93     void notifyStateChanged(boolean state) {
       
    94         Checkbox cb = (Checkbox) target;
       
    95         ItemEvent e = new ItemEvent(cb,
       
    96                           ItemEvent.ITEM_STATE_CHANGED,
       
    97                           cb.getLabel(),
       
    98                           state ? ItemEvent.SELECTED : ItemEvent.DESELECTED);
       
    99         postEvent(e);
       
   100     }
       
   101 
       
   102 
       
   103     // NOTE: This method is called by privileged threads.
       
   104     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
       
   105     void action(boolean state) {
       
   106         final Checkbox cb = (Checkbox)target;
       
   107         final boolean newState = state;
       
   108         MToolkit.executeOnEventHandlerThread(cb, new Runnable() {
       
   109             public void run() {
       
   110                 CheckboxGroup cbg = cb.getCheckboxGroup();
       
   111                 /* Bugid 4039594. If this is the current Checkbox in
       
   112                  * a CheckboxGroup, then return to prevent deselection.
       
   113                  * Otherwise, it's logical state will be turned off,
       
   114                  * but it will appear on.
       
   115                  */
       
   116                 if ((cbg != null) && (cbg.getSelectedCheckbox() == cb) &&
       
   117                     cb.getState()) {
       
   118                   inUpCall = false;
       
   119                   cb.setState(true);
       
   120                   return;
       
   121                 }
       
   122                 // All clear - set the new state
       
   123                 cb.setState(newState);
       
   124                 notifyStateChanged(newState);
       
   125             } // run()
       
   126         });
       
   127     } // action()
       
   128 
       
   129 
       
   130 
       
   131     static final int SIZE = 19;
       
   132     static final int BORDER = 4;
       
   133     static final int SIZ = SIZE - BORDER*2 - 1;
       
   134 
       
   135     /*
       
   136      * Print the native component by rendering the Motif look ourselves.
       
   137      * ToDo(aim): needs to query native motif for more accurate size and
       
   138      * color information; need to render check mark.
       
   139      */
       
   140     public void print(Graphics g) {
       
   141         Checkbox cb = (Checkbox)target;
       
   142         Dimension d = cb.size();
       
   143         Color bg = cb.getBackground();
       
   144         Color fg = cb.getForeground();
       
   145         Color shadow = bg.darker();
       
   146         int x = BORDER;
       
   147         int y = ((d.height - SIZE) / 2) + BORDER;
       
   148 
       
   149         g.setColor(cb.getState()? shadow : bg);
       
   150 
       
   151         if (cb.getCheckboxGroup() != null) {
       
   152             g.fillOval(x, y, SIZ, SIZ);
       
   153             draw3DOval(g, bg, x, y, SIZ, SIZ, !(cb.getState()));
       
   154             if (cb.getState()) {
       
   155                 g.setColor(fg);
       
   156                 g.fillOval(x + 3, y + 3, SIZ - 6, SIZ - 6);
       
   157             }
       
   158         } else {
       
   159             g.fillRect(x, y, SIZ, SIZ);
       
   160             draw3DRect(g, bg, x, y, SIZ, SIZ, !(cb.getState()));
       
   161             if (cb.getState()) {
       
   162                 g.setColor(fg);
       
   163                 g.drawLine(x+1, y+1, x+SIZ-1, y+SIZ-1);
       
   164                 g.drawLine(x+1, y+SIZ-1, x+SIZ-1, y+1);
       
   165             }
       
   166         }
       
   167         g.setColor(fg);
       
   168         String lbl = cb.getLabel();
       
   169         if (lbl != null) {
       
   170             // REMIND: align
       
   171             g.setFont(cb.getFont());
       
   172             FontMetrics fm = g.getFontMetrics();
       
   173             g.drawString(lbl, SIZE,
       
   174                          (d.height + fm.getMaxAscent() - fm.getMaxDescent()) / 2);
       
   175         }
       
   176 
       
   177         target.print(g);
       
   178     }
       
   179 
       
   180     /**
       
   181      * DEPRECATED
       
   182      */
       
   183     public Dimension minimumSize() {
       
   184             return getMinimumSize();
       
   185     }
       
   186 
       
   187 }