Search code examples
javaswinguser-interfacescale

Drawing a rectangle in a JPanel, snapped to the nearest x pixels


I have a Swing UI for which the user should be able to click and drag within a JPanel (over some background image) to be able to define a given region. The problem is that the coordinates and the representation of the rectangle on the screen will need to snap to the outside 4 pixels of the region they have drawn. The background image will be enlarged such that it does not make sense for someone to be able to set a border between those points, and I'd like the UI to reflect this.

To give an example, if I were to click and draw a rectangle from (103, 105) to (203,205), the rectangle should appear to cover the area from (100,104) to (204,208) - i.e. the smallest possible rectangle such that all of the coordinates of the corners should be at a multiple of 4 pixels and that the area that was actually clicked is completely covered.

How would I go about doing this?


Solution

  • Well, I assume you have two Point objects (start, end), so you can create a little method to adjust the values.

    Here is a simple example to get your started:

    import java.awt.*;
    public class Main
    {
        public static void main(String[] args) throws Exception
        {
            Point start = new Point(103, 105);
            Point end = new Point(203, 205);
    
            adjust(start, 4, true);
            adjust(end, 4, false);
    
            System.out.println(start);
            System.out.println(end);
        }
    
        public static void adjust(Point p, int snap, boolean snapLower)
        {
            int modX = p.x % snap;
            p.x = snapLower ? p.x - modX : p.x + snap - modX;
    
            int modY = p.y % snap;
            p.y = snapLower ? p.y - modY : p.y + snap - modY;
        }
    }