简体   繁体   中英

Java swing graphics drawing and filling selected rectangles with colors

I am new to Java swing desktop graphics applications I got an issue please suggest i need to select a some of the rectangles and fill the rectangles with do we any predefined concept is there like rubber band if any please suggest me to start a drawing

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Exam extends JPanel implements MouseMotionListener {

    private static final int recW = 50;
    private static final int MAX = 100;
    private Rectangle[] rect = new Rectangle[MAX];
    private int numOfRecs = 0;
    private int currentSquareIndex = -1;
    private Point startPoint = new Point();
    private Point currentPoint = new Point();
    private int x, y, width, height;
    private Stroke dashedStroke = new BasicStroke(0.0f, BasicStroke.CAP_ROUND,
            BasicStroke.CAP_SQUARE, 5.0f, new float[] { 5f, 5f, 5f, 5f }, 5.0f);

    ArrayList list = new ArrayList();

    public Exam() {

        addRect(50, 50);
        addRect(100, 50);
        addRect(150, 50);
        addRect(200, 50);
        addRect(250, 50);
        addRect(300, 50);
        addRect(350, 50);
        addRect(400, 50);
        addRect(450, 50);
        addRect(500, 50);
        //
        addRect(50, 100);
        addRect(100, 100);
        addRect(150, 100);
        addRect(200, 100);
        addRect(250, 100);
        addRect(300, 100);
        addRect(350, 100);
        addRect(400, 100);
        addRect(450, 100);
        addRect(500, 100);
        //
        addRect(50, 150);
        addRect(100, 150);
        addRect(150, 150);
        addRect(200, 150);
        addRect(250, 150);
        addRect(300, 150);
        addRect(350, 150);
        addRect(400, 150);
        addRect(450, 150);
        addRect(500, 150);
        //
        addRect(50, 200);
        addRect(100, 200);
        addRect(150, 200);
        addRect(200, 200);
        addRect(250, 200);
        addRect(300, 200);
        addRect(350, 200);
        addRect(400, 200);
        addRect(450, 200);
        addRect(500, 200);

        addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent evt) {
                startPoint = evt.getPoint();
            }

            public void mouseReleased(MouseEvent e) {

                System.out.println(" mouseReleased is " + e.getX() + " y i s "
                        + e.getY());
                Graphics g = getGraphics();
                Graphics2D g2 = (Graphics2D) g;
                g2.setComposite(AlphaComposite.SrcOver.derive(0.8f));
                Color myColour = new Color(255, 0, 0);
                g.setColor(myColour);
                x = Math.min(startPoint.x, currentPoint.x);
                y = Math.min(startPoint.y, currentPoint.y);
                width = Math.abs(startPoint.x - currentPoint.x);
                height = Math.abs(startPoint.y - currentPoint.y);
                rect[numOfRecs] = new Rectangle(x, y, width, height);
                // System.out.println("list size is:"+list.size());
                 Rectangle ggg=new Rectangle(x, y, width, height);
            for(Rectangle rect3d: rect){
                if(ggg.intersects(rect3d)){
                g2.fill(rect3d);
                }
                else
                    System.out.println("doesn't contains");
                }
repaint();
            }

        });

        addMouseMotionListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < numOfRecs; i++) {
            ((Graphics2D) g).draw(rect[i]);
            list.add(rect[i]);
        }

        x = Math.min(startPoint.x, currentPoint.x);
        y = Math.min(startPoint.y, currentPoint.y);
        width = Math.abs(startPoint.x - currentPoint.x);
        height = Math.abs(startPoint.y - currentPoint.y);
        ((Graphics2D) g).setStroke(dashedStroke);
        g.setColor(Color.BLACK);
        g.drawRect(x, y, width, height);
        // Rectangle dashedRec=new Rectangle(x, y, width, height);

    }

    public void addRect(int x, int y) {
        if (numOfRecs < MAX) {
            rect[numOfRecs] = new Rectangle(x, y, recW, recW);
            currentSquareIndex = numOfRecs;
            numOfRecs++;
            repaint();
        }
    }

    @Override
    public void mouseMoved(MouseEvent event) {
    }

    @Override
    public void mouseDragged(MouseEvent event) {

        currentPoint = event.getPoint();
        repaint();
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.setTitle("");
        jFrame.setSize(600, 300);
        Container cPane = jFrame.getContentPane();
        cPane.add(new Exam());
        jFrame.setVisible(true);
    }
}

