2014-11-23 44 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; 
    } 
}