How to use the swing class java to draw a grid and detect the mouse position when clicking and dragging

I'm trying to use swing class to create grid UI (5 * 5) I tried a nested loop and dynamically added JPanel to JFrame I also try to change the background color of each JPanel when the user clicks and deletes it

public class clsCanvasPanel extends JPanel {
    private static final int intRows = 5;
    private static final int intCols = 5;
    private List<JPanel> jpllist = new ArrayList<JPanel>();

    public clsCanvasPanel() {                           
        /*
         * 
         * Add eventListener to individual JPanel within CanvasPanel
         *
         * 
         * TODO : 
         * 1) mousePressed --> update Temperature and HeatConstant of clsElement Class
         * 2) start a new thread and  
         * 3) call clsElement.run() method
         * 
         * 
         * Right Now : it updates the colours of the JPanel
         * */
          MouseListener mouseListener = new MouseAdapter() {
             @Override
             public void mousePressed(MouseEvent e) {
                JPanel panel = (JPanel) e.getSource();

                Component[] components = panel.getComponents();
                for (Component component : components) {
                   component.setVisible(!component.isVisible());
                   component.setBackground(new Color(255,255,0));
                }
                panel.revalidate();
                panel.repaint();
             }
          };

          //TODO : refactoring
          GridLayout gdlyPlates = new GridLayout();
          gdlyPlates.setColumns(intCols);
          gdlyPlates.setRows(intRows);
          gdlyPlates.setHgap(0);
          gdlyPlates.setVgap(0);
          setLayout(gdlyPlates);

          //TODO : refactoring
          for (int row = 0; row < intRows; row++) {
              for (int col = 0; col < intCols; coL++) {
                 JPanel panel = new JPanel(new GridBagLayout());
                 panel.setOpaque(false);
                 JPanel jl = new JPanel();
                 jl.setVisible(true);
                 panel.add(jl);
                 panel.addMouseListener(mouseListener);
                 jpllist.add(panel);
                 add(panel);
              }
           }
    }
}

So now I try to create a panel and draw a grid on it, then detect the mouse position on the grid and further change the color of each cell

Someone can give me some advice on how to implement this grid on JPanel and change the color of the selected cells

Solution

There are many ways to make it work, depending on what you want to achieve

The first example uses only 2D graphics API to render cells and mousemotionlistener to monitor highlighted cells

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestGrid01 {

    public static void main(String[] args) {
        new TestGrid01();
    }

    public TestGrid01() {
        EventQueue.invokelater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | illegalaccessexception | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int columnCount = 5;
        private int rowCount = 5;
        private List<Rectangle> cells;
        private Point selectedCell;

        public TestPane() {
            cells = new ArrayList<>(columnCount * rowCount);
            MouseAdapter mouseHandler;
            mouseHandler = new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    Point point = e.getPoint();

                    int width = getWidth();
                    int height = getHeight();

                    int cellWidth = width / columnCount;
                    int cellHeight = height / rowCount;

                    selectedCell = null;
                    if (e.getX() >= xOffset && e.getY() >= yOffset) {

                        int column = (e.getX() - xOffset) / cellWidth;
                        int row = (e.getY() - yOffset) / cellHeight;

                        if (column >= 0 && row >= 0 && column < columnCount && row < rowCount) {

                            selectedCell = new Point(column,row);

                        }

                    }
                    repaint();

                }
            };
            addMouseMotionListener(mouseHandler);
        }

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

        @Override
        public void invalidate() {
            cells.clear();
            selectedCell = null;
            super.invalidate();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int width = getWidth();
            int height = getHeight();

            int cellWidth = width / columnCount;
            int cellHeight = height / rowCount;

            int xOffset = (width - (columnCount * cellWidth)) / 2;
            int yOffset = (height - (rowCount * cellHeight)) / 2;

            if (cells.isEmpty()) {
                for (int row = 0; row < rowCount; row++) {
                    for (int col = 0; col < columnCount; coL++) {
                        Rectangle cell = new Rectangle(
                                xOffset + (col * cellWidth),yOffset + (row * cellHeight),cellWidth,cellHeight);
                        cells.add(cell);
                    }
                }
            }

            if (selectedCell != null) {

                int index = selectedCell.x + (selectedCell.y * columnCount);
                Rectangle cell = cells.get(index);
                g2d.setColor(Color.BLUE);
                g2d.fill(cell);

            }

            g2d.setColor(Color.GRAY);
            for (Rectangle cell : cells) {
                g2d.draw(cell);
            }

            g2d.dispose();
        }
    }
}

This example uses windows to resize the grid, but fixing the size of the cells would be a trivial change

See 2D graphics for more details

Update using component samples

This example uses a series of jpanels to represent each cell

Each cell is defined as a fixed width and height and does not resize with the main window

In this example, each cell panel has its own mouse listener Recoding it won't be too difficult, so the main panel has only one mouse listener and manages the workload itself

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

public class TestGrid02 {

    public static void main(String[] args) {
        new TestGrid02();
    }

    public TestGrid02() {
        EventQueue.invokelater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | illegalaccessexception | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            for (int row = 0; row < 5; row++) {
                for (int col = 0; col < 5; coL++) {
                    gbc.gridx = col;
                    gbc.gridy = row;

                    CellPane cellPane = new CellPane();
                    Border border = null;
                    if (row < 4) {
                        if (col < 4) {
                            border = new MatteBorder(1,1,Color.GRAY);
                        } else {
                            border = new MatteBorder(1,Color.GRAY);
                        }
                    } else {
                        if (col < 4) {
                            border = new MatteBorder(1,Color.GRAY);
                        }
                    }
                    cellPane.setBorder(border);
                    add(cellPane,gbc);
                }
            }
        }
    }

    public class CellPane extends JPanel {

        private Color defaultBackground;

        public CellPane() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    defaultBackground = getBackground();
                    setBackground(Color.BLUE);
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    setBackground(defaultBackground);
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(50,50);
        }
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>