我需要突出显示网格的不同单元格。在我的算法的每次迭代中,均获得坐标(i,j)。我将这些值传递给Gridcurrent_xcurrent_y变量。如何通过调用paintComponent()类的TestPane方法为相应的单元格着色。

public class Grid {

    int current_x;
    int current_y;

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

    public Grid() {
        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 void getCurrentValues( int x, int y ){

        this.current_x = x;
        this.current_y = y;
    }

    public class TestPane extends JPanel {

        // code to create grid using rectangles

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // more code
        }

    }
}


我不清楚如何将(i,j)值传递给TestPane类以及如何调用paintComponent

最佳答案

给出TestPane setGridX(int x)setGridY(int y)方法。
给需要调用这些方法的任何类提供对显示的TestPane实例的引用。
当触发更改的事件发生时调用方法。然后在TestPane实例上调用repaint()




编辑
实际证明我的建议的新代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;

public class Grid {
   private static final int TIMER_DELAY = 200;
   private int current_x;
   private int current_y;
   private TestPane testPane = new TestPane();
   private Random random = new Random();

   public Grid() {
      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.add(testPane); // !!
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
         }
      });
      new Timer(TIMER_DELAY, new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent evt) {
            current_x = random.nextInt(TestPane.MAX_X);
            current_y = random.nextInt(TestPane.MAX_Y);
            testPane.setGridX(current_x);
            testPane.setGridY(current_y);
            testPane.repaint();
         }
      }).start();
   }

   public void getCurrentValues(int x, int y) {
      this.current_x = x;
      this.current_y = y;
   }

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

class TestPane extends JPanel {
   public static final int MAX_X = 8;
   public static final int MAX_Y = MAX_X;
   private static final int CELL_WIDTH = 50;
   private static final int PREF_W = CELL_WIDTH * MAX_X;
   private static final int PREF_H = CELL_WIDTH * MAX_Y;
   private static final Color FILL_COLOR = Color.yellow;
   private static final Color GRID_COLOR = Color.black;
   private int gridX = -1;
   private int gridY = -1;

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      for (int y = 0; y < MAX_Y; y++) {
         for (int x = 0; x < MAX_X; x++) {
            if (x == gridX && y == gridY) {
               g.setColor(FILL_COLOR);
               g.fillRect(x * CELL_WIDTH, y * CELL_WIDTH, CELL_WIDTH, CELL_WIDTH);
            }
            g.setColor(GRID_COLOR);
            g.drawRect(x * CELL_WIDTH, y * CELL_WIDTH, CELL_WIDTH, CELL_WIDTH);
         }
      }
   }

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

   public int getGridX() {
      return gridX;
   }

   public void setGridX(int gridX) {
      this.gridX = gridX;
   }

   public int getGridY() {
      return gridY;
   }

   public void setGridY(int gridY) {
      this.gridY = gridY;
   }
}





  我目前正在Grid类中创建一个TestPane对象。


是的,您一定要这样做。


  那么我应该在主Driver类中创建一个吗?


不,应该只有一个TestPane实例。如果在两个位置都需要它,则创建一次,然后通过方法或构造函数参数将其传递给另一个。


  另外,如何触发该repaint()方法的调用?我还是不太清楚。


所有这些取决于将触发您的current_x和current_y值变化的原因。您可能需要某种侦听器,也许是MouseListener。在我的示例中,我使用Swing计时器持有的ActionListener来随机移动选定的x和y值。



编辑2
您声明:


  我的触发器是-在算法的每次迭代中-我都获得了新的(i,j)值。


您可能会在诸如使用SwingWorker对象获得的后台线程中进行迭代,然后调用TestPane的setGridX和setGridY方法并重新绘制。

09-07 16:34