2014-11-23 69 views
0

在爲我的窗口框架使用WebLookAndFeel UI時,我查找了調整未修飾框架的方式。幸運的是,該解決方案被發現: Drag and Resize undecorated JFrame實現邊框ComponentResizer偏移

但是,在使用Component Resizer代碼時,我遇到了邊界檢測問題。調整大小是檢測超出了我的應用程序的可視邊界。使用Windows的剪切工具,我通過將模式設置爲「窗口剪切」模式來確認我的懷疑,您可以看到這種模式,您可以看到here。我的框架的實際邊框延伸過了典型用戶會看到的視覺部分,因爲爲框架渲染了柔和的陰影。

如何將偏移量應用到Component Resizer代碼中,以便在視覺邊界上檢測到光標而不是外觀的柔和陰影邊界?我試着玩弄插圖和改變內部價值,但沒有骰子。任何幫助表示讚賞。

回答

0

在自己重新創建類之後,我可以理解代碼如何工作我在那裏實現了偏移量。請注意,我只測試了一個負偏移量,但它似乎工作正常。我也改變了你如何安裝監聽器和變量來控制,比如區域,它所做的全部工作是在決定使用光標之前檢查偏移行中的一半和一半。因此,7區將光標檢查3外部和3內部。

public class CustomResizer extends MouseAdapter 
{ 
    protected final static Map<Component, CustomResizer> instance = new HashMap<Component, CustomResizer>(); 
    protected final static Map<Integer, Integer> cursors = new HashMap<Integer, Integer>(); 
    { 
     cursors.put(1, Cursor.N_RESIZE_CURSOR); 
     cursors.put(2, Cursor.W_RESIZE_CURSOR); 
     cursors.put(4, Cursor.S_RESIZE_CURSOR); 
     cursors.put(8, Cursor.E_RESIZE_CURSOR); 
     cursors.put(3, Cursor.NW_RESIZE_CURSOR); 
     cursors.put(9, Cursor.NE_RESIZE_CURSOR); 
     cursors.put(6, Cursor.SW_RESIZE_CURSOR); 
     cursors.put(12, Cursor.SE_RESIZE_CURSOR); 
    } 

    public static CustomResizer install(Component component) 
    { 
     if(instance.containsKey(component)) 
     { 
      CustomResizer.uninstall(component); 
     } 
     CustomResizer crInstance = new CustomResizer(); 
     component.addMouseMotionListener(crInstance); 
     component.addMouseListener(crInstance); 
     instance.put(component, crInstance); 
     return crInstance; 
    } 

    public static void uninstall(Component component) 
    { 
     CustomResizer crInstance = instance.get(component); 
     instance.remove(component); 
     component.removeMouseListener(crInstance); 
     component.removeMouseMotionListener(crInstance); 
    } 

    public static CustomResizer getInstance(Component component) 
    { 
     return instance.get(component); 
    } 

    protected final static int NORTH = 1; 
    protected final static int WEST = 2; 
    protected final static int SOUTH = 4; 
    protected final static int EAST = 8; 

    private int zone = 7/2; 
    private int offset = 0; 

    private Point pressed; 
    private int direction; 
    private Rectangle bounds; 
    private boolean resizing; 
    private boolean autoscrolls; 
    private Cursor originalCursor; 

    @Override 
    public void mouseEntered(MouseEvent e) 
    { 
     originalCursor = !(resizing) ? e.getComponent().getCursor() : originalCursor; 
    } 

    @Override 
    public void mouseExited(MouseEvent e) 
    { 
     Component source = e.getComponent(); 
     source.setCursor(!(resizing) ? originalCursor : source.getCursor()); 
    } 

