⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sizegrip.java

📁 采用java SWT图形库的特效代码
💻 JAVA
字号:
/*******************************************************************************
 * Copyright (c) 2004 Stefan Zeiger and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.novocode.com/legal/epl-v10.html
 * 
 * Contributors:
 *     Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
 *******************************************************************************/

package com.novocode.naf.swt.custom;

import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;


/**
 * A non-native size grip which looks (and almost feels) like the native Win32 size grip.
 * <p>
 * The SHADOW_IN style causes highlight lines to be drawn at the right and bottom border.
 * This style should be used when placing the size grip on top of the bottom right corner
 * of a FramedComposite with style SHADOW_IN. If the FLAT style is set, the size grip is
 * drawn in a Windows XP style instead of the normal Windows Classic style.
 * </p><p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>SHADOW_IN, FLAT</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * </p><p>
 * NOTE: The visibility of this widget is controlled by the "maximized" state of the
 * shell. The size grip is hidden when the shell is maximized, even if it has been made
 * visible by calling <code>setVisible(true)</code>. getVisible() always returns
 * the value set with setVisible(). isVisible() returns the true visibility, as usual.
 * </p>
 * 
 * <p>New in 1.6: Smoother resizing for a more native look & feel. The window size is
 * not updated more than once every 25ms to reduce the number of unnecessary repaints.</p>
 * 
 * <p>New in 1.8: You can specify a parent Composite other than the shell which will be
 * resized by the SizeGrip.</p>
 *
 * @author Stefan Zeiger (szeiger@novocode.com)
 * @since Mar 8, 2004
 * @version $Id: SizeGrip.java,v 1.9 2005/01/24 21:52:14 szeiger Exp $
 */

public final class SizeGrip extends Canvas
{
  private static final int WIDTH  = 13;
  private static final int HEIGHT = 13;
  private static final long UPDATE_DELAY = 25;
  
  private int mouseDownOffsetX, mouseDownOffsetY, snapBackX, snapBackY;
  private boolean cancelled;
  private Cursor sizeCursor;
  private Point minSize;
  private boolean userVisible = true;
  private volatile long lastUpdate;
  private Timer timer = new Timer(true);
  private TimerTask timerTask;
  private Composite resizableParent;


  public SizeGrip(Composite parent, int style)
  {
    this(parent, parent.getShell(), style);
  }


  public SizeGrip(Composite parent, final Composite resizableParent, int style)
  {
    super(parent, style = checkStyle (style));
    this.resizableParent = resizableParent;
    setSize(WIDTH, HEIGHT);

    sizeCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZENWSE);
    setCursor(sizeCursor);

    addListener(SWT.Dispose, new Listener()
    {
      public void handleEvent(Event e)
      {
        if(sizeCursor != null)
        {
          sizeCursor.dispose();
          sizeCursor = null;
        }
      }
    });

