How do i make each of the buttons highlight when i hover - java

I'm trying to make the buttons highlight (by changing color) when i am hovering above them with my mouse.
this is my code;
import javax.swing.JOptionPane;
final int BUTTON_WIDTH = 100;
final int BUTTON_HEIGHT = 50;
int buttonX = 0;
int COLOR = 150;
void setup() {
size(800, 400);
}
void draw() {
for (int i=0; i<=8; i++) {
drawButtons();
buttonX = buttonX+BUTTON_WIDTH;
}
}
void drawButtons() {
strokeWeight(2);
fill(0, COLOR, COLOR);
rect(buttonX, 0, BUTTON_WIDTH, BUTTON_HEIGHT);
}
I thought it would work if i add this ;
if(mouseX<BUTTON_WIDTH && mouseY<BUTTON_HEIGHT){
COLOR = 255;
}
It does not work though, i am trying to make the button highlight when the mouse is over it and the other buttons would remain unchanged.

Your condition in the draw (before drawing the buttons) is wrong. Here a correct version of your program :
final int BUTTON_WIDTH = 100;
final int BUTTON_HEIGHT = 50;
int buttonX = 0;
void setup() {
size(800, 400);
strokeWeight(2);
}
void draw() {
for (int i=0; i<=8; i++) {
// The condition was wrong before, now it checks if you are on a button
if(buttonX <= mouseX && mouseX < buttonX + BUTTON_WIDTH && mouseY<BUTTON_HEIGHT){
fill(0, 255, 255);
} else {
fill(0, 150, 150);
}
rect(buttonX, 0, BUTTON_WIDTH, BUTTON_HEIGHT);
buttonX += BUTTON_WIDTH;
}
buttonX = 0; // don't forget to put buttonX at 0 after the for loop, or the next buttons drawn are going to be invisible (on the right of the canva) and you won't see the color change.
}
Now it should be ok !

Related

How to make object dissapear when hit

I was working on a brick breaker game in proccessing, and was trying to create the collision system for the game. I was able to identify when a collision happens between the ball and the brick, but I was not able to to make the brick dissapear when it gets hit by the ball. How do I do this? I would also appreciate a explanation, as I am a beginner.
Thanks.
color black = color(0,0,0);
color red = color(255,0,0);
color white = color(255,255,255);
float ballx = 412.5, bally = 600, balld = 20, ballr = balld/2, paddleX = 362.5, paddleY = 650;
float paddleW = 100, paddleH = 15;
float ballspdX, ballspdY;
boolean ball_drop = true;
float direction_choice;
float[] brickX = new float[10];
float[] brickY = new float[5];
float brickW = 50, brickH = 25;
void setup(){
size(825,800);
surface.setTitle("Brick breaker");
noCursor();
smooth();
brickX[0] = 50;
brickX[1] = 125;
brickX[2] = 200;
brickX[3] = 275;
brickX[4] = 350;
brickX[5] = 425;
brickX[6] = 500;
brickX[7] = 575;
brickX[8] = 650;
brickX[9] = 725;
brickY[0] = 50;
brickY[1] = 125;
brickY[2] = 200;
brickY[3] = 275;
brickY[4] = 350;
}
void paddle(){
noStroke();
fill(white);
rect(paddleX, paddleY, paddleW, paddleH);
}
void ball(){
noStroke();
fill(red);
circle(ballx, bally, balld);
}
void draw(){
background(black);
paddle();
ball();
if (bally + ballr == paddleY && ballx > paddleX && ballx < paddleX + (paddleW / 2)){
ball_drop = false;
ballspdY = -ballspdY;
ballspdX = -4;
}
/*
if (bally + ballr == paddleY && ballx > paddleX && ballx < paddleX + paddleW){
ball_drop = false;
ballspdY = -ballspdY;
direction_choice = int(random(1,3));
if (direction_choice == 1){
ballspdX = 4;
}
if (direction_choice == 2){
ballspdX = -4;
}
}
println(direction_choice);
*/
if (bally + ballr == paddleY && ballx > paddleX + (paddleW /2) && ballx < paddleX + paddleW){
ball_drop = false;
ballspdY = -ballspdY;
ballspdX = 4;
}
if (ballx + ballr > width || ballx - ballr < 0){
ballspdX = -ballspdX;
}
if (bally - ballr < 0){
ballspdY = -ballspdY;
}
if (ball_drop){
ballspdX = 0;
ballspdY = 1;
}
for (int i = 0; i < brickX.length; i ++){
for(int j = 0; j < brickY.length; j ++){
fill(red);
rect(brickX[i], brickY[j], brickW, brickH);
if (collideLineCircle(brickX[i], brickY[j] + brickH, brickX[i] + brickW, brickY[j] + brickH, ballx, bally, ballr)){
ballspdY = -ballspdY;
}
}
}
if (bally >= 800){
bally = 600;
ballx = 412.5;
ball_drop = true;
}
bally += ballspdY;
ballx += ballspdX;
}
boolean collideLineCircle(float x1, float y1, float x2, float y2, float cx, float cy, float cr){
float A = y2 - y1, B = x1 - x2, C = x2*y1 - x1+y2;
float denom = A+A + B*B;
if (denom == 0){
return dist(x1,y1, cx, cy) < cr;
}
float Ix = (B*B*cx-A*B*cy - A*C)/denom, Iy = (A*A*cy-A*B*cx - B*C)/denom;
if (Ix >= min(x1,x2) && Ix <= max(x1,x2) & Iy >= min(y1,y2) && Iy <= max(y1,y2)) {
return abs (A*cx + B*cy + C)/sqrt(denom) < cr;
}
float d1 = dist(x1,y1,cx,cy), d2 = dist(x2,y2,cx,cy);
return min(d1,d2) < cr;
}
void mouseMoved(MouseEvent evt){
paddleX = evt.getX();
}
There are a number of ways this can be done. Perhaps the simplest change, given the data structures you already have is to create another array, this time a boolean array, and call it something like brickIsVisible.
Then you can use a simple if statement, e.g., if (brickIsVisible[i]) in your loops to determine how to color the brick. The same variable can be used to tell whether or not to do a collision test between the ball and the brick.
As for the coloring itself, there are a couple options.
I'm not sure how you are drawing your board. If you redraw the entire board with each gameloop frame, then presumably you first draw the background (which covers over the bricks) and then you draw the bricks. If this what is happening, then if brickIsVisible[i] is false you can simply omit drawing that brick on top of the background.
Another technique that is sometimes used is to make use of a transparent color. This is done by adding an alpha channel value to the color definition. Thus there are four variables instead of three. They are referred to as RGBA instead of RGB. If the fourth variable is 0, the color will be transparent. If it is 255 it will be fully visible. Intermediate values in sequence can be used if you want to create a fade in or fade out.
I am guessing you are using java.awt.Color. Following is an example that uses the four argument constructor, with the fourth being the alpha channel.
Color invisiblePurple = new Color(255, 0, 255, 0);
If the color is invisible, the RGB values don't really matter.
These days I mostly use JavaFX for graphics, so I might not be up on all the tricks of the trade with AWT/Swing. With JavaFX, one can directly set an opacity property for a graphic being displayed, which is pretty convenient. I think part of the reason that this is available in JavaFX is that screen graphics are structured more like a DOM tree (like an HTML domain object model), and the redrawing is handled behind the scenes on the current state of the tree, rather than explicitly for each object, as it is with AWT/Swing.
Another possible technique shown below uses a brick class array. The class has a 'show' boolean associated with it and the bricks are only displayed when brick[id].show is true. In this demo when the brick is selected with a mouse brick[id].show is set to false and that brick is not displayed. For your project you would have to do this when a brick is hit by the ball.
/*
Creates a grid of rectangles from a Brick class array.
Syntax: brick[id] = new Brick( x, y, w, h, "title", bkgrndColor, txtColor);
ID is taken from position in array.
*/
final int _brickGridX = 40;
final int _brickGridY = 60;
final int _brickW = 120;
final int _brickH = 60;
color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
Brick[] brick;
class Brick {
float x, y, w, h;
String title;
color bkgrnd;
color txtColor;
boolean show;
// Constructor
Brick(int xpos, int ypos, float wt, float ht, String titleStr, color background, color foreground) {
x = xpos;
y = ypos;
w = wt;
h = ht;
title = titleStr;
bkgrnd = background;
txtColor = foreground;
}
void display(int id) {
if (brick[id].show) {
fill(bkgrnd); // background color
stroke(0);
rect(x, y, w, h);
fill(txtColor); // text color
textSize(42);
textAlign(CENTER, CENTER);
text(title, x, y, w, h);
}
}
void press(int id) {
println("brick id = ", id + ": show =", brick[id].show);
}
}
void brickGrid() {
int left = 0;
int top = 0;
int vg = 0; // Space between cols (vert.gutter)
int hg = 0; // Space between rows (horz.gutter)
int rows = 5;
int cols = 5;
int id = 0;
brick = new Brick[rows*cols]; // creates brick array
for (int k = 0; k < cols; k++) {
for (int j = 0; j < rows; j++) {
left = _brickGridX + j * (_brickW + vg);
top = _brickGridY + k * (_brickH + hg);
brick[id] = new Brick(left, top, _brickW, _brickH, str(id), LTGRAY, BLACK);
brick[id].show = true;
id++;
}
}
}
void setup() {
size(800, 600);
background(BLUE);
brickGrid();
}
void draw() {
background(BLUE);
for (int i = 0; i < brick.length; i++) {
brick[i].display(i);
}
}
void mousePressed() {
for (int i = 0; i < brick.length; i++) {
if ((mouseX >= brick[i].x) && (mouseX <= brick[i].x + _brickW) && (mouseY >= brick[i].y) && (mouseY <= brick[i].y + _brickH)) {
brick[i].show = false;
// brick[i].press(i);
}
}
}

Adding Element to Class Array with function. "Paint" in Processing 3

I'm trying to create a "Paint" application with Processing 3, and I want to add buttons to change the color (later on for brushes, size, etc).
I'm stuck because I'm keep getting a NullPointerException for adding the button to my array.
(I know i could just ask for the mouseX and Y after creating every button without the array but it seems a bit unprofessional to me and would get very messy by time).
ERROR: Line 24 -> "allButtons[counter].name = Name;"
*Sidenote: I'm pretty new to Processing / Java xd
This is my code:
class button
{
public String name;
public int x;
public int y;
public color curColor;
};
color currentColor = color(0, 0, 0);
String currentBrush = "Brush";
int currentBrushSize = 3;
button[] allButtons = new button[100];
int buttonSize = 20;
int counter = 1;
void setup() {
size(800, 600);
background(255);
surface.setResizable(true);
surface.setTitle("Not Skribble");
}
void button(String Name, int X, int Y, color CurColor) {
allButtons[counter].name = Name;
allButtons[counter].x = X;
allButtons[counter].y = Y;
allButtons[counter].curColor = CurColor;
counter += 1;
fill(CurColor);
rect(X, Y, buttonSize, buttonSize);
if (overButton(X, Y, X + buttonSize, Y + buttonSize)) {
fill(0, 0, 0, 80);
rect(X, Y, buttonSize, buttonSize);
}
}
boolean overButton(int minX, int minY, int maxX, int maxY) {
if (mouseX >= minX && mouseX <= maxX) {
if (mouseY >= minY && mouseY <= maxY) {
return true;
}
}
return false;
}
boolean buttonPressed(String name) {
for (int i = 0; i < allButtons.length; i++) {
if (name == allButtons[i].name) {
if (mouseX >= allButtons[i].x && mouseX <= allButtons[i].x + buttonSize) {
if (mouseY >= allButtons[i].y && mouseY <= allButtons[i].y + buttonSize) {
if (mousePressed) {
return true;
}
}
}
}
}
return false;
}
void setColor(color settingColor) {
currentColor = settingColor;
}
void setBrush(String settingBrush) {
currentBrush = settingBrush;
}
void setBrushSize(int settingBrushSize) {
currentBrushSize = settingBrushSize;
}
void colorButtons() {
button("Orange", 10, 10, color(255, 100, 0));
if (buttonPressed("Orange")) setColor(color(255, 100, 0));
button("Blue", 50, 10, color(255, 100, 0));
if (buttonPressed("Blue")) setColor(color(0, 0, 255));
}
void brushButtons(){
}
void settingButtons(){
}
void draw() {
noStroke();
fill(100);
rect(0, 0, width, 70);
colorButtons();
brushButtons();
settingButtons();
}
When you create an array like this:
Button[] allButtons = new Button[100];
You're creating an array that can hold 100 Button instances. But that array starts out as empty. Try doing something like this:
println(allButtons[0]);
You'll see that this prints out null, which means that the value is basically empty. You haven't actually added any Button instances to your array. This is why you're getting an error: because you're trying to use values that don't exist.
To add an instance to your array, you'd do something like this:
allButtons[0] = new Button();
At which point it would be safe to do use that value:
allButtons[0].name = "cancel";
By the way, you might consider just using an ArrayList instead of an array. Or take advantage of Processing's array functions that allow you to add elements to an array instead of creating an array with a size of 100.
Also, in the future please try to use proper naming conventions. Variables should start with a lower-case letter, and classes should start with an upper-case letter. This makes your code much easier to read.

drawString() isn't drawing the String on my game

I am using drawString() to write text on the string, but nothing shows up. I set the color to white and set the coordinates to (100,100). Is there anything else that I am doing wrong?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
public class Screen extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800, HEIGHT = 800;
private Thread thread;
private boolean running = false;
private BodyPart b;
private ArrayList<BodyPart> snake;
private Apple apple;
private ArrayList<Apple> apples;
private Random r;
private int xCoor = 20, yCoor = 20;
private int size = 10;
private int score = 0;
private boolean right = true, left = false, up = false, down = false;
private int ticks = 0;
private Key key;
public Screen() {
setFocusable(true);
key = new Key();
addKeyListener(key);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
r = new Random();
snake = new ArrayList<BodyPart>();
apples = new ArrayList<Apple>();
start();
}
public void reset() {
snake.clear();
apples.clear();
xCoor = 20;
yCoor = 20;
size = 10;
score = 0;
running = true;
}
public void tick() {
if(snake.size() == 0) {
b = new BodyPart(xCoor, yCoor, 20);
snake.add(b);
}
if(apples.size() == 0) {
int xCoor = r.nextInt(40);
int yCoor = r.nextInt(40);
apple = new Apple(xCoor, yCoor, 20);
apples.add(apple);
}
for(int i = 0; i < apples.size(); i++) {
if(xCoor == apples.get(i).getxCoor() && yCoor == apples.get(i).getyCoor()) {
size++;
apples.remove(i);
score += 10;
i--;
}
}
for(int i = 0; i < snake.size(); i++) {
if(xCoor == snake.get(i).getxCoor() && yCoor == snake.get(i).getyCoor()) {
if(i != snake.size() - 1) {
reset();
}
}
}
if(xCoor < 0) xCoor = 40;
if(xCoor > 40) xCoor = 0;
if(yCoor < 0) yCoor = 40;
if(yCoor > 40) yCoor = 0;
ticks++;
if(ticks > 250000) {
if(right) xCoor++;
if(left) xCoor--;
if(up) yCoor--;
if(down) yCoor++;
ticks = 185000;
b = new BodyPart(xCoor, yCoor, 20);
snake.add(b);
if(snake.size() > size) {
snake.remove(0);
}
}
}
public void paint(Graphics g) {
g.clearRect(0, 0, WIDTH, HEIGHT);
g.drawString("Score: " + score, 100, 100);
g.setColor(Color.WHITE);
g.setColor(new Color(20, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
for(int i = 0; i < WIDTH / 20; i++) {
g.drawLine(i * 20, 0, i * 20, HEIGHT);
}
for(int i = 0; i < HEIGHT / 20; i++) {
g.drawLine(0, i * 20, WIDTH, i * 20);
}
for(int i = 0; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for(int i = 0; i < apples.size(); i++) {
apples.get(i).draw(g);
}
}
public void start() {
running = true;
thread = new Thread(this, "Game Loop");
thread.start();
}
public void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while(running) {
tick();
repaint();
}
}
private class Key implements KeyListener {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
right = true;
}
if(key == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
}
if(key == KeyEvent.VK_UP && !down) {
left = false;
right = false;
up = true;
}
if(key == KeyEvent.VK_DOWN && !up) {
left = false;
right = false;
down = true;
}
}
}
The order in which you do things is very important, remember, painting in Swing is like painting on paper, if you paint the text first, then paint over it, it will no longer be visible...
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(20, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
for (int i = 0; i < WIDTH / 20; i++) {
g.drawLine(i * 20, 0, i * 20, HEIGHT);
}
for (int i = 0; i < HEIGHT / 20; i++) {
g.drawLine(0, i * 20, WIDTH, i * 20);
}
for (int i = 0; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for (int i = 0; i < apples.size(); i++) {
apples.get(i).draw(g);
}
g.setColor(Color.WHITE);
g.drawString("Score: " + score, 100, 100);
}
Don't override paint, override paintComponent, you've circumvented the painting process, meaning you could end up with all sorts of nasty glitches
Call super.paintComponent
Take a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting is done.
Swing is also not thread safe and you need to be careful any time you are changing anything that the paint process uses to update the UI, as painting may occur at any time and for any reason.
Consider using a Swing Timer instead of Thread. The timer executes it's tick events within the context of the Event Dispatching Thread, making it safer to update the UI from within. See Creating a GUI With JFC/Swing
You have a few things in the wrong order. When painting, you need to paint in the correct order, otherwise you will paint over the top of other objects.
So, in your code, the first 5 lines of the paint() method should look like this... (note the same code, but a different order)
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(new Color(20, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.WHITE);
g.drawString("Score: " + score, 100, 100);
You need to paint the background color first. Then you can paint the String on top of it.

Image not showing on JLabel

I've been tasked to make a java replica of Candy Crush Saga.
Right now im quite stuck on the GUI part.
I've decided that each candy will be represented by a JLabel holding the candy icon, and a mouselistener to control the functionality.
What happens is, after i finish running the screen shows, the mouse listeners respond but the image doesn't show, meaning i can press the labels get a response but cannot see the icons. I take this as the labels are on the panel but somehow not visible or the icon is not loaded correctly - although when checking the ImageIcon.toString it shows the path to the file.
Any ideas?
Here is the code:
public class Board extends JPanel {
Candy[][] board;
static final int TILE_SIZE = 55;
static final int TILES_MARGIN = 8;
public Board() {
setFocusable(true);
board = new Candy[13][13];
Candy c;
for (int i = 0; i < 13; i++)
for (int j = 0; j < 13; j++) {
if (i != 0 && i != 1 && j != 0 && j != 1 && i != 11 && i != 12 && j != 11 && j != 12) {
Random rand = new Random();
int randomNum = rand.nextInt((6 - 1) + 1) + 1;
c = new Basic(randomNum, this);
} else {
c = new Basic(0, this);
}
setAt(i, j, c);
}
repaint();
}
public void drawCandy(Graphics g2, Candy candy, int x, int y) {
Graphics2D g = ((Graphics2D) g2);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
int value = candy.getClr();
int xOffset = offsetCoors(x);
int yOffset = offsetCoors(y);
ImageIcon myImg = candy.switchIcon();
JLabel toAdd = new JLabel(myImg);
toAdd.setIcon(myImg);
toAdd.setLocation(xOffset,yOffset);
toAdd.setSize(TILE_SIZE,TILE_SIZE);
toAdd.addMouseListener(new ButtonPressed(x,y,candy));
toAdd.setVisible(true);
if (value != 0)
add(toAdd);
}
private static int offsetCoors(int arg) {
return (arg-2) * (TILES_MARGIN + TILE_SIZE) + TILES_MARGIN;
}
public void paint(Graphics g) {
super.paint(g);
removeAll();
requestFocusInWindow();
g.setColor(Color.black);
g.fillRect(0, 0, this.getSize().width, this.getSize().height);
for (int x = 2; x < 11; x++) {
for (int y = 2; y < 11; y++) {
drawCandy(g, board[x][y], x, y);
}
}
validate();
}
and the JFrame :
public Game() {
super("Candy Crush Game");
setDefaultLookAndFeelDecorated(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
setSize(600, 600);
setResizable(false);
setLocationRelativeTo(null);
this.board = new Board();
this.score = 0;
this.moves = 20;
this.getContentPane().add(board, BorderLayout.CENTER);
setVisible(true);
board.checkSquare(2, 2, 10, 10);
}
I'm quite frustrated, any help will be great!
Instead of overriding paint() method use paintComponent() method for JPanel.
#Overrie
public void paintComponent(Graphics g) {
super.paintComponent(g);
//your custom painting here
}
Read more
Painting in AWT and Swing
paintComponent() vs paint() and JPanel vs Canvas in a paintbrush-type GUI
There might be some issue in reading image icon. My another post might help you.
ImageIcon does not work with me
Instead of creating new JLabel simply change it's icon.

Painted rectangles not showing up

I've been trying for quite a while to get this to work and done a lot of research but I can't work out why it's not happening: My end goal is get a grid of x by y green squares, and when you click on a square it changes colour. (this is part of a bigger project)
Now I am aware that this is probably a very inefficient way of doing so, but I've tried different ways and nothing seems to work.
In my Grid class I have this:
squares = new Square[width][height];
for (int i = 0; i < width; i++){
for (int j = 0; j < height; j++){
squares[i][j] = new Square(i,j);
frame.getContentPane().add(squares[i][j]);
}
}
And this is my Square class:
public class Square extends JLabel implements MouseListener{
private int x,y,width,height, mouseX,mouseY;
private Color colour = Color.GREEN;
public Square(int width, int height){
this.x = width*45;
this.y = height*45;
addMouseListener(this);
this.setBounds(x, y, 45, 45);
}
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setColor(colour);
g2.fillRect(x, y, 45, 45);
}
#Override
public void mouseClicked(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
if(mouseX > x && mouseX < x+45 && mouseY > y && mouseY < y+45){
if(colour.equals(Color.GREEN)){
colour = Color.RED;
} else{
colour = Color.GREEN;
}
repaint();
}
}
}
However when I run the code, all I see is the first square and the last square; how come?
If you have any tips of how I could have done this far more efficiently, please do tell and criticize this code.
To solve your problem. You need to change your code in some places.
1) You don't need to pass x, y co-ordinates with Square() constructor. Declare empty constructor like this:
public Square() {
addMouseListener(this);
this.setBounds(x, y, 45, 45);
}
2) Set GridLayout to your JFrame.
frame.setLayout(new GridLayout(width, height));
3) Call empty constructor on your loop.
Square[][] squares = new Square[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
squares[i][j] = new Square();
frame.add(squares[i][j]);
}
}

Categories