Advertisement
Guest User

SWT GifCLabel

a guest
Aug 10th, 2011
665
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 33.65 KB | None | 0 0
  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.InputStream;
  5.  
  6. import org.eclipse.swt.*;
  7. import org.eclipse.swt.widgets.*;
  8. import org.eclipse.swt.graphics.*;
  9. import org.eclipse.swt.events.*;
  10. import org.eclipse.swt.accessibility.*;
  11.  
  12. /**
  13.  * <p><b>This class supports gif animation in label and is derived from {@link GifCLabel} SWT class (see {@link #setGifImage(InputStream)} or {@link #setGifImage(String)})</b><br />
  14.  * <b>Changes by Sorceror, (a)sync.exec(...) call fix by YAMaiDie</b></p>
  15.  * A Label which supports aligned text and/or an image and different border styles.
  16.  * <p>
  17.  * If there is not enough space a CLabel uses the following strategy to fit the
  18.  * information into the available space:
  19.  * <pre>
  20.  *      ignores the indent in left align mode
  21.  *      ignores the image and the gap
  22.  *      shortens the text by replacing the center portion of the label with an ellipsis
  23.  *      shortens the text by removing the center portion of the label
  24.  * </pre>
  25.  * <p>
  26.  * <dl>
  27.  * <dt><b>Styles:</b>
  28.  * <dd>LEFT, RIGHT, CENTER, SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
  29.  * <dt><b>Events:</b>
  30.  * <dd></dd>
  31.  * </dl>
  32.  *
  33.  * </p><p>
  34.  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
  35.  * </p>
  36.  *
  37.  * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: CustomControlExample</a>
  38.  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  39.  * @noextend This class is not intended to be subclassed by clients.
  40.  */
  41. public class GifCLabel extends Canvas {
  42.  
  43.     /** Gap between icon and text */
  44.     private static final int GAP = 5;
  45.     /** Left and right margins */
  46.     private static final int DEFAULT_MARGIN = 3;
  47.     /** a string inserted in the middle of text that has been shortened */
  48.     private static final String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026"
  49.     /** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT*/
  50.     private int align = SWT.LEFT;
  51.     private int leftMargin = DEFAULT_MARGIN;
  52.     private int topMargin = DEFAULT_MARGIN;
  53.     private int rightMargin = DEFAULT_MARGIN;
  54.     private int bottomMargin = DEFAULT_MARGIN;
  55.     /** the current text */
  56.     private String text;
  57.     /** the current icon */
  58.     private Image image;
  59.     // The tooltip is used for two purposes - the application can set
  60.     // a tooltip or the tooltip can be used to display the full text when the
  61.     // the text has been truncated due to the label being too short.
  62.     // The appToolTip stores the tooltip set by the application.  Control.tooltiptext
  63.     // contains whatever tooltip is currently being displayed.
  64.     private String appToolTipText;
  65.     private boolean ignoreDispose;
  66.    
  67.     private Image backgroundImage;
  68.     private Color[] gradientColors;
  69.     private int[] gradientPercents;
  70.     private boolean gradientVertical;
  71.     private Color background;
  72.    
  73.     private GifThread thread = null;
  74.    
  75.     private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;
  76.  
  77. /**
  78.  * Constructs a new instance of this class given its parent
  79.  * and a style value describing its behavior and appearance.
  80.  * <p>
  81.  * The style value is either one of the style constants defined in
  82.  * class <code>SWT</code> which is applicable to instances of this
  83.  * class, or must be built by <em>bitwise OR</em>'ing together
  84.  * (that is, using the <code>int</code> "|" operator) two or more
  85.  * of those <code>SWT</code> style constants. The class description
  86.  * lists the style constants that are applicable to the class.
  87.  * Style bits are also inherited from superclasses.
  88.  * </p>
  89.  *
  90.  * @param parent a widget which will be the parent of the new instance (cannot be null)
  91.  * @param style the style of widget to construct
  92.  *
  93.  * @exception IllegalArgumentException <ul>
  94.  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
  95.  * </ul>
  96.  * @exception SWTException <ul>
  97.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
  98.  * </ul>
  99.  *
  100.  * @see SWT#LEFT
  101.  * @see SWT#RIGHT
  102.  * @see SWT#CENTER
  103.  * @see SWT#SHADOW_IN
  104.  * @see SWT#SHADOW_OUT
  105.  * @see SWT#SHADOW_NONE
  106.  * @see #getStyle()
  107.  */
  108. public GifCLabel(Composite parent, int style) {
  109.     super(parent, checkStyle(style));
  110.     if ((style & (SWT.CENTER | SWT.RIGHT)) == 0) style |= SWT.LEFT;
  111.     if ((style & SWT.CENTER) != 0) align = SWT.CENTER;
  112.     if ((style & SWT.RIGHT) != 0)  align = SWT.RIGHT;
  113.     if ((style & SWT.LEFT) != 0)   align = SWT.LEFT;
  114.    
  115.     addPaintListener(new PaintListener() {
  116.         public void paintControl(PaintEvent event) {
  117.             onPaint(event);
  118.         }
  119.     });
  120.    
  121.     addTraverseListener(new TraverseListener() {
  122.         public void keyTraversed(TraverseEvent event) {
  123.             if (event.detail == SWT.TRAVERSE_MNEMONIC) {
  124.                 onMnemonic(event);
  125.             }
  126.         }
  127.     });
  128.    
  129.     addListener(SWT.Dispose, new Listener() {
  130.         public void handleEvent(Event event) {
  131.             onDispose(event);
  132.         }
  133.     });
  134.    
  135.     initAccessible();
  136.  
  137. }
  138. /**
  139.  * Check the style bits to ensure that no invalid styles are applied.
  140.  */
  141. private static int checkStyle (int style) {
  142.     if ((style & SWT.BORDER) != 0) style |= SWT.SHADOW_IN;
  143.     int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
  144.     style = style & mask;
  145.     return style |= SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED;
  146. }
  147.  
  148. //protected void checkSubclass () {
  149. //  String name = getClass().getName ();
  150. //  String validName = CLabel.class.getName();
  151. //  if (!validName.equals(name)) {
  152. //      SWT.error (SWT.ERROR_INVALID_SUBCLASS);
  153. //  }
  154. //}
  155.  
  156. public Point computeSize(int wHint, int hHint, boolean changed) {
  157.     checkWidget();
  158.     Point e = getTotalSize(image, text);
  159.     if (wHint == SWT.DEFAULT){
  160.         e.x += leftMargin + rightMargin;
  161.     } else {
  162.         e.x = wHint;
  163.     }
  164.     if (hHint == SWT.DEFAULT) {
  165.         e.y += topMargin + bottomMargin;
  166.     } else {
  167.         e.y = hHint;
  168.     }
  169.     return e;
  170. }
  171. /**
  172.  * Draw a rectangle in the given colors.
  173.  */
  174. private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {
  175.     gc.setForeground(bottomright);
  176.     gc.drawLine(x+w, y,   x+w, y+h);
  177.     gc.drawLine(x,   y+h, x+w, y+h);
  178.    
  179.     gc.setForeground(topleft);
  180.     gc.drawLine(x, y, x+w-1, y);
  181.     gc.drawLine(x, y, x,     y+h-1);
  182. }
  183. /*
  184.  * Return the lowercase of the first non-'&' character following
  185.  * an '&' character in the given string. If there are no '&'
  186.  * characters in the given string, return '\0'.
  187.  */
  188. char _findMnemonic (String string) {
  189.     if (string == null) return '\0';
  190.     int index = 0;
  191.     int length = string.length ();
  192.     do {
  193.         while (index < length && string.charAt (index) != '&') index++;
  194.         if (++index >= length) return '\0';
  195.         if (string.charAt (index) != '&') return Character.toLowerCase (string.charAt (index));
  196.         index++;
  197.     } while (index < length);
  198.     return '\0';
  199. }
  200. /**
  201.  * Returns the horizontal alignment.
  202.  * The alignment style (LEFT, CENTER or RIGHT) is returned.
  203.  *
  204.  * @return SWT.LEFT, SWT.RIGHT or SWT.CENTER
  205.  */
  206. public int getAlignment() {
  207.     //checkWidget();
  208.     return align;
  209. }
  210. /**
  211.  * Return the CLabel's bottom margin.
  212.  *
  213.  * @return the bottom margin of the label
  214.  *
  215.  * @since 3.6
  216.  */
  217. public int getBottomMargin() {
  218.     //checkWidget();
  219.     return bottomMargin;
  220. }
  221. /**
  222.  * Return the CLabel's image or <code>null</code>.
  223.  *
  224.  * @return the image of the label or null
  225.  */
  226. public Image getImage() {
  227.     //checkWidget();
  228.     return image;
  229. }
  230. /**
  231.  * Return the CLabel's left margin.
  232.  *
  233.  * @return the left margin of the label
  234.  *
  235.  * @since 3.6
  236.  */
  237. public int getLeftMargin() {
  238.     //checkWidget();
  239.     return leftMargin;
  240. }
  241. /**
  242.  * Return the CLabel's right margin.
  243.  *
  244.  * @return the right margin of the label
  245.  *
  246.  * @since 3.6
  247.  */
  248. public int getRightMargin() {
  249.     //checkWidget();
  250.     return rightMargin;
  251. }
  252. /**
  253.  * Compute the minimum size.
  254.  */
  255. private Point getTotalSize(Image image, String text) {
  256.     Point size = new Point(0, 0);
  257.  
  258.     if (image != null) {
  259.         Rectangle r = image.getBounds();
  260.         size.x += r.width;
  261.         size.y += r.height;
  262.     }
  263.        
  264.     GC gc = new GC(this);
  265.     if (text != null && text.length() > 0) {
  266.         Point e = gc.textExtent(text, DRAW_FLAGS);
  267.         size.x += e.x;
  268.         size.y = Math.max(size.y, e.y);
  269.         if (image != null) size.x += GAP;
  270.     } else {
  271.         size.y = Math.max(size.y, gc.getFontMetrics().getHeight());
  272.     }
  273.     gc.dispose();
  274.    
  275.     return size;
  276. }
  277. public int getStyle () {
  278.     int style = super.getStyle();
  279.     switch (align) {
  280.         case SWT.RIGHT: style |= SWT.RIGHT; break;
  281.         case SWT.CENTER: style |= SWT.CENTER; break;
  282.         case SWT.LEFT: style |= SWT.LEFT; break;
  283.     }
  284.     return style;
  285. }
  286.  
  287. /**
  288.  * Return the Label's text.
  289.  *
  290.  * @return the text of the label or null
  291.  */
  292. public String getText() {
  293.     //checkWidget();
  294.     return text;
  295. }
  296. public String getToolTipText () {
  297.     checkWidget();
  298.     return appToolTipText;
  299. }
  300. /**
  301.  * Return the CLabel's top margin.
  302.  *  
  303.  * @return the top margin of the label
  304.  *
  305.  * @since 3.6
  306.  */
  307. public int getTopMargin() {
  308.     //checkWidget();
  309.     return topMargin;
  310. }
  311. private void initAccessible() {
  312.     Accessible accessible = getAccessible();
  313.     accessible.addAccessibleListener(new AccessibleAdapter() {
  314.         public void getName(AccessibleEvent e) {
  315.             e.result = getText();
  316.         }
  317.        
  318.         public void getHelp(AccessibleEvent e) {
  319.             e.result = getToolTipText();
  320.         }
  321.        
  322.         public void getKeyboardShortcut(AccessibleEvent e) {
  323.             char mnemonic = _findMnemonic(GifCLabel.this.text);
  324.             if (mnemonic != '\0') {
  325.                 e.result = "Alt+"+mnemonic; //$NON-NLS-1$
  326.             }
  327.         }
  328.     });
  329.        
  330.     accessible.addAccessibleControlListener(new AccessibleControlAdapter() {
  331.         public void getChildAtPoint(AccessibleControlEvent e) {
  332.             e.childID = ACC.CHILDID_SELF;
  333.         }
  334.        
  335.         public void getLocation(AccessibleControlEvent e) {
  336.             Rectangle rect = getDisplay().map(getParent(), null, getBounds());
  337.             e.x = rect.x;
  338.             e.y = rect.y;
  339.             e.width = rect.width;
  340.             e.height = rect.height;
  341.         }
  342.        
  343.         public void getChildCount(AccessibleControlEvent e) {
  344.             e.detail = 0;
  345.         }
  346.        
  347.         public void getRole(AccessibleControlEvent e) {
  348.             e.detail = ACC.ROLE_LABEL;
  349.         }
  350.        
  351.         public void getState(AccessibleControlEvent e) {
  352.             e.detail = ACC.STATE_READONLY;
  353.         }
  354.     });
  355. }
  356. void onDispose(Event event) {
  357.     /* make this handler run after other dispose listeners */
  358.     if (ignoreDispose) {
  359.         ignoreDispose = false;
  360.         return;
  361.     }
  362.     ignoreDispose = true;
  363.     notifyListeners (event.type, event);
  364.     event.type = SWT.NONE;
  365.  
  366.     gradientColors = null;
  367.     gradientPercents = null;
  368.     backgroundImage = null;
  369.     text = null;
  370.     image = null;
  371.     appToolTipText = null;
  372. }
  373. void onMnemonic(TraverseEvent event) {
  374.     char mnemonic = _findMnemonic(text);
  375.     if (mnemonic == '\0') return;
  376.     if (Character.toLowerCase(event.character) != mnemonic) return;
  377.     Composite control = this.getParent();
  378.     while (control != null) {
  379.         Control [] children = control.getChildren();
  380.         int index = 0;
  381.         while (index < children.length) {
  382.             if (children [index] == this) break;
  383.             index++;
  384.         }
  385.         index++;
  386.         if (index < children.length) {
  387.             if (children [index].setFocus ()) {
  388.                 event.doit = true;
  389.                 event.detail = SWT.TRAVERSE_NONE;
  390.             }
  391.         }
  392.         control = control.getParent();
  393.     }
  394. }
  395.  
  396. void onPaint(PaintEvent event) {
  397.     Rectangle rect = getClientArea();
  398.     if (rect.width == 0 || rect.height == 0) return;
  399.    
  400.     boolean shortenText = false;
  401.     String t = text;
  402.     Image img = image;
  403.     int availableWidth = Math.max(0, rect.width - (leftMargin + rightMargin));
  404.     Point extent = getTotalSize(img, t);
  405.     if (extent.x > availableWidth) {
  406.         img = null;
  407.         extent = getTotalSize(img, t);
  408.         if (extent.x > availableWidth) {
  409.             shortenText = true;
  410.         }
  411.     }
  412.    
  413.     GC gc = event.gc;
  414.     String[] lines = text == null ? null : splitString(text);
  415.    
  416.     // shorten the text
  417.     if (shortenText) {
  418.         extent.x = 0;
  419.         for(int i = 0; i < lines.length; i++) {
  420.             Point e = gc.textExtent(lines[i], DRAW_FLAGS);
  421.             if (e.x > availableWidth) {
  422.                 lines[i] = shortenText(gc, lines[i], availableWidth);
  423.                 extent.x = Math.max(extent.x, getTotalSize(null, lines[i]).x);
  424.             } else {
  425.                 extent.x = Math.max(extent.x, e.x);
  426.             }
  427.         }
  428.         if (appToolTipText == null) {
  429.             super.setToolTipText(text);
  430.         }
  431.     } else {
  432.         super.setToolTipText(appToolTipText);
  433.     }
  434.        
  435.     // determine horizontal position
  436.     int x = rect.x + leftMargin;
  437.     if (align == SWT.CENTER) {
  438.         x = (rect.width - extent.x)/2;
  439.     }
  440.     if (align == SWT.RIGHT) {
  441.         x = rect.width - rightMargin - extent.x;
  442.     }
  443.    
  444.     // draw a background image behind the text
  445.     try {
  446.         if (backgroundImage != null) {
  447.             // draw a background image behind the text
  448.             Rectangle imageRect = backgroundImage.getBounds();
  449.             // tile image to fill space
  450.             gc.setBackground(getBackground());
  451.             gc.fillRectangle(rect);
  452.             int xPos = 0;
  453.             while (xPos < rect.width) {
  454.                 int yPos = 0;
  455.                 while (yPos < rect.height) {
  456.                     gc.drawImage(backgroundImage, xPos, yPos);
  457.                     yPos += imageRect.height;
  458.                 }
  459.                 xPos += imageRect.width;
  460.             }
  461.         } else if (gradientColors != null) {
  462.             // draw a gradient behind the text
  463.             final Color oldBackground = gc.getBackground();
  464.             if (gradientColors.length == 1) {
  465.                 if (gradientColors[0] != null) gc.setBackground(gradientColors[0]);
  466.                 gc.fillRectangle(0, 0, rect.width, rect.height);
  467.             } else {
  468.                 final Color oldForeground = gc.getForeground();
  469.                 Color lastColor = gradientColors[0];
  470.                 if (lastColor == null) lastColor = oldBackground;
  471.                 int pos = 0;
  472.                 for (int i = 0; i < gradientPercents.length; ++i) {
  473.                     gc.setForeground(lastColor);
  474.                     lastColor = gradientColors[i + 1];
  475.                     if (lastColor == null) lastColor = oldBackground;
  476.                     gc.setBackground(lastColor);
  477.                     if (gradientVertical) {
  478.                         final int gradientHeight = (gradientPercents[i] * rect.height / 100) - pos;
  479.                         gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, true);
  480.                         pos += gradientHeight;
  481.                     } else {
  482.                         final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos;
  483.                         gc.fillGradientRectangle(pos, 0, gradientWidth, rect.height, false);
  484.                         pos += gradientWidth;
  485.                     }
  486.                 }
  487.                 if (gradientVertical && pos < rect.height) {
  488.                     gc.setBackground(getBackground());
  489.                     gc.fillRectangle(0, pos, rect.width, rect.height - pos);
  490.                 }
  491.                 if (!gradientVertical && pos < rect.width) {
  492.                     gc.setBackground(getBackground());
  493.                     gc.fillRectangle(pos, 0, rect.width - pos, rect.height);
  494.                 }
  495.                 gc.setForeground(oldForeground);
  496.             }
  497.             gc.setBackground(oldBackground);
  498.         } else {
  499.             if (background != null || (getStyle() & SWT.DOUBLE_BUFFERED) == 0) {
  500.                 gc.setBackground(getBackground());
  501.                 gc.fillRectangle(rect);
  502.             }
  503.         }
  504.     } catch (SWTException e) {
  505.         if ((getStyle() & SWT.DOUBLE_BUFFERED) == 0) {
  506.             gc.setBackground(getBackground());
  507.             gc.fillRectangle(rect);
  508.         }
  509.     }
  510.  
  511.     // draw border
  512.     int style = getStyle();
  513.     if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0) {
  514.         paintBorder(gc, rect);
  515.     }
  516.  
  517.     /*
  518.      * Compute text height and image height. If image height is more than
  519.      * the text height, draw image starting from top margin. Else draw text
  520.      * starting from top margin.
  521.      */
  522.     Rectangle imageRect = null;
  523.     int lineHeight = 0, textHeight = 0, imageHeight = 0;
  524.    
  525.     if (img != null) {
  526.         imageRect = img.getBounds();
  527.         imageHeight = imageRect.height;
  528.     }
  529.     if (lines != null) {
  530.         lineHeight = gc.getFontMetrics().getHeight();
  531.         textHeight = lines.length * lineHeight;
  532.     }
  533.    
  534.     int imageY = 0, midPoint = 0, lineY = 0;
  535.     if (imageHeight > textHeight ) {
  536.         if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) imageY = rect.y + (rect.height - imageHeight) / 2;
  537.         else imageY = topMargin;
  538.         midPoint = imageY + imageHeight/2;
  539.         lineY = midPoint - textHeight / 2;
  540.     }
  541.     else {
  542.         if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) lineY = rect.y + (rect.height - textHeight) / 2;
  543.         else lineY = topMargin;
  544.         midPoint = lineY + textHeight/2;
  545.         imageY = midPoint - imageHeight / 2;
  546.     }
  547.    
  548.     // draw the image
  549.     if (img != null) {
  550.         gc.drawImage(img, 0, 0, imageRect.width, imageHeight,
  551.                         x, imageY, imageRect.width, imageHeight);
  552.         x +=  imageRect.width + GAP;
  553.         extent.x -= imageRect.width + GAP;
  554.     }
  555.    
  556.     // draw the text
  557.     if (lines != null) {
  558.         gc.setForeground(getForeground());
  559.         for (int i = 0; i < lines.length; i++) {
  560.             int lineX = x;
  561.             if (lines.length > 1) {
  562.                 if (align == SWT.CENTER) {
  563.                     int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
  564.                     lineX = x + Math.max(0, (extent.x - lineWidth) / 2);
  565.                 }
  566.                 if (align == SWT.RIGHT) {
  567.                     int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
  568.                     lineX = Math.max(x, rect.x + rect.width - rightMargin - lineWidth);
  569.                 }
  570.             }
  571.             gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS);
  572.             lineY += lineHeight;
  573.         }
  574.     }
  575. }
  576. /**
  577.  * Paint the Label's border.
  578.  */
  579. private void paintBorder(GC gc, Rectangle r) {
  580.     Display disp= getDisplay();
  581.  
  582.     Color c1 = null;
  583.     Color c2 = null;
  584.    
  585.     int style = getStyle();
  586.     if ((style & SWT.SHADOW_IN) != 0) {
  587.         c1 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
  588.         c2 = disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
  589.     }
  590.     if ((style & SWT.SHADOW_OUT) != 0) {       
  591.         c1 = disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
  592.         c2 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
  593.     }
  594.        
  595.     if (c1 != null && c2 != null) {
  596.         gc.setLineWidth(1);
  597.         drawBevelRect(gc, r.x, r.y, r.width-1, r.height-1, c1, c2);
  598.     }
  599. }
  600. /**
  601.  * Set the horizontal alignment of the CLabel.
  602.  * Use the values LEFT, CENTER and RIGHT to align image and text within the available space.
  603.  *
  604.  * @param align the alignment style of LEFT, RIGHT or CENTER
  605.  *
  606.  * @exception SWTException <ul>
  607.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  608.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  609.  *    <li>ERROR_INVALID_ARGUMENT - if the value of align is not one of SWT.LEFT, SWT.RIGHT or SWT.CENTER</li>
  610.  * </ul>
  611.  */
  612. public void setAlignment(int align) {
  613.     checkWidget();
  614.     if (align != SWT.LEFT && align != SWT.RIGHT && align != SWT.CENTER) {
  615.         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
  616.     }
  617.     if (this.align != align) {
  618.         this.align = align;
  619.         redraw();
  620.     }
  621. }
  622.  
  623. public void setBackground (Color color) {
  624.     super.setBackground (color);
  625.     // Are these settings the same as before?
  626.     if (backgroundImage == null &&
  627.         gradientColors == null &&
  628.         gradientPercents == null) {
  629.         if (color == null) {
  630.             if (background == null) return;
  631.         } else {
  632.             if (color.equals(background)) return;
  633.         }      
  634.     }
  635.     background = color;
  636.     backgroundImage = null;
  637.     gradientColors = null;
  638.     gradientPercents = null;
  639.     redraw ();
  640. }
  641.  
  642. /**
  643.  * Specify a gradient of colours to be drawn in the background of the CLabel.
  644.  * <p>For example, to draw a gradient that varies from dark blue to blue and then to
  645.  * white and stays white for the right half of the label, use the following call
  646.  * to setBackground:</p>
  647.  * <pre>
  648.  *  clabel.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
  649.  *                                 display.getSystemColor(SWT.COLOR_BLUE),
  650.  *                                 display.getSystemColor(SWT.COLOR_WHITE),
  651.  *                                 display.getSystemColor(SWT.COLOR_WHITE)},
  652.  *                     new int[] {25, 50, 100});
  653.  * </pre>
  654.  *
  655.  * @param colors an array of Color that specifies the colors to appear in the gradient
  656.  *               in order of appearance from left to right;  The value <code>null</code>
  657.  *               clears the background gradient; the value <code>null</code> can be used
  658.  *               inside the array of Color to specify the background color.
  659.  * @param percents an array of integers between 0 and 100 specifying the percent of the width
  660.  *                 of the widget at which the color should change; the size of the percents
  661.  *                 array must be one less than the size of the colors array.
  662.  *
  663.  * @exception SWTException <ul>
  664.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  665.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  666.  *    <li>ERROR_INVALID_ARGUMENT - if the values of colors and percents are not consistent</li>
  667.  * </ul>
  668.  */
  669. public void setBackground(Color[] colors, int[] percents) {
  670.     setBackground(colors, percents, false);
  671. }
  672. /**
  673.  * Specify a gradient of colours to be drawn in the background of the CLabel.
  674.  * <p>For example, to draw a gradient that varies from dark blue to white in the vertical,
  675.  * direction use the following call
  676.  * to setBackground:</p>
  677.  * <pre>
  678.  *  clabel.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
  679.  *                                 display.getSystemColor(SWT.COLOR_WHITE)},
  680.  *                       new int[] {100}, true);
  681.  * </pre>
  682.  *
  683.  * @param colors an array of Color that specifies the colors to appear in the gradient
  684.  *               in order of appearance from left/top to right/bottom;  The value <code>null</code>
  685.  *               clears the background gradient; the value <code>null</code> can be used
  686.  *               inside the array of Color to specify the background color.
  687.  * @param percents an array of integers between 0 and 100 specifying the percent of the width/height
  688.  *                 of the widget at which the color should change; the size of the percents
  689.  *                 array must be one less than the size of the colors array.
  690.  * @param vertical indicate the direction of the gradient.  True is vertical and false is horizontal.
  691.  *
  692.  * @exception SWTException <ul>
  693.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  694.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  695.  *    <li>ERROR_INVALID_ARGUMENT - if the values of colors and percents are not consistent</li>
  696.  * </ul>
  697.  *
  698.  * @since 3.0
  699.  */
  700. public void setBackground(Color[] colors, int[] percents, boolean vertical) {  
  701.     checkWidget();
  702.     if (colors != null) {
  703.         if (percents == null || percents.length != colors.length - 1) {
  704.             SWT.error(SWT.ERROR_INVALID_ARGUMENT);
  705.         }
  706.         if (getDisplay().getDepth() < 15) {
  707.             // Don't use gradients on low color displays
  708.             colors = new Color[] {colors[colors.length - 1]};
  709.             percents = new int[] { };
  710.         }
  711.         for (int i = 0; i < percents.length; i++) {
  712.             if (percents[i] < 0 || percents[i] > 100) {
  713.                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
  714.             }
  715.             if (i > 0 && percents[i] < percents[i-1]) {
  716.                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
  717.             }
  718.         }
  719.     }
  720.    
  721.     // Are these settings the same as before?
  722.     final Color background = getBackground();
  723.     if (backgroundImage == null) {
  724.         if ((gradientColors != null) && (colors != null) &&
  725.             (gradientColors.length == colors.length)) {
  726.             boolean same = false;
  727.             for (int i = 0; i < gradientColors.length; i++) {
  728.                 same = (gradientColors[i] == colors[i]) ||
  729.                     ((gradientColors[i] == null) && (colors[i] == background)) ||
  730.                     ((gradientColors[i] == background) && (colors[i] == null));
  731.                 if (!same) break;
  732.             }
  733.             if (same) {
  734.                 for (int i = 0; i < gradientPercents.length; i++) {
  735.                     same = gradientPercents[i] == percents[i];
  736.                     if (!same) break;
  737.                 }
  738.             }
  739.             if (same && this.gradientVertical == vertical) return;
  740.         }
  741.     } else {
  742.         backgroundImage = null;
  743.     }
  744.     // Store the new settings
  745.     if (colors == null) {
  746.         gradientColors = null;
  747.         gradientPercents = null;
  748.         gradientVertical = false;
  749.     } else {
  750.         gradientColors = new Color[colors.length];
  751.         for (int i = 0; i < colors.length; ++i)
  752.             gradientColors[i] = (colors[i] != null) ? colors[i] : background;
  753.         gradientPercents = new int[percents.length];
  754.         for (int i = 0; i < percents.length; ++i)
  755.             gradientPercents[i] = percents[i];
  756.         gradientVertical = vertical;
  757.     }
  758.     // Refresh with the new settings
  759.     redraw();
  760. }
  761. /**
  762.  * Set the image to be drawn in the background of the label.
  763.  *
  764.  * @param image the image to be drawn in the background
  765.  *
  766.  * @exception SWTException <ul>
  767.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  768.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  769.  * </ul>
  770.  */
  771. public void setBackground(Image image) {
  772.     checkWidget();
  773.     if (image == backgroundImage) return;
  774.     if (image != null) {
  775.         gradientColors = null;
  776.         gradientPercents = null;
  777.     }
  778.     backgroundImage = image;
  779.     redraw();
  780.    
  781. }
  782. /**
  783.  * Set the label's bottom margin, in pixels.
  784.  *
  785.  * @param bottomMargin the bottom margin of the label, which must be equal to or greater than zero
  786.  *
  787.  * @exception SWTException <ul>
  788.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  789.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  790.  * </ul>
  791.  *
  792.  * @since 3.6
  793.  */
  794. public void setBottomMargin(int bottomMargin) {
  795.     checkWidget();
  796.     if (this.bottomMargin == bottomMargin || bottomMargin < 0) return;
  797.     this.bottomMargin = bottomMargin;
  798.     redraw();
  799. }
  800. public void setFont(Font font) {
  801.     super.setFont(font);
  802.     redraw();
  803. }
  804. /**
  805.  * Set the label's Image.
  806.  * The value <code>null</code> clears it.
  807.  *
  808.  * @param image the image to be displayed in the label or null
  809.  *
  810.  * @exception SWTException <ul>
  811.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  812.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  813.  * </ul>
  814.  */
  815. public void setImage(Image image) {
  816.     checkWidget();
  817.     if(thread != null) {
  818.         thread.stopRunning();
  819.         try {
  820.             thread.join();
  821.         } catch (InterruptedException e) {
  822.             e.printStackTrace();
  823.         }
  824.     }
  825.    
  826.     if (image != this.image) {
  827.         this.image = image;
  828.         redraw();
  829.     }
  830. }
  831.  
  832. /**
  833.  * Set gif image to label and start gif animation (if any exists)<br />
  834.  * Should be used as <br />
  835.  * <code>label.setGifImage("image.gif")</code>
  836.  * @param path String file path to gif image
  837.  */
  838. public void setGifImage(String path) {
  839.     try {
  840.         this.setGifImage(new FileInputStream(new File(path)));
  841.     } catch (FileNotFoundException e) {
  842.         this.image = null;
  843.         return;
  844.     }
  845. }
  846.  
  847. /**
  848.  * Set gif image to label and start gif animation (if any exists)<br />
  849.  * Should be used as <br />
  850.  * <code>label.setGifImage(this.getClass().getResourceAsStream("/image.gif"))</code>
  851.  * @param inputStream {@link InputStream} gif image stream
  852.  */
  853. public void setGifImage(InputStream inputStream) {
  854.     checkWidget();
  855.     if(thread != null) thread.stopRunning();
  856.    
  857.     ImageLoader loader = new ImageLoader();
  858.    
  859.     try {
  860.         loader.load(inputStream);
  861.     } catch (Exception e) {
  862.         this.image = null;
  863.         return;
  864.     }
  865.  
  866.     if (loader.data[0] != null)
  867.         this.image = new Image(this.getDisplay(), loader.data[0]);
  868.  
  869.     if (loader.data.length > 1) {
  870.         thread = new GifThread(loader);
  871.         thread.start();
  872.     }
  873.  
  874.     redraw();
  875. }
  876.  
  877. /**
  878.  * Dispose method with gif thread stopping correction
  879.  */
  880. @Override
  881. public void dispose() {
  882.     super.dispose();
  883.     if(thread != null) thread.stopRunning();
  884. }
  885.  
  886.  
  887. /**
  888.  * gif image animating thread
  889.  * @author Sorceror
  890.  */
  891. private class GifThread extends Thread {
  892.    
  893.     private int imageNumber = 0;
  894.     private ImageLoader loader = null;
  895.     private boolean run = true;
  896.    
  897.     public GifThread(ImageLoader loader) {
  898.         this.loader = loader;
  899.     }
  900.    
  901.     public void run() {
  902.         while(run) {
  903.             int delayTime = loader.data[imageNumber].delayTime;
  904.             try {
  905.                 Thread.sleep(delayTime * 10);
  906.             } catch (InterruptedException e) {
  907.                 e.printStackTrace();
  908.             }
  909.             if(!GifCLabel.this.isDisposed()) {
  910.                 GifCLabel.this.getDisplay().asyncExec(new Runnable() {
  911.                     public void run() {
  912.                         if(!run){
  913.                             return;
  914.                         }
  915.                         if(!GifCLabel.this.isDisposed()) {
  916.                             imageNumber = imageNumber == loader.data.length - 1 ? 0 : imageNumber + 1;
  917.                             if (!GifCLabel.this.image.isDisposed()) GifCLabel.this.image.dispose();
  918.                             ImageData nextFrameData = loader.data[imageNumber];
  919.                             GifCLabel.this.image = new Image(GifCLabel.this.getDisplay(), nextFrameData);
  920.                             GifCLabel.this.redraw();
  921.                         } else stopRunning();
  922.                     }
  923.                 });
  924.             } else stopRunning();
  925.         }
  926.     }
  927.    
  928.     public void stopRunning() {
  929.         run = false;
  930.     }
  931. }
  932.  
  933. /**
  934.  * Set the label's horizontal left margin, in pixels.
  935.  *
  936.  * @param leftMargin the left margin of the label, which must be equal to or greater than zero
  937.  *
  938.  * @exception SWTException <ul>
  939.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  940.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  941.  * </ul>
  942.  *
  943.  * @since 3.6
  944.  */
  945. public void setLeftMargin(int leftMargin) {
  946.     checkWidget();
  947.     if (this.leftMargin == leftMargin || leftMargin < 0) return;
  948.     this.leftMargin = leftMargin;
  949.     redraw();
  950. }
  951. /**
  952.  * Set the label's margins, in pixels.
  953.  *
  954.  * @param leftMargin the left margin.
  955.  * @param topMargin the top margin.
  956.  * @param rightMargin the right margin.
  957.  * @param bottomMargin the bottom margin.
  958.  * @exception SWTException <ul>
  959.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  960.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  961.  * </ul>
  962.  *
  963.  * @since 3.6
  964.  */
  965. public void setMargins (int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
  966.     checkWidget();
  967.     this.leftMargin = Math.max(0, leftMargin);
  968.     this.topMargin = Math.max(0, topMargin);
  969.     this.rightMargin = Math.max(0, rightMargin);
  970.     this.bottomMargin = Math.max(0, bottomMargin);
  971.     redraw();
  972. }
  973. /**
  974.  * Set the label's right margin, in pixels.
  975.  *
  976.  * @param rightMargin the right margin of the label, which must be equal to or greater than zero
  977.  *
  978.  * @exception SWTException <ul>
  979.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  980.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  981.  * </ul>
  982.  *
  983.  * @since 3.6
  984.  */
  985. public void setRightMargin(int rightMargin) {
  986.     checkWidget();
  987.     if (this.rightMargin == rightMargin || rightMargin < 0) return;
  988.     this.rightMargin = rightMargin;
  989.     redraw();
  990. }
  991. /**
  992.  * Set the label's text.
  993.  * The value <code>null</code> clears it.
  994.  * <p>
  995.  * Mnemonics are indicated by an '&amp;' that causes the next
  996.  * character to be the mnemonic.  When the user presses a
  997.  * key sequence that matches the mnemonic, focus is assigned
  998.  * to the control that follows the label. On most platforms,
  999.  * the mnemonic appears underlined but may be emphasised in a
  1000.  * platform specific manner.  The mnemonic indicator character
  1001.  * '&amp;' can be escaped by doubling it in the string, causing
  1002.  * a single '&amp;' to be displayed.
  1003.  * </p>
  1004.  *
  1005.  * @param text the text to be displayed in the label or null
  1006.  *
  1007.  * @exception SWTException <ul>
  1008.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  1009.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  1010.  * </ul>
  1011.  */
  1012. public void setText(String text) {
  1013.     checkWidget();
  1014.     if (text == null) text = ""; //$NON-NLS-1$
  1015.     if (! text.equals(this.text)) {
  1016.         this.text = text;
  1017.         redraw();
  1018.     }
  1019. }
  1020. public void setToolTipText (String string) {
  1021.     super.setToolTipText (string);
  1022.     appToolTipText = super.getToolTipText();
  1023. }
  1024. /**
  1025.  * Set the label's top margin, in pixels.
  1026.  *
  1027.  * @param topMargin the top margin of the label, which must be equal to or greater than zero
  1028.  *
  1029.  * @exception SWTException <ul>
  1030.  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  1031.  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  1032.  * </ul>
  1033.  *
  1034.  * @since 3.6
  1035.  */
  1036. public void setTopMargin(int topMargin) {
  1037.     checkWidget();
  1038.     if (this.topMargin == topMargin || topMargin < 0) return;
  1039.     this.topMargin = topMargin;
  1040.     redraw();
  1041. }
  1042. /**
  1043.  * Shorten the given text <code>t</code> so that its length doesn't exceed
  1044.  * the given width. The default implementation replaces characters in the
  1045.  * center of the original string with an ellipsis ("...").
  1046.  * Override if you need a different strategy.
  1047.  *
  1048.  * @param gc the gc to use for text measurement
  1049.  * @param t the text to shorten
  1050.  * @param width the width to shorten the text to, in pixels
  1051.  * @return the shortened text
  1052.  */
  1053. protected String shortenText(GC gc, String t, int width) {
  1054.     if (t == null) return null;
  1055.     int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x;
  1056.     if (width<=w) return t;
  1057.     int l = t.length();
  1058.     int max = l/2;
  1059.     int min = 0;
  1060.     int mid = (max+min)/2 - 1;
  1061.     if (mid <= 0) return t;
  1062.     TextLayout layout = new TextLayout (getDisplay());
  1063.     layout.setText(t);
  1064.     mid = validateOffset(layout, mid);
  1065.     while (min < mid && mid < max) {
  1066.         String s1 = t.substring(0, mid);
  1067.         String s2 = t.substring(validateOffset(layout, l-mid), l);
  1068.         int l1 = gc.textExtent(s1, DRAW_FLAGS).x;
  1069.         int l2 = gc.textExtent(s2, DRAW_FLAGS).x;
  1070.         if (l1+w+l2 > width) {
  1071.             max = mid;         
  1072.             mid = validateOffset(layout, (max+min)/2);
  1073.         } else if (l1+w+l2 < width) {
  1074.             min = mid;
  1075.             mid = validateOffset(layout, (max+min)/2);
  1076.         } else {
  1077.             min = max;
  1078.         }
  1079.     }
  1080.     String result = mid == 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(validateOffset(layout, l-mid), l);
  1081.     layout.dispose();
  1082.     return result;
  1083. }
  1084. int validateOffset(TextLayout layout, int offset) {
  1085.     int nextOffset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER);
  1086.     if (nextOffset != offset) return layout.getPreviousOffset(nextOffset, SWT.MOVEMENT_CLUSTER);
  1087.     return offset;
  1088. }
  1089. private String[] splitString(String text) {
  1090.     String[] lines = new String[1];
  1091.     int start = 0, pos;
  1092.     do {
  1093.         pos = text.indexOf('\n', start);
  1094.         if (pos == -1) {
  1095.             lines[lines.length - 1] = text.substring(start);
  1096.         } else {
  1097.             boolean crlf = (pos > 0) && (text.charAt(pos - 1) == '\r');
  1098.             lines[lines.length - 1] = text.substring(start, pos - (crlf ? 1 : 0));
  1099.             start = pos + 1;
  1100.             String[] newLines = new String[lines.length+1];
  1101.             System.arraycopy(lines, 0, newLines, 0, lines.length);
  1102.             lines = newLines;
  1103.         }
  1104.     } while (pos != -1);
  1105.     return lines;
  1106. }
  1107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement