How can I create a JButton with border shadow in Swing - java

How can I create a JButton like this with inner shadow in Swing?
I wan to create JButton with different Color of border, like top and left border color should be black and right and bottom border color should be of white color.
But all together, I want inner shadow of dark gray color in top and left side like above image.

First I thought you can just achieve this with a simple BevelBorder, but unfortunately you can't set the border's thickness comfortably... So I had to basically make a customized Border. You can customize it more if you don't like the style of my button in the paintBorder method, but you have to know how to work with Graphics. Here is what I've got:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.border.Border;
/**
*
*/
public class MyBorder implements Border {
private int thickness_ = 4;
private Color white = Color.WHITE;
private Color gray = Color.GRAY;
private Color black = Color.BLACK;
public static void main(String[] args) {
JFrame frm = new JFrame("Border Test");
frm.setLayout(new FlowLayout());
JButton btn = new JButton("Button");
MyBorder border = new MyBorder();
btn.setBorder(border);
btn.setFocusPainted(false);
btn.setPreferredSize(new Dimension(60,30));
btn.setBackground(Color.LIGHT_GRAY);
frm.add(btn);
frm.setSize(200,200);
frm.setVisible(true);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
Color oldColor = g.getColor();
int i;
for (i = 0; i < thickness_; i++) {
g.setColor(white);
g.drawRect(x + i, y + i, width - i - i - 1, height - i - i - 1); //White Rectangle
}
for (i = 0; i < thickness_/2; i++) {
g.setColor(black);
g.drawLine(x + i, y + i, (width - x) - (i * 2), y + i); //Top Outer Edge
g.drawLine(x + i, y + i, x + i, (height - y) - (i * 2)); //Left Outer Edge
}
for (i = thickness_/2; i < thickness_; i++) {
g.setColor(gray);
g.drawLine(x + i, y + i, (width - x) - (i * 2), y + i); //Top Inner Edge
g.drawLine(x + i, y + i, x + i, (height - y) - (i * 2)); //Left Inner Edge
}
g.setColor(oldColor);
}
public int getThickness() {
return thickness_;
}
public void setThickness(int i) {
thickness_ = i;
}
public boolean isBorderOpaque() {
return true;
}
public Insets getBorderInsets(Component c) {
return new Insets(thickness_, thickness_, thickness_, thickness_);
}
}

Related

Is there a way to make a constructor that draws a rectangle

My partner and I are trying to remake Tetris for our final project of the year in my Computer Science class we currently have a for loop that draws individual rectangles in an overwritten paint method.
private final int spacer = 30;
public int getSpacer()
{
return spacer;
}
public void paint(Graphics g) {
setBackground(Color.GRAY);
for(int i = getHeight()/2 - (spacer * 10); i < getHeight()/2 + (spacer * 10); i += spacer) {
for(int x = getWidth()/2 - (spacer * 5); x < getWidth()/2 + (spacer * 5); x += (spacer)) {
g.drawRect(x, i, (spacer), (spacer));
}
}
setForeground(Color.black);
}
The method basically takes the width and height of the window and makes a 10 x 20 grid of boxes that are 30 units, pixels I think, wide.
We'd like to make a Grid.java class that takes in color, the spacer int, and an x and y int. The constructor for Grid.java should draw the exact same thing as the code above using the for loop, but when we tried it gave us a white screen that would not resize with the window.
private final int spacer = 30;
private static Grid[][] arr = new Grid[10][20];
public int getSpacer()
{
return spacer;
}
public void paint(Graphics g) {
setBackground(Color.GRAY);
int countY = 0;
int countX = 0;
for(int y = getHeight()/2 - (spacer * 10); y < getHeight()/2 + (spacer * 10); y += spacer) {
for(int x = getWidth()/2 - (spacer * 5); x < getWidth()/2 + (spacer * 5); x += spacer) {
arr[countX][countY] = new Grid(x, y, spacer, g);
countX++;
}
countY++;
}
setForeground(Color.black);
}
*Grid.java Class*
package Tetris_Shapes;
import javax.swing.*;
import java.awt.*;
public class Grid {
private int x;
private int y;
private int side;
private Graphics g;
public Grid(int x, int y, int side, Graphics g) {
// g.drawRect(x, y, spacer, spacer);
this.x = x;
this.y = y;
this.side = side;
this.g = g;
paint(this.g);
}
private void paint(Graphics g) {
g.drawRect(x, y, side, side);
}
}
When we try and run this we get the white box that doesn't resize. My question is does anyone know of a way to get a constructor to draw shapes. Thank you in advance, this is pretty niche so I'm also going to apologize in advance.

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.

