How to draw a wall in paint method based on user input - java

I fairly new to programming and I have decided to take an intro to java class. I have an assignment where I have to create a wall using a for loop that changes height of the wall based on user input. I think I got most of the code right but I can't seem to connect the user input with the for loop. Any help would be appreciated.
//Package List
import java.awt.*;
import java.applet.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
public class Wall extends JApplet implements ActionListener{
//Component declaration
JLabel directions;
JTextField input = new JTextField( 10 );
private JButton go;
//Variable declaration
int userinput;
//Method declaration
public void init()
{
getContentPane().setBackground(new Color (128, 128, 128));//Changes backround of JApplet to black
//Set JButton and JLabel
setLayout (new FlowLayout( ));
directions = new JLabel("Enter in any number between 1 and 20 and then press Enter on your keyboard.");
go = new JButton( "Go!" );
go.setBackground( Color.GREEN );
go.setFocusPainted( false );
go.addActionListener( this );
add (directions );
add (input);
add( go );
}
public void actionPerformed( ActionEvent ae )
{
String text = input.getText();
userinput = Integer.parseInt( text );
repaint();
}
//Method declaration
public void paint(Graphics g)
{
super.paint(g);
int startX = 50;
int startY = 650;
int width = 50;
int height = 20;
int spacing = 2;
int xOffset = 0;
for (int row = 0; row < userinput; row++) {
int y = startY + (row * ( height + spacing));
if ( row % 2 == 0) {
xOffset = width / 2;
} else {
xOffset = 0;
}
for (int col = 0; col < 8; col++) {
int x = xOffset + (startX + (col * (width + spacing)));
System.out.println(x + "x" + y);
g.setColor( Color.RED );
g.fillRect( x, y, width, height);
}
}
}
}

Basically, your code works, but your starty is to large and seems to be painting off the screen.
Generally, you should avoid overriding paint of top level containers like JApplet (why are using applets?!) and instead, use a component like JPanel instead.
A few reasons for this, but the one you will run into is that paint can paint over the child components, BUT, because of the way painting works, those child components, when updated, can paint over what you've painted ... which altogether, is just weird for the user.
Instead, separate you code into logic units, each unit should be responsible for a single unit (of logic) work
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Wall extends JApplet implements ActionListener {
//Component declaration
JLabel directions;
JTextField input = new JTextField(10);
private JButton go;
private WallPanel wallPanel;
//Method declaration
public void init() {
getContentPane().setBackground(new Color(128, 128, 128));//Changes backround of JApplet to black
//Set JButton and JLabel
setLayout(new BorderLayout());
JPanel controls = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
directions = new JLabel("Enter in any number between 1 and 20 and then press Enter on your keyboard.");
go = new JButton("Go!");
go.setBackground(Color.GREEN);
go.setFocusPainted(false);
go.addActionListener(this);
controls.add(directions, gbc);
controls.add(input, gbc);
controls.add(go, gbc);
wallPanel = new WallPanel();
add(controls, BorderLayout.NORTH);
add(wallPanel);
}
public void actionPerformed(ActionEvent ae) {
String text = input.getText();
wallPanel.setRowCount(Integer.parseInt(text));
repaint();
}
public class WallPanel extends JPanel {
private int rowCount;
public void setRowCount(int rowCount) {
this.rowCount = rowCount;
repaint();
}
public int getRowCount() {
return rowCount;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int startX = 50;
int startY = 0;
int width = 50;
int height = 20;
int spacing = 2;
int xOffset = 0;
for (int row = 0; row < getRowCount(); row++) {
int y = startY + (row * (height + spacing));
if (row % 2 == 0) {
xOffset = width / 2;
} else {
xOffset = 0;
}
for (int col = 0; col < 8; col++) {
int x = xOffset + (startX + (col * (width + spacing)));
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
}
}
}
}
}
So, basically, all I've done here is move the "wall painting" to it's own component/class and provided a simple setter (and getter) for changing the number of rows