You should start by changing import java.awt.event.MouseMotionListener;

to

import java.awt.event.MouseListener;

mousePressed does not go with MouseMotionListener

I see the class name is Exam , so since this is for school, I won't give you code solution. Just some logical ways to look at it.

I notice that when you drag the mouse, you are just getting a point and drawing based off that point. What you should do instead is, when the mouse is first pressed, create a Rectangle (and draw the rectangle), and while the mouse is being dragged, increase the size of the rectangle with setRect() . You can see a good example here .

Depending, if you want the color change to be dynamic (while dragging or when dragging is done), you have two options:

  1. While dragging iterate through the list of rectangles and check if each rectangle in the list intersects or is contained by the dragged rectangle. Rectangle inherits method intersects() and contains() from Shape

  2. If you just want the color changed when the dragging is finished, then do the same as above, when the mouse is released.


Also note, you should not be using getGraphics() in any way to do custom painting. All the painting should be done within the context of the Graphics object provided in the paintComponent method


UPDATE

Here is an example based on the points I made above. The example expands on the example provided in the link above

在此处输入图片说明

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class RectangleDrawWithDrag extends JPanel{

    private static final int D_W = 400;
    private static final int D_H = 400;
    private static final Color DEFAULT_COLOR = Color.GRAY;
    private static final Color SELECT_COLOR = Color.BLUE;
    private static final Color CURSOR_COLOR = new Color(100, 100, 100, 100);

    private Point p1;
    private Point p2;
    private Rectangle2D rectangle;
    private List<ColoredRectangle> rectangles;

    public RectangleDrawWithDrag() {
        rectangles = createRectangleList();
        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent e) {
                p1 = e.getPoint();
                rectangle = new Rectangle2D.Double(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
            }
        });
        addMouseMotionListener(new MouseMotionAdapter(){
            public void mouseDragged(MouseEvent e) {
                p2 = e.getPoint();
                if (isPointTwoInQuadOne(p1, p2)) {
                    rectangle.setRect(p2.x, p2.y, p1.x - p2.x, p1.y - p2.y);
                } else {
                    rectangle.setRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);  
                }
                checkRectangleContainment();
                repaint();
            }
        });
    }

    public void checkRectangleContainment() {
        for (ColoredRectangle rects: rectangles) {
            if (rectangle.contains(rects.getRectangle())) {
                rects.setColor(SELECT_COLOR);
            } else {
                rects.setColor(DEFAULT_COLOR);
            }
        }
    }

    public boolean isPointTwoInQuadOne(Point p1, Point p2) {
        return p1.x >= p2.x && p1.y >= p2.y;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        for (ColoredRectangle rect: rectangles) {
            rect.draw(g2);
        }
        if (rectangle != null) {
            g2.setColor(CURSOR_COLOR);
            g2.fill(rectangle);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(D_W, D_H);
    }

    private List<ColoredRectangle> createRectangleList() {
        List<ColoredRectangle> rects = new ArrayList<>();
        Random rand= new Random();
        for (int i = 0; i < 20; i++) {
            rects.add(new ColoredRectangle(rand.nextInt(D_W), rand.nextInt(D_H)));
        }
        return rects;
    }

    public class ColoredRectangle {
        Rectangle2D rectangle;
        Color color = DEFAULT_COLOR;
        double size = 20;

        public ColoredRectangle(double x, double y) {
            rectangle = new Rectangle2D.Double(x, y, size, size);
        }

        public ColoredRectangle(double x, double y, double size) {
            this.size = size;
            rectangle = new Rectangle2D.Double(x, y, size, size);
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public Rectangle2D getRectangle() {
            return rectangle;
        }

        public void draw(Graphics2D g2) {
            g2.setColor(color);
            g2.fill(rectangle);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new RectangleDrawWithDrag());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

I came across your question while searching for something similar I needed. I customized the Paul's code a little bit more for my requirements. I'm writing here because I'm not allowed make comment here my version

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.util.HashSet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;

public class TimetableFrame extends javax.swing.JFrame {

Point p1, p2;
Rectangle2D rectangle;
int mode = 0;
HashSet<JLabel> all = new HashSet<JLabel>();
HashSet<JLabel> selected = new HashSet<JLabel>();
HashSet<JLabel> current_selection = new HashSet<JLabel>();
Color empty_color = Color.WHITE;
Color fill_color = Color.RED;
Color empty_select = Color.GRAY;
Color fill_select = Color.PINK;

JPanel grid;
JPanel jPanel1;
JScrollPane jScrollPane1;

public TimetableFrame() {
    initComponents();
    setTitle("Swing grid selector example halimoglu.com");
    String[] col_titles = new String[]{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

    String[] row_titles = new String[24];
    for (int i = 0; i < row_titles.length; i++) {
        row_titles[i] = (i) + "-" + (i + 1);
    }

    for (int y = 0; y < row_titles.length + 1; y++) {
        for (int x = 0; x < col_titles.length + 1; x++) {
            if (y == 0 && x == 0) {
                grid.add(new JLabel(""));
            } else if (y == 0) {
                JLabel col = new JLabel(col_titles[x - 1]);
                col.setHorizontalAlignment(SwingConstants.CENTER);
                grid.add(col);
            } else if (x == 0) {
                grid.add(new JLabel(row_titles[y - 1]));
            } else {
                JLabel mylabel = new JLabel(" ");

                mylabel.setOpaque(true);
                mylabel.setBackground(empty_color);
                all.add(mylabel);
                grid.add(mylabel);
            }
        }
    }

    grid.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent me) {
            for (JLabel j : all) {
                if (j.getBounds().contains(me.getPoint())) {

                    if (selected.contains(j)) {
                        selected.remove(j);
                        j.setBackground(empty_color);
                    } else {
                        selected.add(j);
                        j.setBackground(fill_color);
                    }
                }
            }
        }

        @Override
        public void mousePressed(MouseEvent me) {
            p1 = me.getPoint();
            rectangle = new Rectangle2D.Double(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
        }

        @Override
        public void mouseReleased(MouseEvent me) {

            if (mode == 1) {
                selected.addAll(current_selection);

            } else if (mode == -1) {
                selected.removeAll(current_selection);

            }
            for (JLabel j : all) {
                if (selected.contains(j)) {
                    j.setBackground(fill_color);
                } else {
                    j.setBackground(empty_color);
                }
            }
            current_selection.clear();
            mode = 0;
        }

        @Override
        public void mouseEntered(MouseEvent me) {
        }

        @Override
        public void mouseExited(MouseEvent me) {
        }

    });

    grid.addMouseMotionListener(new MouseMotionListener() {
        @Override
        public void mouseDragged(MouseEvent me) {
            p2 = me.getPoint();

            Point lu;

            int minx = Math.min(p1.x, p2.x);
            int miny = Math.min(p1.y, p2.y);
            int maxx = Math.max(p1.x, p2.x);
            int maxy = Math.max(p1.y, p2.y);

            lu = new Point(minx, miny);// left upper point

            rectangle.setRect(lu.x, lu.y, maxx - minx, maxy - miny);

            //set mode 
            //1 = if first selected cell is empty set mode to fill
            //-1 = otherwise clear 
            if (mode == 0) {
                for (JLabel j : all) {
                    if (j.getBounds().intersects(rectangle)) {
                        if (selected.contains(j)) {
                            mode = -1;
                        } else {
                            mode = 1;
                        }
                        break;
                    }
                }
            }

            for (JLabel j : all) {

                if (selected.contains(j) == (mode != 1)) {
                    if (j.getBounds().intersects(rectangle)) {
                        current_selection.add(j);
                    } else {
                        if (current_selection.contains(j)) {
                            current_selection.remove(j);
                            if (mode == 1) {
                                if (selected.contains(j) == false) {
                                    j.setBackground(empty_color);
                                }
                            } else {
                                if (selected.contains(j) == true) {
                                    j.setBackground(fill_color);
                                }
                            }
                        }
                    }
                }
            }

            for (JLabel j : current_selection) {
                if (mode == 1) {
                    j.setBackground(fill_select);
                } else if (mode == -1) {
                    j.setBackground(empty_select);
                }
            }

        }

        @Override
        public void mouseMoved(MouseEvent me) {
        }
    });
}

private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    jPanel1 = new javax.swing.JPanel();
    grid = new javax.swing.JPanel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setLayout(new java.awt.BorderLayout());

    grid.setLayout(new java.awt.GridLayout(25, 0, 2, 2));
    jPanel1.add(grid, java.awt.BorderLayout.CENTER);

    jScrollPane1.setViewportView(jPanel1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 465, Short.MAX_VALUE)
    );

    pack();
}

public static void main(String args[]) {

    new TimetableFrame().setVisible(true);

}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM