Java 实现边界组件Resistizer偏移

Java 实现边界组件Resistizer偏移,java,mouseevent,look-and-feel,Java,Mouseevent,Look And Feel,在为我的窗框使用WebLookAndFeel UI时,我找到了一种调整未装饰窗框大小的方法。幸运的是,找到了解决方案: 然而,在使用代码时,我遇到了边界检测的问题。调整大小时检测到我的应用程序的可视边界有点超出。使用Windows的剪贴工具,我通过将模式设置为窗口剪贴模式来确认我的怀疑,您可以看到。我的帧的实际边界会延伸到典型用户会看到的视觉部分之外,因为有软阴影正在为帧渲染 如何在组件大小调整器代码中实现偏移,以便在视觉边框上而不是外观的软阴影边框上检测光标?我尝试过使用插图和更改内部值,但

在为我的窗框使用WebLookAndFeel UI时,我找到了一种调整未装饰窗框大小的方法。幸运的是,找到了解决方案:

然而,在使用代码时,我遇到了边界检测的问题。调整大小时检测到我的应用程序的可视边界有点超出。使用Windows的剪贴工具,我通过将模式设置为窗口剪贴模式来确认我的怀疑,您可以看到。我的帧的实际边界会延伸到典型用户会看到的视觉部分之外,因为有软阴影正在为帧渲染


如何在组件大小调整器代码中实现偏移,以便在视觉边框上而不是外观的软阴影边框上检测光标?我尝试过使用插图和更改内部值,但没有骰子。非常感谢您的帮助。

在我自己重新创建了这个类,以便我能够理解代码是如何工作的之后,我在其中实现了偏移量。请注意,我只测试了负偏移量,但它似乎工作正常。我还改变了如何安装监听器和变量进行控制,比如zone,它所做的只是在决定使用光标之前检查偏移量行的一半和一半。因此,一个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;
    }
}
public类CustomResizer扩展了MouseAdapter
{
受保护的最终静态映射实例=new HashMap();
受保护的最终静态映射游标=新HashMap();
{
光标.put(1,Cursor.N\u RESIZE\u Cursor);
光标.put(2,Cursor.W_RESIZE_Cursor);
光标.put(4,Cursor.S_RESIZE_Cursor);
光标.put(8,Cursor.E_RESIZE_Cursor);
游标.put(3,游标.NW\u调整游标大小);
游标.put(9,游标.NE_调整游标大小);
光标.put(6,Cursor.SW_RESIZE_Cursor);
光标.put(12,Cursor.SE_RESIZE_Cursor);
}
公共静态CustomResizer安装(组件)
{
if(实例.containsKey(组件))
{
卸载(组件);
}
CustomResizer crInstance=新CustomResizer();
addMouseMotionListener(crInstance);
组件。addMouseListener(crInstance);
实例.put(组件、实例);
回程阻力;
}
公共静态无效卸载(组件)
{
CustomResizer crInstance=instance.get(组件);
实例。移除(组件);
组件。移除鼠标侦听器(crInstance);
组件。removeMouseMotionListener(crInstance);
}
公共静态CustomResizer getInstance(组件)
{
返回instance.get(组件);
}
受保护的最终静态int北=1;
受保护的最终静态int WEST=2;
受保护的最终静态int南=4;
受保护的最终静态int东=8;
私人综合区=7/2;
私有整数偏移=0;
私人点按;
私人int方向;
私有矩形边界;
私有布尔调整大小;
私有布尔自动换行符;
私有游标源游标;
@凌驾
公共无效鼠标事件(鼠标事件e)
{
originalCursor=!(调整大小)?e.getComponent().getCursor():originalCursor;
}
@凌驾
公共无效mouseExited(MouseEvent e)
{
组件源=e.getComponent();
source.setCursor(!(调整大小)?originalCursor:source.getCursor();
}
@凌驾
公共无效鼠标按下(MouseEvent e)
{
如果(方向!=0)
{
调整大小=真;
按下=e.getPoint();
组件源=e.getComponent();
SwingUtilities.convertPointToScreen(按下,来源);
bounds=source.getBounds();
if(JComponent的源实例)
{
JComponent jc=(JComponent)源;
autoscrolls=jc.getAutoscrolls();
jc.setAutoscrolls(假);
}
}
}
@凌驾
公共无效鼠标标记(鼠标事件e)
{
如果(调整大小)
{
组件源=e.getComponent();
点拖动=e.getPoint();
SwingUtilities.convertPointToScreen(拖动,源);
int x=界限.x;
int y=bounds.y;
int width=bounds.width;
int height=bounds.height;
维度maximumSize=source.getMaximumSize();
维度minimumSize=source.getMinimumSize();
如果(西==(方向和西))
{
int drag=getDragDistance(按.x,拖动.x);
drag=getDragBounded(drag,width,minimumSize.width,Math.min(width+x-偏移量,maximumSize.width));
x-=阻力;
宽度+=阻力;
}
如果(北==(方向和北))
{
int drag=getDragDistance(按.y,拖动.y);
drag=getDragBounded(拖动、高度、minimumSize.height、Math.min(高度+y偏移、maximumSize.height));
y-=阻力;
高度+=阻力;
}
如果(东==(方向和东))
{
int drag=getDragDistance(拖动.x,按下.x);
drag=getDragBounded(drag,width,minimumSize.width,Math.min(getBoundingSize(source).width-x,maximumSize.width));
宽度+=阻力;
}
如果(南==(方向和南))
{
int drag=getDragDistance(拖动.y,按下.y);
drag=getDragBounded(drag,height,minimumSize.height,Math.min(getBoundingSize(source).height-y,maximumSize.height));
高度+=阻力;
}
来源.立根(x,y,宽度,高度);
}
}
@凌驾
public void mouseMoved(MouseEvent e)
{
组件源=e.getComponent();
方向=