Related

Java AWT Graphics Class: Making Rows and Columns of Squares

I'm using the java.awt graphics class, and I'm trying to make rows and squares.
I can't seem to get the layout of the rows correctly.
I'm trying to code 8 rows with 3 columns each. However, I just get 2 rows with 12 columns.
If somebody can help me to create the outcome that I want, that would be greatly appreciated.
Here's my code:
g.setColor(Color.WHITE);
int x = 70;
int y = 80;
int w = 30;
int h = 35;
for(int row = 0; row < 3; row++) {
for(int col = 0; col < 4; col++) {
g.fillRect( x, y, w, h );
g.fillRect( x, y + h + 20, w, h );
x += w + 15;
}
System.out.println();
}
Here's the output: 2 rows, 12 columns of squares
Beware of how you are updating your position information. For example, you should only be updating the x position in the inner loop and resetting to 0 before entering the inner loop, and the y position should only be updated on each new row.
Alternatively, you could calculate the position directly, based on the row/column index and the row/column height, as demonstrated below.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
private static int COLUMN_COUNT = 3;
private static int ROW_COUNT = 8;
private static int COLUMN_WIDTH = 30;
private static int ROW_HEIGHT = 35;
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(3 * COLUMN_WIDTH, 8 * ROW_HEIGHT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int columnWidth = getWidth() / 3;
int rowHeight = getHeight() / 8;
int x = 0;
int y = 0;
for (int row = 0; row < ROW_COUNT; row++) {
for (int col = 0; col < COLUMN_COUNT ; col++) {
if (col % 2 == 0) {
x = columnWidth * col;
y = rowHeight * row;
g2d.fillRect(x + 2, y + 2, columnWidth - 4, rowHeight - 4);
}
}
}
g2d.dispose();
}
}
}

Java - Hexagon location in grid

Im searching for an algorythem to get the location of a hexagon in a grid.
I found this one but it doesnt seam to work:
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
grid[i][j] = new Hexagon(x+(j*((3*Hexagon.S)/2)), y+((j%2)*Hexagon.A)+(2*i*Hexagon.A));
}
}
The output is kind of strange:
output
This is the window-creating class(just a test class):
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Grid extends JPanel {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
int width = 2;
int height = 4;
int x = 100;
int y = 100;
Hexagon[][] grid = new Hexagon[width][height];
JFrame f = new JFrame();
Container cp = f.getContentPane();
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
grid[i][j] = new Hexagon(x+(j*((3*Hexagon.S)/2)), y+((j%2)*Hexagon.A)+(2*i*Hexagon.A));
cp.add(grid[i][j]);
}
}
f.setLayout(null);
f.setBounds(100, 100, 300, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
The Hexagon.java class:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.swing.JButton;
public class Hexagon extends JButton {
public static final int S = 50;
public static final int A = (int) (Math.sqrt(3)*(S/2));
private static final long serialVersionUID = 1L;
private final int x, y;
private final Polygon shape;
public Hexagon(int x, int y) {
this.x = x;
this.y = y;
this.shape = initHexagon();
setSize(2*S, 2*A);
setLocation(x-S, y-A);
setContentAreaFilled(false);
}
private Polygon initHexagon() {
Polygon p = new Polygon();
p.addPoint(x+(S/2), y-A);
p.addPoint(x+S, y);
p.addPoint(x+(S/2), y+A);
p.addPoint(x-(S/2), y+A);
p.addPoint(x-S, y);
p.addPoint(x-(S/2), y-A);
return p;
}
protected void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.drawPolygon(this.shape);
}
protected void paintBorder(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(4));
g2.drawPolygon(this.shape);
}
public boolean contains(int x, int y) {
return this.shape.contains(x, y);
}
}
As i said, this class worked just fine using non-rectangular shapes.
There was no clipping or such.
You've posted your definition of Hexagon too late, so I copy-pasted a modified version of a similar class from my collection of code snippets.
Here is one way to generate a hexagonal grid:
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.function.*;
public class Hexagons extends JPanel {
private static final long serialVersionUID = 1L;
/** Height of an equilateral triangle with side length = 1 */
private static final double H = Math.sqrt(3) / 2;
static class Hexagon {
final int row;
final int col;
final double sideLength;
public Hexagon(int r, int c, double a) {
this.row = r;
this.col = c;
this.sideLength = a;
}
double getCenterX() {
return 2 * H * sideLength * (col + (row % 2) * 0.5);
}
double getCenterY() {
return 3 * sideLength / 2 * row;
}
void foreachVertex(BiConsumer<Double, Double> f) {
double cx = getCenterX();
double cy = getCenterY();
f.accept(cx + 0, cy + sideLength);
f.accept(cx - H * sideLength, cy + 0.5 * sideLength);
f.accept(cx - H * sideLength, cy - 0.5 * sideLength);
f.accept(cx + 0, cy - sideLength);
f.accept(cx + H * sideLength, cy - 0.5 * sideLength);
f.accept(cx + H * sideLength, cy + 0.5 * sideLength);
}
}
public static void main(String[] args) {
final int width = 50;
final int height = 50;
final Hexagon[][] grid = new Hexagon[height][width];
for(int row = 0; row < height; row++) {
for(int col = 0; col < width; col++) {
grid[row][col] = new Hexagon(row, col, 50);
}
}
JFrame f = new JFrame("Hexagons");
f.getContentPane().setLayout(new GridLayout());
f.getContentPane().add(new JComponent() {
#Override public void paint(Graphics g) {
g.setColor(new Color(0xFF, 0xFF, 0xFF));
g.fillRect(0,0,1000,1000);
g.setColor(new Color(0,0,0));
final int[] xs = new int[6];
final int[] ys = new int[6];
for (Hexagon[] row : grid) {
for (Hexagon h: row) {
final int[] i = {0};
h.foreachVertex((x, y) -> {
xs[i[0]] = (int)((double)x);
ys[i[0]] = (int)((double)y);
i[0]++;
});
g.drawPolygon(xs, ys, 6);
g.drawString(
"(" + h.row + "," + h.col + ")",
(int)(h.getCenterX() - 15),
(int)(h.getCenterY() + 12)
);
}
}
}
});
f.setBounds(0, 0, 500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
try {
Thread.sleep(100);
} catch (Throwable e) {
} finally {
f.repaint();
}
}
}
It produces the following output:
Sorry for the lack of anti-aliasing. A few hints:
Height H of an equilateral triangle with unit side length is sqrt(3) / 2
The six offsets from the center are (0, +1), (H, +1/2), (H, -1/2), (0, -1), (-H, -1/2), (-H, +1/2), everything times side length.
Distance between rows is 1.5, distance between columns is 2 * H (times scaling constant = side length).
Every odd row is shifted by (0, H) (times scaling constant).
The position of (row,col)-th hexagon is (1.5 * row, 2 * H * (col + 0.5 * (row % 2))) (times constant).
If you want to rotate the hexagons such that two of their sides are horizontal, you have to flip rows and columns.

UI is not Creating Shapes