Nesting parabolic curves from straight lines

I am having trouble replicating the picture for my assignment. I would appreciate any tips or solutions. I believe I have the general idea down, but I am having a hard time figuring out the math to replicate the image and doing everything in a single loop.
My program needs to meet these criteria:
Match the Image
Generate a random color for each pair of parabolic curve
Work with any width or height
Use a single loop to draw the entire figure.
Here is the image:
This is what I have tried so far
public static final int WIDTH = 500;
public static final int HEIGHT = 500;
public static final int LINE_INCREMENT = 5;
public static void main(String[] args) {
DrawingPanel panel = new DrawingPanel(WIDTH, HEIGHT);
Graphics g = panel.getGraphics();
int d = 0;
int iterations = HEIGHT/LINE_INCREMENT;
Random rand = new Random();
int red = 0, green = 0, blue = 0;
red = rand.nextInt(128) + 128;
green = rand.nextInt(128) + 128;
blue = rand.nextInt(128) + 128;
g.setColor(new Color(red,green,blue));
for(int y = 0; y < iterations; y++) {
g.drawLine(0, d, d, HEIGHT);
g.drawLine(WIDTH, d, d, 0);
d += LINE_INCREMENT;
}
red = rand.nextInt(128) + 128;
green = rand.nextInt(128) + 128;
blue = rand.nextInt(128) + 128;
g.setColor(new Color(red,green,blue));
d = 0;
for (int x = 0; x < iterations/2; x++) {
g.drawLine(WIDTH/4, d + HEIGHT/4, d + WIDTH/4, HEIGHT - HEIGHT/4);
g.drawLine(d + WIDTH/4, WIDTH/4, WIDTH - WIDTH/4, d + WIDTH/4);
d += LINE_INCREMENT;
}
}
The output:
The way to implement it is by overriding paintComponent:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ParabolicCurves extends JFrame {
private static final int SIZE = 600;
private static final int LINE_INCREMENT = 5;
private static final int NUM_OF_PATTERNS = 4;
private Random rand = new Random();
ParabolicCurves() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel panel = new DrawingPanel(SIZE);
add(panel, BorderLayout.CENTER);
pack();
setVisible(true);
}
class DrawingPanel extends JPanel{
public DrawingPanel(int size) {
setPreferredSize(new Dimension(size, size));
setBackground(Color.WHITE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int red, green, blue, delta , iterations;
int height, width ,startX, startY, endX, endY ;
Rectangle boundingRrectangle = getBounds();
for(int pattern = 0 ; pattern < NUM_OF_PATTERNS; pattern++) {
red = rand.nextInt(128) + 128;
green = rand.nextInt(128) + 128;
blue = rand.nextInt(128) + 128;
g.setColor(new Color(red,green,blue));
height = (int) boundingRrectangle.getHeight();
width = (int) boundingRrectangle.getWidth();
startX = (int) boundingRrectangle.getX();
startY = (int) boundingRrectangle.getY();
endX = startX+width;
endY = startY+ height;
iterations = Math.min(width, height)/LINE_INCREMENT;
delta = 0;
for (int x = 0; x < iterations ; x++) {
g.drawLine(startX, startY+delta, startX+delta, endY);
g.drawLine(endX, startY+delta, startX+delta, startY);
delta += LINE_INCREMENT;
}
//change bounding rectangle
boundingRrectangle = new Rectangle(startX+(width/4),
startY+(width/4), width/2, height/2);
}
}
}
public static void main(String[] args) {
new ParabolicCurves();
}
}
Output:

Tabs Rendering Order in Custom JTabbedPane