    @Override 
    public void mousePressed(MouseEvent e) 
    { 
     if(direction != 0) 
     { 
      resizing = true; 

      pressed = e.getPoint(); 
      Component source = e.getComponent(); 
      SwingUtilities.convertPointToScreen(pressed, source); 
      bounds = source.getBounds(); 

      if(source instanceof JComponent) 
      { 
       JComponent jc = (JComponent) source; 
       autoscrolls = jc.getAutoscrolls(); 
       jc.setAutoscrolls(false); 
      } 
     } 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) 
    { 
     if(resizing) 
     { 
      Component source = e.getComponent(); 
      Point dragged = e.getPoint(); 
      SwingUtilities.convertPointToScreen(dragged, source); 

      int x = bounds.x; 
      int y = bounds.y; 
      int width = bounds.width; 
      int height = bounds.height; 
      Dimension maximumSize = source.getMaximumSize(); 
      Dimension minimumSize = source.getMinimumSize(); 

      if(WEST == (direction & WEST)) 
      { 
       int drag = getDragDistance(pressed.x, dragged.x); 
       drag = getDragBounded(drag, width, minimumSize.width, Math.min(width + x - offset, maximumSize.width)); 

       x -= drag; 
       width += drag; 
      } 
      if(NORTH == (direction & NORTH)) 
      { 
       int drag = getDragDistance(pressed.y, dragged.y); 
       drag = getDragBounded(drag, height, minimumSize.height, Math.min(height + y - offset, maximumSize.height)); 

       y -= drag; 
       height += drag; 
      } 
      if(EAST == (direction & EAST)) 
      { 
       int drag = getDragDistance(dragged.x, pressed.x); 
       drag = getDragBounded(drag, width, minimumSize.width, Math.min(getBoundingSize(source).width - x, maximumSize.width)); 

       width += drag; 
      } 
      if(SOUTH == (direction & SOUTH)) 
      { 
       int drag = getDragDistance(dragged.y, pressed.y); 
       drag = getDragBounded(drag, height, minimumSize.height, Math.min(getBoundingSize(source).height - y, maximumSize.height)); 

       height += drag; 
      } 

      source.setBounds(x, y, width, height); 
     } 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) 
    { 
     Component source = e.getComponent(); 
     direction = 0; 

     Point location = e.getPoint(); 
     int x = location.x; 
     int y = location.y; 
     int widthOffset = source.getWidth() + offset; 
     int heightOffset = source.getHeight() + offset; 

     if(x < -offset + zone && x > -offset - zone) direction += WEST; 
     if(x > widthOffset - zone && x < widthOffset + zone) direction += EAST; 
     if(y < -offset + zone && y > -offset - zone) direction += NORTH; 
     if(y > heightOffset - zone && y < heightOffset + zone) direction += SOUTH; 

     source.setCursor(direction == 0 ? originalCursor : Cursor.getPredefinedCursor(cursors.get(direction))); 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) 
    { 
     resizing = false; 

     Component source = e.getComponent(); 
     source.setCursor(originalCursor); 

     if(source instanceof JComponent) 
     { 
      ((JComponent) source).setAutoscrolls(autoscrolls); 
     } 
    } 

    private int getDragDistance(int larger, int smaller) 
    { 
     int drag = larger - smaller; 
     drag += (drag < 0) ? -1 : 1; 
     return drag; 
    } 

    private int getDragBounded(int drag, int dimension, int minimum, int maximum) 
    { 
     while(dimension + drag < minimum) drag += 1; 
     while(dimension + drag > maximum) drag -= 1; 
     return drag; 
    } 

    private Dimension getBoundingSize(Component source) 
    { 
     if(source instanceof Window) 
     { 
      Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); 
      return new Dimension(bounds.width - offset, bounds.height - offset); 
     } 
     else 
     { 
      Dimension size = source.getParent().getSize(); 
      return new Dimension(size.width - offset, size.height - offset); 
     } 
    } 

    public void setOffset(int offset) 
    { 
     this.offset = offset; 
    } 

    public int getOffset() 
    { 
     return offset; 
    } 

    public void setZone(int zone) 
    { 
     this.zone = zone/2; 
    } 

    public int getZone() 
    { 
     return zone; 
    } 
}