I have a simple example that is supposed to create a set of green balls, but instead is only creating one. I want to create an ArrayList to hold the balls, but something is wrong. Please Help.
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.Random;
import javax.security.auth.x500.X500Principal;
import javax.swing.*;
public class MyBall extends JPanel{
Random rand = new Random();
int xr = rand.nextInt(400);
int yr = rand.nextInt(400);
int size = 10 ;
int x = xr ;
int y = yr ;
Ellipse2D.Double ball = new Ellipse2D.Double(0, 0, 30, 30);
ArrayList<Bubbles> balls = new ArrayList<Bubbles>();
Bubbles blobsOb = new Bubbles(x, y , size , Color.GREEN);
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 =(Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLUE);
g2.fill(ball);
g2.setColor(Color.green);
for (int j = 0 ; j < 10 ; j++)]{
for(int i = 0 ; i < 10; i++){
balls.add(blobsOb);
g.setColor(Color.green);
g.fillOval(x, y, size, size);
}
}
}
}
//SECOND CLASS
import javax.swing.*;
public class Main {
public static void main(String[] args) {
MyBall p = new MyBall();
JFrame f = new JFrame();
f.add(p);
f.setVisible(true);
f.setLocation(200,200);
f.setSize(400, 420);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//Third Class
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
// this class is for the properties of green balls
public class Bubbles extends Component {
public int x;
public int y;
public int size;
public Color color;
public static Bubbles blob = new Bubbles(250,250,100,Color.BLUE);
Bubbles(int x, int y, int size, Color c){
this.x = x;
this.y = y;
this.size = size;
this.color = c;
}
public void paint(Graphics g){
g.setColor(color);
g.fillOval(x, y, size, size);
}
}
You need to create new instance in every cycle
for(int j = 0; j < 10; j++){
for(int i = 0 ; i < 10; i++)
{
// ...
balls.add(new Bubbles(xr, yr , size , Color.GREEN));
}
}
I want to create array list which holds green balls but the problem
is I just get one green ball instead of (10) or more
First, this should be inside the loop:
Bubbles blobsOb = new Bubbles(x, y , size , Color.GREEN);
then you'll also need to insert the code below inside the loop to ensure that at each iteration there is a new generated random value.
int xr = rand.nextInt(400);
int yr = rand.nextInt(400);
int size = 10;
int x = xr ;
int y = yr ;
example:
for(int j = 0; j < 10; j++){
for(int i = 0 ; i < 10; i++)
{
int xr = rand.nextInt(400);
int yr = rand.nextInt(400);
int size = 10;
Bubbles blobsOb = new Bubbles(xr, yr , size , Color.GREEN);
balls.add(blobsOb);
g.setColor(Color.green);
g.fillOval(x, y, size, size);
}
}
you should always call .setVisible(true) after all the components have been added to the frame.
MyBall p = new MyBall();
JFrame f = new JFrame();
f.add(p);
f.setLocation(200,200);
f.setSize(400, 420);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Lastly but not least, you've added all the generated Bubble objects into the ArrayList ArrayList<Bubbles> balls = new ArrayList<Bubbles>(), However, you haven't used the balls ArrayList yet.

Button To Reset The View Of JFrame

I have to write a program that will generate 20 random circles with random radius lengths. If any of these circles intersect with another, the circle must be blue, and if it does not intersect, the color is red. I must also place a button on the JFrame. If this button is pressed, it needs to clear out the JFrame, and generate a new set of 20 circles following the same color rules. I am extremely new to Java Swing and am really stuck. I have everything working except the button. I cannot get a new set of circles to generate. Any help would be greatly appreciated. Thank You.
import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class IntersectingCircles extends JPanel
{
private int[] xAxis = new int [20]; // array to hold x axis points
private int[] yAxis = new int [20]; // array to hold y axis points
private int[] radius = new int [20]; // array to hold radius length
public static void main (String[] args)
{
JFrame frame = new JFrame("Random Circles");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add (new IntersectingCircles());
frame.pack();
frame.setVisible(true);
}
public IntersectingCircles()
{
setPreferredSize(new Dimension(1000, 800)); // set window size
Random random = new Random();
// Create coordinates for circles
for (int i = 0; i < 20; i++)
{
xAxis[i] = random.nextInt(700) + 100;
yAxis[i] = random.nextInt(500) + 100;
radius[i] = random.nextInt(75) + 10;
}
}
public void paintComponent(Graphics g)
{
// Add button to run again
JButton btnAgain = new JButton("Run Again");
btnAgain.setBounds(850, 10, 100, 30);
add(btnAgain);
btnAgain.addActionListener(new ButtonClickListener());
// Determine if circles intersect, create circles, color circles
for (int i = 0; i < 20; i++)
{
int color = 0;
for (int h = 0; h < 20; h++)
{
if(i != h)
{
double x1 = 0, x2 = 0, y1 = 0, y2 = 0, d = 0;
x1 = (xAxis[i] + radius[i]);
y1 = (yAxis[i] + radius[i]);
x2 = (xAxis[h] + radius[h]);
y2 = (yAxis[h] + radius[h]);
d = (Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1)*(y2 - y1))));
if (d > radius[i] + radius[h] || d < (Math.abs(radius[i] - radius[h])))
{
color = 0;
}
else
{
color = 1;
break;
}
}
}
if (color == 0)
{
g.setColor(Color.RED);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
else
{
g.setColor(Color.BLUE);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
}
}
private class ButtonClickListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if(action.equals("Run Again"))
{
new IntersectingCircles();
}
}
}
}
Suggestions:
Give your class a method that creates the random circles and calls repaint()
This method should create the circles and add them into an ArrayList.
Consider using Ellipse2D to represent your circles, and so you'd have an ArrayList<Ellipse2D>.
Call this method in your class constructor.
Call it again in the button's ActionListener.
Never add button's or change the state of your class from within your paintComponent method. This method is for drawing the circles and drawing them only and nothing more. Your way you will be creating the button each time the paintComponent method is called, so you could be potentially needlessly creating many JButtons
and needlessly slowing down your time-critical painting method.
Instead add the button in the constructor.
Be sure to call super.paintComponent(g) in your paintComponent method as its first call. This will clear the old circles when need be.
Also in paintComponent, iterate through the ArrayList of circles, drawing each one.
After some searching on this website, i found what i needed. Everything seems to work now. Thanks.
import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class IntersectingCircles extends JPanel
{
private int[] xAxis = new int [20]; // array to hold x axis points
private int[] yAxis = new int [20]; // array to hold y axis points
private int[] radius = new int [20]; // array to hold radius length
public static void main (String[] args)
{
JFrame frame = new JFrame("Random Circles");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(1000, 800));
ActionListener runAgain = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent c)
{
frame.getContentPane().add(new IntersectingCircles());
frame.pack();
}
};
JButton btnAgain = new JButton("Run Again");
btnAgain.setBounds(850, 10, 100, 30);
btnAgain.addActionListener(runAgain);
frame.add(btnAgain);
frame.getContentPane().add (new IntersectingCircles());
frame.pack();
frame.setVisible(true);
}
public IntersectingCircles()
{
Random random = new Random();
// Create coordinates for circles
for (int i = 0; i < 20; i++)
{
xAxis[i] = random.nextInt(700) + 100;
yAxis[i] = random.nextInt(500) + 100;
radius[i] = random.nextInt(75) + 10;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// Determine if circles intersect, create circles, color circles
for (int i = 0; i < 20; i++)
{
int color = 0;
for (int h = 0; h < 20; h++)
{
if(i != h)
{
double x1 = 0, x2 = 0, y1 = 0, y2 = 0, d = 0;
x1 = (xAxis[i] + radius[i]);
y1 = (yAxis[i] + radius[i]);
x2 = (xAxis[h] + radius[h]);
y2 = (yAxis[h] + radius[h]);
d = (Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1)*(y2 - y1))));
if (d > radius[i] + radius[h] || d < (Math.abs(radius[i] - radius[h])))
{
color = 0;
}
else
{
color = 1;
break;
}
}
}
if (color == 0)
{
g.setColor(Color.RED);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
else
{
g.setColor(Color.BLUE);
g.drawOval(xAxis[i], yAxis[i], radius[i] * 2, radius[i] * 2);
}
}
}
}
private class ButtonClickListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
}
Maybe you can have a try...