    addListener(SWT.Paint, new Listener()
    {
      public void handleEvent(Event event)
      {
        Rectangle r = getClientArea();
        if(r.width == 0 || r.height == 0) return;
    
        Display disp = getDisplay();
        Color shadow = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
        Color highlight = disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);

        event.gc.setLineWidth(1);

        if((getStyle() & SWT.FLAT) != 0)
        {
          event.gc.setBackground(highlight);
          event.gc.fillRectangle(r.width-3, r.height-3, 2, 2);
          event.gc.fillRectangle(r.width-7, r.height-3, 2, 2);
          event.gc.fillRectangle(r.width-11, r.height-3, 2, 2);
          event.gc.fillRectangle(r.width-3, r.height-7, 2, 2);
          event.gc.fillRectangle(r.width-7, r.height-7, 2, 2);
          event.gc.fillRectangle(r.width-3, r.height-11, 2, 2);
          event.gc.setBackground(shadow);
          event.gc.fillRectangle(r.width-4, r.height-4, 2, 2);
          event.gc.fillRectangle(r.width-8, r.height-4, 2, 2);
          event.gc.fillRectangle(r.width-12, r.height-4, 2, 2);
          event.gc.fillRectangle(r.width-4, r.height-8, 2, 2);
          event.gc.fillRectangle(r.width-8, r.height-8, 2, 2);
          event.gc.fillRectangle(r.width-4, r.height-12, 2, 2);
          event.gc.setForeground(highlight);
        }
        else
        {
          event.gc.setForeground(shadow);
          event.gc.drawLine(r.width-3, r.height-2, r.width-2, r.height-3);
          event.gc.drawLine(r.width-4, r.height-2, r.width-2, r.height-4);
          event.gc.drawLine(r.width-7, r.height-2, r.width-2, r.height-7);
          event.gc.drawLine(r.width-8, r.height-2, r.width-2, r.height-8);
          event.gc.drawLine(r.width-11, r.height-2, r.width-2, r.height-11);
          event.gc.drawLine(r.width-12, r.height-2, r.width-2, r.height-12);
  
          event.gc.setForeground(highlight);
          event.gc.drawLine(r.width-5, r.height-2, r.width-2, r.height-5);
          event.gc.drawLine(r.width-9, r.height-2, r.width-2, r.height-9);
          event.gc.drawLine(r.width-13, r.height-2, r.width-2, r.height-13);
        }
        
        if((getStyle() & SWT.SHADOW_IN) != 0)
        {
          if(event.width > WIDTH) event.gc.drawLine(0, r.height-1, r.width-14, r.height-1);
          if(event.height > HEIGHT) event.gc.drawLine(r.width-1, 0, r.width-1, r.height-14);
        }
      }
    });

    addListener(SWT.MouseDown, new Listener()
    {
      public void handleEvent(Event event)
      {
        if(event.button == 1)
        {
          mouseDownOffsetX = event.x;
          mouseDownOffsetY = event.y;
          Point p = resizableParent.getSize();
          snapBackX = p.x;
          snapBackY = p.y;
          cancelled = false;
          //System.out.println("x="+mouseDownOffsetX+", y="+mouseDownOffsetY);
        }
        else if(event.button == 3 && (event.stateMask & SWT.BUTTON1) != 0) // chord click
        {
          if(snapBackX > 0 && snapBackY > 0)
          {
            resizableParent.setSize(snapBackX, snapBackY);
            snapBackX = 0;
            snapBackY = 0;
            cancelled = true;
          }
        }
      }
    });

    addListener(SWT.MouseMove, new Listener()
    {
      public void handleEvent(final Event event)
      {
        if(!cancelled && (event.stateMask & SWT.BUTTON1) != 0)
        {
          if(timerTask != null)
          {
            timerTask.cancel();
            timerTask = null;
          }
          long now = System.currentTimeMillis();
          if(lastUpdate + UPDATE_DELAY < now)
          {
            performResize(event);
            lastUpdate = now;
          }
          else
          {
            timerTask = new TimerTask()
            {
              public void run()
              {
                final TimerTask executingTask = this;
                event.display.asyncExec(new Runnable()
                {
                  public void run()
                  {
                    if(executingTask != timerTask) return;
                    performResize(event);
                  }
                });
              }
            };
            timer.schedule(timerTask, UPDATE_DELAY);
          }
        }
      }
    });
    
    addListener(SWT.MouseUp, new Listener()
    {
      public void handleEvent(Event event)
      {
        if(timerTask != null)
        {
          timerTask.cancel();
          timerTask = null;
        }
        if(!cancelled && (event.stateMask & SWT.BUTTON1) != 0)
        {
          performResize(event);
        }
      }
    });

    final Listener resizeListener = (resizableParent instanceof Shell) ? new Listener()
    {
      public void handleEvent(Event event)
      {
        updateVisibility();
      }
    } : null;

    if(resizeListener != null) resizableParent.addListener(SWT.Resize, resizeListener);
    
    addListener(SWT.Dispose, new Listener()
    {
      public void handleEvent(Event event)
      {
        timer.cancel();
        if(resizeListener != null) resizableParent.removeListener(SWT.Resize, resizeListener);
      }
    });

    updateVisibility();
  }


  private void performResize(Event event)
  {
    // Make sure we stay within the container parent's client area
    Rectangle ca;
    if(resizableParent instanceof Shell) ca = getDisplay().getClientArea();
    else ca = getDisplay().map(resizableParent.getParent(), null, resizableParent.getParent().getClientArea());
    Point limit = toControl(ca.x + ca.width - 1, ca.y + ca.height - 1);
    event.x = Math.min(event.x, limit.x);
    event.y = Math.min(event.y, limit.y);

    Point p = resizableParent.getSize();
    int newX = p.x + event.x - mouseDownOffsetX;
    int newY = p.y + event.y - mouseDownOffsetY;
    if(minSize != null)
    {
      newX = Math.max(minSize.x, newX);
      newY = Math.max(minSize.y, newY);
    }
    if(newX != p.x || newY != p.y) resizableParent.setSize(newX, newY);
  }


  private void updateVisibility()
  {
    if(resizableParent instanceof Shell)
    {
      boolean vis = super.getVisible();
      boolean max = ((Shell)resizableParent).getMaximized();
      boolean newVis = userVisible && !max;
      if(vis != newVis) super.setVisible(newVis);
    }
    else if(userVisible != super.getVisible()) super.setVisible(userVisible);
  }


  public Point computeSize(int wHint, int hHint, boolean changed)
  {
    checkWidget();
    if(wHint == SWT.DEFAULT) wHint = WIDTH;
    if(hHint == SWT.DEFAULT) hHint = HEIGHT;
    return new Point(wHint, hHint);
  }


  private static int checkStyle(int style)
  {
    int mask = SWT.SHADOW_IN | SWT.FLAT;
    style &= mask;
    return style;
  }


  public boolean setFocus()
  {
    checkWidget();
    return false;
  }


  public boolean isReparentable ()
  {
    checkWidget();
    return false;
  }
  
  
  /**
   * Set the allowed minimum size for the shell. The SizeGrip will
   * not resize the shell to a smaller size.
   * <p>
   * Note: This does <em>not</em> affect other ways of resizing the shell,
   * like using the size controls which are placed on the trimmings by
   * the window manager.
   * </p>
   */

  public void setMinimumShellSize(Point p)
  {
    checkWidget();
    this.minSize = p;
  }


  /**
   * Set the allowed minimum size for the shell. The SizeGrip will
   * not resize the shell to a smaller size.
   * <p>
   * Note: This does <em>not</em> affect other ways of resizing the shell,
   * like using the size controls which are placed on the trimmings by
   * the window manager.
   * </p>
   */

  public void setMinimumShellSize(int width, int height)
  {
    checkWidget();
    this.minSize = new Point(width, height);
  }


  public boolean getVisible()
  {
    checkWidget();
    return userVisible;
  }


  public void setVisible(boolean visible)
  {
    checkWidget();
    userVisible = visible;
    updateVisibility();
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -