通过单击更改网格单元格的颜色

时间:2017-08-05 19:13:34

标签: java swing graph graphics

我正在研究正在绘制细胞网格的程序。每个单元格都有指定的颜色和四种状态之一:

  1. STARTCELL //marked by yellow color
    
  2. ENDCELL //marked by red color 
    
  3. EMPTYCELL //marked by white color
    
  4. BLOCKEDCELL // marked by black color
    
  5. 开头有一个黄色单元格,一个红色单元格,其余部分为白色。

    我希望能够通过点击它们来改变细胞的颜色和状态,经过一些研究后我找到了解决方案:

    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        for (Cell item : gridCells) {
            if (item.getCellShape().contains(e.getPoint())&& item.getCellState()==CellState.EMPTYCELL) {
                item.setCellColor(mouseColor);
                if(mouseColor==startCellColor){
                    item.setCellState(CellState.STARTCELL);
                }else if(mouseColor==endCellColor){
                    item.setCellState(CellState.ENDCELL);
                }else{
                    item.setCellState(CellState.BLOCKEDCELL);
                }
            }
        }
        repaint();
    }
    

    唯一的问题是应该只有一个STARTCELL 当时有一个ENDCELL我无法找到正确更改未点击单元状态的方法。

    我多次尝试并最终得到了这个:

        @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        for (Cell item : gridCells) {
            if (item.getCellShape().contains(e.getPoint())&& item.getCellState()==CellState.EMPTYCELL) {
                item.setCellColor(mouseColor);
                if(mouseColor==startCellColor){
                        gridCells.get(numberOfStartCell-1).setCellColor(cellColor);
                        gridCells.get(numberOfStartCell-1).setCellState(CellState.EMPTYCELL);
                        numberOfStartCell=item.getNumberOfCell();
                        item.setCellState(CellState.STARTCELL);
                }else if(mouseColor==endCellColor){
                    item.setCellState(CellState.ENDCELL);
                }else{
                    item.setCellState(CellState.BLOCKEDCELL);
                }
                areaTest.setText(Integer.toString(numberOfStartCell));
            }
        }
        repaint();
    }
    

    不幸的是它无法正常工作。第一次单击后,新单元格的颜色变为黄色,旧单元格的颜色变为白色,变量numberOfStartCell的值也会变化。但是在第二次点击之后,唯一的部分就是numberOfStartCell

    这是MCV: 我想在前两个课程中无需解释。

    Class Main

    import java.awt.EventQueue;
    
    public class Main {
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new MyFrame();
                }
            });
         }
    }
    

    Class MyFrame

    import java.awt.Dimension;
    import java.awt.Toolkit;
    
    import javax.swing.JFrame;
    
    public class MyFrame extends JFrame {
    
       int width  = 750;
       int height = 750;
       MyPanel panel;
    
       public MyFrame() {
            super("Przeszukiwanie");
            setSize(width,height);
            setResizable(false);
    
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            double screenWidth = screenSize.getWidth();
            double ScreenHeight = screenSize.getHeight();
            int x = ((int)screenWidth-width)/2;
            int y = ((int)ScreenHeight-height)/2;
    
            setLocation(x,y);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setVisible(true);
            panel=new MyPanel();
            add(panel);
            pack();
        }
    }
    

    Class MyPanel负责事件处理和GUI。

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.ButtonGroup;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.JTextField;
    
    public class MyPanel extends JPanel implements ActionListener{
    
        private JButton createButton;
    
        private ButtonGroup cellColorGroup;
        private JRadioButton startingNode;
        private JRadioButton endingNode;
        private JRadioButton obstacleNode;
    
        private JTextField rows;
        private JTextField columns;
    
        private JLabel labelRows;
        private JLabel labelColumns;
    
        private String strRowsField;
        private String strColumnsField;
    
        private JPanel panelButtons;
        private GridPanel panelGrid;
        private JPanel panelSettings;
    
        public MyPanel(){
    
            setPreferredSize(new Dimension(700, 600));
            setLayout(new BorderLayout());
    
            strRowsField="10";
            strColumnsField="10";
    
            panelButtons=new JPanel();
            panelSettings=new JPanel();
            panelGrid=new GridPanel(Integer.parseInt(strColumnsField),Integer.parseInt(strRowsField));
    
            panelSettings.setLayout(new GridLayout(6,2));
    
            createButton= new JButton("Create");
    
            cellColorGroup=new ButtonGroup();
            startingNode=new JRadioButton("Strating Node");
            endingNode=new JRadioButton("Ending Node");
            obstacleNode=new JRadioButton("Remove/Add Obstacle", true);
    
            cellColorGroup.add(startingNode);
            cellColorGroup.add(endingNode);
            cellColorGroup.add(obstacleNode);
    
            createButton.addActionListener(this);
            startingNode.addActionListener(this);
            endingNode.addActionListener(this);
            obstacleNode.addActionListener(this);
    
            columns=new JTextField(strColumnsField,2);
            rows=new JTextField(strRowsField,2);
            labelRows=new JLabel("Number of rows");
            labelColumns= new JLabel("Number of columns");
    
            panelButtons.add(createButton);
    
            panelSettings.add(labelColumns);
            panelSettings.add(columns);
            panelSettings.add(labelRows);
            panelSettings.add(rows);
            panelSettings.add(startingNode);
            panelSettings.add(endingNode);
            panelSettings.add(obstacleNode);
    
            add(panelButtons,BorderLayout.SOUTH);
            add(panelGrid,BorderLayout.WEST);
            add(panelSettings,BorderLayout.EAST);
    
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == createButton) {
                panelGrid.setcNodes(Integer.parseInt(columns.getText()));
                panelGrid.setrNodes(Integer.parseInt(rows.getText()));
                panelGrid.getGridCells().clear();
                panelGrid.repaint();
            }else if(e.getSource() == startingNode){
                 panelGrid.setMouseColor(panelGrid.getStartCellColor());
    
            }else if(e.getSource() == endingNode){
                panelGrid.setMouseColor(panelGrid.getEndCellColor());
    
            }else if(e.getSource() == obstacleNode){
                 panelGrid.setMouseColor(panelGrid.getObstacleCellColor());
            }
        }
    }
    

    Class GridPanel负责绘制节点,边和单元格。

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseMotionListener;
    import java.awt.geom.Line2D;
    import java.awt.geom.Rectangle2D;
    import java.util.ArrayList;
    
    import javax.swing.JPanel;
    
    public class GridPanel extends JPanel implements MouseListener, MouseMotionListener {
    
        private int cNodes;//Number of nodes across
        private int rNodes;//Number of nodes along
        private int nodeX;//X coordinate of the first node
        private int nodeY;//Y coordinate of the first node
        private int width=330;
        private int height=330;
        private int circleX;//Center of circle X
        private int circleY;//Center of circle Y
        private Color cellColor;
        private Color startCellColor;
        private Color endCellColor;
        private Color obstacleCellColor;
        private Color mouseColor;
        private int numberOfStartCell;
    
        private ArrayList<Cell> gridCells;
        public GridPanel(int cNodes, int rNodes){
    
            setPreferredSize(new Dimension(width,height));
    
            this.cNodes=cNodes;
            this.rNodes=rNodes;
    
            if(cNodes>rNodes){
                nodeX=width/(cNodes+1);//Calculation of the x coordinate value of the first node
                nodeY=height/(cNodes+1);//Calculation of the y coordinate value of the first node
            }else{
                nodeX=width/(rNodes+1);
                nodeY=height/(rNodes+1);
            }
    
            circleX=nodeX;
            circleY=nodeY;
    
            cellColor=Color.WHITE;
            startCellColor=Color.YELLOW;
            endCellColor=Color.RED;
            obstacleCellColor=Color.BLACK;
    
            gridCells=new ArrayList<Cell>();
    
            addMouseListener(this);
            addMouseMotionListener(this);
    
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            drawCells(g2d);
    
         }
    
        public void drawCells(Graphics2D g2d){
            int number=0;
            int c=0;
            for(int i=0; i<rNodes; i++){
                for(int j=0; j<cNodes; j++){
                    number++;
                    if(i==0 && j==cNodes-1){
                         gridCells.add(new Cell(circleX,circleY,nodeX,endCellColor,new Rectangle2D.Double(circleX-(nodeX/2),circleY-(nodeX/2),nodeX,nodeX),CellState.ENDCELL,number));
    
                    }
                     else if(i==rNodes-1 && j==0){
                         gridCells.add(new Cell(circleX,circleY,nodeX,startCellColor,new Rectangle2D.Double(circleX-(nodeX/2),circleY-(nodeX/2),nodeX,nodeX),CellState.STARTCELL,number));
                    numberOfStartCell=number;
                    }
                     else {
                         gridCells.add(new Cell(circleX,circleY,nodeX,cellColor,new Rectangle2D.Double(circleX-(nodeX/2),circleY-(nodeX/2),nodeX,nodeX),CellState.EMPTYCELL,number));
                    }
                    g2d.setPaint(gridCells.get(c).getCellColor());
                    g2d.fill(gridCells.get(c).getCellShape());
                    g2d.setPaint(Color.BLACK);
                    g2d.draw(gridCells.get(c).getCellShape());
                    if(j<(cNodes-1)){
                        circleX+=nodeX;
                    }
                    c++;
                }
                circleX=nodeX;
                if(i<(rNodes-1)){
                    circleY+=nodeY;
                }
            }
            circleX=nodeX;
            circleY=nodeY;
        }
    
        public void setMouseColor(Color mouseColor) {
            this.mouseColor = mouseColor;
        }
    
        public void setcNodes(int cNodes) {
            this.cNodes = cNodes;
        }
    
        public void setrNodes(int rNodes) {
            this.rNodes = rNodes;
        }   
    
        public Color getObstacleCellColor() {
            return obstacleCellColor;
        }
    
        public Color getStartCellColor() {
            return startCellColor;
        }
    
        public Color getEndCellColor() {
            return endCellColor;
        }
    
        public ArrayList<Cell> getGridCells() {
            return gridCells;
        }
    
        @Override
        public void mouseDragged(MouseEvent arg0) {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void mouseMoved(MouseEvent arg0) {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub
            for (Cell item : gridCells) {
                if (item.getCellShape().contains(e.getPoint())&& item.getCellState()==CellState.EMPTYCELL) {
                    item.setCellColor(mouseColor);
                    if(mouseColor==startCellColor){
                            gridCells.get(numberOfStartCell-1).setCellColor(cellColor);
                            gridCells.get(numberOfStartCell-1).setCellState(CellState.EMPTYCELL);
                            numberOfStartCell=item.getNumberOfCell();
                            item.setCellState(CellState.STARTCELL);
                    }else if(mouseColor==endCellColor){
                        item.setCellState(CellState.ENDCELL);
                    }else{
                        item.setCellState(CellState.BLOCKEDCELL);
                    }
                }
            }
            repaint();
        }
    
        @Override
        public void mouseEntered(MouseEvent arg0) {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void mouseExited(MouseEvent arg0) {
             // TODO Auto-generated method stub
        }
    
        @Override
        public void mousePressed(MouseEvent arg0) {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void mouseReleased(MouseEvent arg0) {
            // TODO Auto-generated method stub
        }
    }
    

    Class Cell包含有关单元格的信息(状态,颜色,数字......)。

        import java.awt.Color;
        import java.awt.Rectangle;
        import java.awt.Shape;
        import java.awt.geom.AffineTransform;
        import java.awt.geom.PathIterator;
        import java.awt.geom.Point2D;
        import java.awt.geom.Rectangle2D;
    
        public class Cell implements Shape{
    
            private int centerX;
            private int centerY;
            private double side;
            private Color cellColor;
            private double x;
            private double y;
            private Shape cellShape;
            private CellState cellState;
            private int numberOfCell;
    
            public Cell(int centerX, int centerY, int side, Color cellColor,Shape cellShape, CellState cellState,int numberOfCell){
                super();
                this.centerX=centerX;
                this.centerY=centerY;
                this.side=side;
                this.cellColor=cellColor;
                this.cellShape=cellShape;
                this.cellState=cellState;
                this.numberOfCell=numberOfCell;
            }
        public Shape getCellShape() {
            return cellShape;
        }
    
        public int getNumberOfCell() {
            return numberOfCell;
        }
    
        public Color getCellColor() {
            return cellColor;
        }
    
        public void setCellColor(Color cellColor) {
            this.cellColor = cellColor;
        }
    
        public void setCellShape(Shape cellShape) {
            this.cellShape = cellShape;
        }
    
        public double getSide() {
            return side;
        }
        public double getX() {
            return x;
        }
        public double getY() {
            return y;
        }
        public CellState getCellState() {
            return cellState;
        }
    
        public void setCellState(CellState cellState) {
            this.cellState = cellState;
        }
    
        @Override
        public boolean contains(Point2D p) {
            // TODO Auto-generated method stub
            return false;
        }
        @Override
        public boolean contains(Rectangle2D r) {
            // TODO Auto-generated method stub
            return false;
        }
        @Override
        public boolean contains(double x, double y) {
            // TODO Auto-generated method stub
            return false;
        }
        @Override
        public boolean contains(double x, double y, double w, double h) {
            // TODO Auto-generated method stub
            return false;
        }
        @Override
        public Rectangle getBounds() {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        public Rectangle2D getBounds2D() {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        public PathIterator getPathIterator(AffineTransform at) {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        public PathIterator getPathIterator(AffineTransform at, double flatness) {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        public boolean intersects(Rectangle2D r) {
            // TODO Auto-generated method stub
            return false;
        }
        @Override
        public boolean intersects(double x, double y, double w, double h) {
            // TODO Auto-generated method stub
            return false;
        }
    
    }
    

    Class CellState

    public enum CellState {
    
        STARTCELL,ENDCELL,EMPTYCELL,BLOCKEDCELL;
    }
    

1 个答案:

答案 0 :(得分:0)

我不能给出章节和经文的答案,不是没有你的MCVE,但我可以给你一个大的建议。请注意,选择空单元格和被阻止单元格在逻辑上与选择开始和结束单元格完全不同,因此您的代码应以非常不同的方式执行这些操作。我要做的是,在鼠标监听器中,检查按下了哪个按钮。如果是左按钮(标准按钮),则切换单元格阻塞/空状态(但仅当它不是已开始或结束单元格时)。如果按下鼠标右键(如果没有鼠标按钮,则按alt鼠标),然后显示一个弹出菜单,允许用户选择单元格作为开始或结束单元格。选择开始或结束的代码将与空/块切换代码分开,首先遍历模型,清除前一个开始或结束单元格,然后进行设置。

如果您想要更完整的解决方案,请再次在此处发布您的有效Minimal, Complete, and Verifiable example代码(不在链接中)。

运气。