Creating a multicolored board

I am to create a multicolored board, starting with the first square as black, then blue, red, and yellow, the squares are being filled diagonally and there are no empty colored squares. I know my algorithm is wrong, but I have not a clue as how to fix it.
Currently, my code prints out like this
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
public class Grid extends JPanel {
private static final long serialVersionUID = 1L;
public static final int GRID_COUNT = 8;
private Color[] colors = { Color.black, Color.yellow, Color.red,
Color.blue };
private int colorIndex = 0;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D graphics = (Graphics2D) g;
graphics.setColor(Color.black);
Dimension size = getSize();
Insets insets = getInsets();
int w = size.width - insets.left - insets.right;
int h = size.height - insets.top - insets.bottom;
int sqrWidth = (int)((double)w / GRID_COUNT);
int sqrHeight = (int)((double)h / GRID_COUNT);
for (int row = 0; row < GRID_COUNT; row++) {
for (int col = 0; col < GRID_COUNT; col++) {
int x = (int) (row * (double) w / GRID_COUNT);
int y = (int) (col * (double) h / GRID_COUNT);
if ((row + col) % 2 == 0) {
int colorIndex = (row + col) % 4;
graphics.fillRect(x, y, sqrWidth, sqrHeight);
graphics.setColor(colors[colorIndex]);
colorIndex = (colorIndex + 1) % colors.length;
}
}
public static void main(String[] args) {
Grid grid = new Grid();
grid.setPreferredSize(new Dimension(400, 400));
JFrame frame = new JFrame("Grid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(grid);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Let's look at the pattern:
Bk Gr Pn Bl
Gr Pn Bl Bk
Pn Bl Bk Gr
Bl Bk Gr Pn
But to make it simpler, let's call Bk 0, Gr 1, Pn 2 and Bl 3 to get:
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
This pattern is easily produced by calculating tile[x][y] = (x + y) % 4 for every tile, and using a lookup table to convert these numbers to colours (Either use an enumeration, or instead of assigning an integer value to the tile use the integer as a look-up in a table of colours and assign the colour to the tile)
If you've never seen it before, % 4 means 'divide by 4 and return the REMAINDER of the division'.
There are two mistake, I saw, first mistake is your pattern, you want to go from black, "then blue, red, and yellow" but you did
private Color[] colors = { Color.black, Color.yellow, Color.red, Color.blue };
change this one
and second mistake is that your program is counting evenly, means it is filling rectangle evenly ,
2 , 4 , 6, 8..
make your program will go on every single rectangle, which is in grey color...
I've run through the code quickly and there are number of little things which seem confusing to me..
Your color calculation is been thrown off because your original code was skipping every second cell...
if ((row + col) % 2 == 0) {
Which meant that when you tried to determine the color, you weren't getting the color you were expecting.
You were also setting the color of the cell within the row loop and not in the column loop, which seems weird to me...
(I added text in to for debugging, feel free to get rid of it)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Grid {
private static final long serialVersionUID = 1L;
public static final int GRID_COUNT = 8;
private Color[] colors = {Color.black, Color.yellow, Color.red,
Color.blue};
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("Grid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GridPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GridPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D graphics = (Graphics2D) g;
graphics.setColor(Color.black);
Dimension size = getSize();
Insets insets = getInsets();
int w = size.width - insets.left - insets.right;
int h = size.height - insets.top - insets.bottom;
FontMetrics fm = graphics.getFontMetrics();
int sqrWidth = (int) ((double) w / GRID_COUNT);
int sqrHeight = (int) ((double) h / GRID_COUNT);
int colorIndex = 0;
for (int row = 0; row < GRID_COUNT; row++) {
for (int col = 0; col < GRID_COUNT; col++) {
int x = (int) (col * sqrWidth);
int y = (int) (row * sqrHeight);
colorIndex = (row + col) % 4;
graphics.setColor(colors[colorIndex]);
graphics.fillRect(x, y, sqrWidth, sqrHeight);
String text = row + "/" + col;
graphics.setColor(Color.WHITE);
graphics.drawString(
text,
x + ((sqrWidth - fm.stringWidth(text)) / 2),
y + ((sqrHeight - fm.getHeight()) / 2) + fm.getAscent());
}
}
}
}
}

Categories

Resources