Hi you all and Happy New Year from my first post of 2017! :)
Problem explanation
I'm currently coding a custom JTabbedPane and all works fine, but I got an unnexpected(for me) design problem when the tabs are rendered.
The problem is that all unselected tabs renders from left to right and since the shape I customized, using GeneralPath class, exceeds the default tab bounds, each tab rendered overlaps part of the tab on its left. You can check it in the following image:
As you can see, selected tab overlaps any tab coming from the right, but unselected tabs, like the named "CustomPanel2" is rendered before the next tab and so on.
Question
I saw one post talking about overriding paintTab method from BasicTabbedPaneUI class, which is the one I'm using, but I cannot realize how to do it so I would like you to show me the correct way for rendering tabs in order to obtain something like tabs in Google Chrome looks like:
Thank you in advance and have a nice day! ;)
PD: I think there's no relevant code to add. If you need it, please ask me for it.
What about trying to shape a tab that is not selected into a pentagon?
Note: This example does not test when JTabbedPane#setTabLayoutPolicy (JTabbedPane.WRAP_TAB_LAYOUT) or JTabbedPane#setTabPlacement (JTabbedPane.BOTTOM) is set:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
public class TabsOverlapTest {
private JComponent makeUI() {
Color selectedTabColor = UIManager.getColor("TabbedPane.selected");
Color tabBackgroundColor = Color.LIGHT_GRAY;
Color tabBorderColor = Color.GRAY;
UIManager.put("TabbedPane.highlight", tabBorderColor);
JTabbedPane tabs = new JTabbedPane();
tabs.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
tabs.setUI(new BasicTabbedPaneUI() {
#Override protected void paintTabBorder(
Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected) {
}
#Override protected void paintFocusIndicator(
Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
Rectangle iconRect, Rectangle textRect, boolean isSelected) {
}
#Override protected void paintContentBorderTopEdge(
Graphics g, int tabPlacement, int selectedIndex,
int x, int y, int w, int h) {
super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
Rectangle selRect = getTabBounds(selectedIndex, calcRect);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(selectedTabColor);
g2.drawLine(selRect.x - 2, y, selRect.x + selRect.width + 2, y);
g2.dispose();
}
#Override protected void paintTabBackground(
Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h,
boolean isSelected) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int a = isSelected ? 0 : 1;
GeneralPath shape = new GeneralPath();
shape.moveTo(x - 3, y + h);
shape.lineTo(x + 3, y + a);
shape.lineTo(x + w - 3, y + a);
shape.lineTo(x + w + 3, y + h);
shape.closePath();
g2.setColor(isSelected ? selectedTabColor : tabBackgroundColor);
g2.fill(shape);
GeneralPath border = new GeneralPath();
if (isSelected || tabIndex == 0) {
border.moveTo(x - 3, y + h - 1);
} else {
border.moveTo(x + 3, y + h - 1);
border.lineTo(x, (y + h - 1) / 2);
}
border.lineTo(x + 3, y + a);
border.lineTo(x + w - 3, y + a);
border.lineTo(x + w + 3, y + h - 1);
g2.setColor(tabBorderColor);
g2.draw(border);
g2.dispose();
}
});
tabs.addTab("JTextArea", new JScrollPane(new JTextArea()));
tabs.addTab("JTree", new JScrollPane(new JTree()));
tabs.addTab("JButton", new JButton("button"));
tabs.addTab("JSplitPane", new JSplitPane());
return tabs;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TabsOverlapTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
Well, I finally found the solution myself by overriding paintTabArea method from BasicTabbedPaneUI class.
The default code is:
protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
int tabCount = tabPane.getTabCount();
Rectangle iconRect = new Rectangle(),
textRect = new Rectangle();
Rectangle clipRect = g.getClipBounds();
for (int i = runCount - 1; i >= 0; i--) {
int start = tabRuns[i];
int next = tabRuns[(i == runCount - 1)? 0 : i + 1];
int end = (next != 0? next - 1: tabCount - 1);
for (int j = start; j <= end; j++) {
if (j != selectedIndex && rects[j].intersects(clipRect)) {
paintTab(g, tabPlacement, rects, j, iconRect, textRect);
}
}
}
if (selectedIndex >= 0 && rects[selectedIndex].intersects(clipRect)) {
paintTab(g, tabPlacement, rects, selectedIndex, iconRect, textRect);
}
}
At the second for statement, you see the condition:
(int j = start; j <= end; j++)
In order to switch tabs rendering order, you just have to change that condition to: (int j = end; j >= start; j--)

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