I need to highlight different cells of a grid. In each iteration of my algorithm, a co-ordinate (i,j)
is obtained. I pass these values to the Grid
to the current_x
and current_y
variables. How do I color the corresponding cell by calling the paintComponent()
method of the TestPane
class.
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 am not clear as to how to pass the (i,j)
values to the TestPane
class and how to call the paintComponent
.
setGridX(int x)
and setGridY(int y)
methods.repaint()
on the TestPane instance.Edit
New code that actually demonstrates my recommendations:
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;
}
}
I am currently creating a TestPane object in the Grid class.
Yep, you definitely want to do this.
So should I create one in the main Driver class?
No, there should only be one TestPane instance. If it is needed in two locations, create it once, and pass it to the other via a method or constructor parameter.
Also, how should I trigger the calling of this repaint() method? I am not so clear still.
That all depends on what will trigger a change in your current_x and current_y values. You will likely need a listener of some sort, perhaps a MouseListener. In my example, I use an ActionListener held by a Swing Timer to randomly move the selected x and y values.
Edit 2
You state:
my trigger is - in each iteration of the algorithm - I get new (i,j) values.. so how so I incorporate that..
You would likely do the iteration in a background thread such as can be obtained with a SwingWorker object, and then call the TestPane's setGridX and setGridY method, and repaint.