When I set X and Y values for my array of JButtons, I get back the correct values only multiplied by 93. I can solve the problem by dividing the value by 93 but I would rather find out where the bug was in the first place.
I have two classes in the code, one for the actual program, and one for the button object along with the coordinates.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.GridLayout;
import java.io.*;
public class ConnectFour implements ActionListener
{
JFrame frame = new JFrame();
Button [][] buttons = new Button[6][7];
public ConnectFour()
{
frame.setSize(700,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(6,7));
frame.setLocationRelativeTo(null);
frame.setTitle("Connect Four");
for(int filler = 0; filler <= 5; filler++)
{
for(int filler2 = 0; filler2 <= 6; filler2++)
{
buttons[filler][filler2] = new Button();
buttons[filler][filler2].setX(filler2);
buttons[filler][filler2].setY(filler);
//System.out.println(buttons[filler][filler2].getX());
//System.out.print(buttons[filler][filler2].getY());
frame.add(buttons[filler][filler2].button);
buttons[filler][filler2].button.addActionListener(this);
}
}
frame.setVisible(true);
}
public void actionPerformed(ActionEvent a)
{
JButton pressedButton = (JButton)a.getSource();
System.out.print(pressedButton.getY() / 93);
System.out.print(pressedButton.getX() / 93);
}
public static void main(String args[])
{
ConnectFour gameplay = new ConnectFour();
}
}
Here's the Button class:
import javax.swing.JButton;
public class Button
{
JButton button;
private int x = 0;
private int y = 0;
public Button()
{
button = new JButton();
}
public int getX() {return x;}
public int getY() {return y;}
public void setX(int xIndex)
{
x = xIndex;
}
public void setY(int yIndex)
{
y = yIndex;
}
}
You're mixing your two Button classes.
In this line, you're adding an actionListener to Button.button:
buttons[filler][filler2].button.addActionListener(this);
because JButton also has methods getX and getY, you can call them. When you do:
pressedButton.getX()
you're getting the x position of the JButton, not of your Button.
What I think would be the easiest way to solve this problem is making your button extend JButton and rename x and y to row and column, for instance:
public class Button extends JButton {
private int row = 0;
private int column = 0;
public Button(int row, int column) {
super();
this.row = row;
this.column = column;
}
public int getRow() {return row;}
public int getColumn() {return column;}
}
You can create you buttons as
for(int filler = 0; filler <= 5; filler++) {
for(int filler2 = 0; filler2 <= 6; filler2++) {
buttons[filler][filler2] = new Button(filler2, filler);
frame.add(buttons[filler][filler2]);
buttons[filler][filler2].addActionListener(this);
}
}
And use them in the ActionListener as
public void actionPerformed(ActionEvent a) {
Button pressedButton = (Button)a.getSource();
System.out.print(pressedButton.getColumn());
System.out.print(pressedButton.getRow());
}
I could not figure how to do it using your composition example, but this one works as you might want.
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.GridLayout;
import java.io.*;
public class ConnectFour implements ActionListener
{
JFrame frame = new JFrame();
CustomButton [][] buttons = new CustomButton[6][7];
public ConnectFour()
{
frame.setSize(700,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(6,7));
frame.setLocationRelativeTo(null);
frame.setTitle("Connect Four");
for(int filler = 0; filler <= 5; filler++)
{
for(int filler2 = 0; filler2 <= 6; filler2++)
{
buttons[filler][filler2] = new CustomButton(filler,filler2);
frame.add(buttons[filler][filler2]);
buttons[filler][filler2].addActionListener(this);
}
}
frame.setVisible(true);
}
public void actionPerformed(ActionEvent a)
{
CustomButton pressedButton = (CustomButton)a.getSource();
System.out.println(pressedButton.getRow() + "/" + pressedButton.getCol());
}
public static void main(String args[])
{
ConnectFour gameplay = new ConnectFour();
}
}
class CustomButton extends JButton
{
private int row = 0;
private int col = 0;
public CustomButton(int row, int col)
{
this.row = row;
this.col = col;
}
public int getRow() {return row;}
public int getCol() {return col;}
public void setRow(int row)
{
this.row = row;
}
public void setCol(int col)
{
this.col = col;
}
}
I think x and y are defined in the superclass, try changing the variable names to something else. e.g.
private int myX = 0;
private int myY = 0;
Related
So the situation is that I'm making a panel filled with 8*8 buttons, like a matrix, and I'm gonna have to change specific button texts depending on the position of the clicked button. It seemd like a good idea to make my own JButton where I can assign x and y indexes to the button, so I can check easily wich button was clicked by indexes.
Here is the code for that:
import javax.swing.JButton;
public class MatrixButton extends JButton {
private int x;
private int y;
public MatrixButton(int x, int y, String text){
super(text);
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
And it does solve the task, but these Matrix buttons doesn't want to appear until I mouse over them. What could be the problem?
here is the code for the panel wich contains these buttons and handles their actions:
public class PlayField extends JPanel implements ActionListener {
private MatrixButton[][] button = new MatrixButton[8][8];
public PlayField(){
Random rand = new Random();
setLayout(new GridLayout(8, 8));
for (int i = 0; i < 8; ++i){
for (int j = 0; j < 8; ++j){
button[i][j] = new MatrixButton(j, i, "" + rand.nextInt(80));
button[i][j].addActionListener(this);
add(button[i][j]);
}
}
}
private String incrementText(MatrixButton mb){
return "" + (Integer.parseInt(mb.getText()) + 1);
}
#Override
public void actionPerformed(ActionEvent e){
MatrixButton mb = (MatrixButton)e.getSource();
for (int i = mb.getY(); i >= 0; --i){
button[i][mb.getX()].setText(incrementText(button[i][mb.getX()]));
}
for (int i = 0; i < 8; ++i){
if (i != mb.getX())
button[mb.getY()][i].setText(incrementText(button[mb.getY()][i]));
}
}
}
PS: if I fill with ordinary JButtons they appear as they should be. Thats why I'm confused, cuz I didn't change much on the JButton extension just added 2 more variables to it.
This is dangerous code:
public int getX() {
return x;
}
public int getY() {
return y;
}
You do realize that this overrides two of JButton's critical methods (actually, the methods are from JButton's parent, JComponent) that help set the placement of the button on the GUI (add #Override above the methods to see that this is so). I strongly suggest that you either change the signature of these methods, perhaps getGridX() and getGridY(), or even better, use composition and not inheritance, since you run into risk of these types of problems -- unwittingly overriding a key method -- when you extend complex classes such as Swing component classes. For this reason I try to avoid extending these classes unless absolutely necessary.
For example:
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PlayField {
private static final int ROWS = 8;
private static final int COLS = ROWS;
private static final int MAX_RAND = 80;
private JPanel mainPanel = new JPanel();
private MatrixButton[][] button = new MatrixButton[ROWS][COLS];
public PlayField(){
Random rand = new Random();
mainPanel.setLayout(new GridLayout(ROWS, COLS));
for (int i = 0; i < ROWS; ++i){
for (int j = 0; j < COLS; ++j){
button[i][j] = new MatrixButton(j, i, rand.nextInt(MAX_RAND));
button[i][j].addActionListener(new MyMatrixListener(i, j));
mainPanel.add(button[i][j].getButton());
}
}
}
private class MyMatrixListener implements ActionListener {
private int i;
private int j;
public MyMatrixListener(int i, int j) {
this.i = i;
this.j = j;
}
#Override
public void actionPerformed(ActionEvent e) {
for (int i2 = 0; i2 < button.length; i2++) {
if (i2 != i) {
int value = button[i2][j].getValue();
value++;
button[i2][j].setValue(value);
}
}
for (int j2 = 0; j2 < button[i].length; j2++) {
if (j2 != j) {
int value = button[i][j2].getValue();
value++;
button[i][j2].setValue(value);
}
}
}
}
public JPanel getMainPanel() {
return mainPanel;
}
private static void createAndShowGui() {
JFrame
frame = new JFrame("PlayField");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new PlayField().getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MatrixButton {
private int column;
private int row;
private JButton button = new JButton();
private int value;
public MatrixButton(int column, int row, int value) {
this.column = column;
this.row = row;
setValue(value);
}
public void addActionListener(ActionListener listener) {
button.addActionListener(listener);
}
public int getColumn() {
return column;
}
public int getRow() {
return row;
}
public JButton getButton() {
return button;
}
public int getValue() {
return value;
}
public final void setValue(int value) {
this.value = value;
button.setText("" + value);
}
}
Better to just use ints and not Strings
I have a 2d array of Grids (JPanels) that are added to another JPanel using the GridLayout. That JPanel is added to the JFrame. Whenever a click happens on the JFrame I'm attempting to take the Point of the click and determine if any of those Grids in the 2d array contain that Point.
I'm attempting to do this inside frame.addMouseListener...
I know the frame is registering the mouse clicks. For some reason the Grids don't register that they should be containing that Point. Can anyone explain this? if(theView[i][j].contains(me.getPoint())){ This is the line of code that seems to be failing me.
I originally attempted to have the Grids know when they were clicked on so I wouldn't have to coordinate between the frame and grids, but I couldn't get that to work.
Here's the level designer.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import javax.swing.*;
public class LevelDesigner extends JPanel implements ButtonListener{
private final int SIZE = 12;
private int [][] thePit;
private Grid [][] theView;
private ButtonPanel bp;
public static int val;
private int rows, cols;
private JPanel gridPanel;
private JFrame frame;
public LevelDesigner(int r, int c){
frame = new JFrame();
int h = 10, w = 10;
setVisible(true);
setLayout(new BorderLayout());
setBackground(Color.BLUE);
rows = r;
cols = c;
thePit = new int[r][c];
theView = new Grid[r][c];
gridPanel = new JPanel();
gridPanel.setVisible(true);
gridPanel.setBackground(Color.BLACK);
gridPanel.setPreferredSize(getMaximumSize());
GridLayout gridLayout = new GridLayout();
gridLayout.setColumns(cols);
gridLayout.setRows(rows);
gridPanel.setLayout(gridLayout);
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
theView[i][j] = new Grid(i, j, SIZE, this);
gridPanel.add(theView[i][j]);
}
}
String test [] = {"0", "1","2","3","4","save"};
bp = new ButtonPanel(test, this);
this.add(bp, BorderLayout.SOUTH);
this.add(gridPanel, BorderLayout.CENTER);
frame.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me) {
for(int i = 0; i < rows; ++i){
for(int j = 0; j < cols; ++j){
if(theView[i][j].contains(me.getPoint())){
theView[i][j].actionPerformed(null);
return;
}
}
}
}
});
frame.setVisible(true);
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
frame.setTitle("Epic Crawl - Main Menu");
frame.pack();
frame.setLocationRelativeTo(null);
frame.repaint();
frame.add(this);
}
public String toString(){
int noRows = thePit.length;
int noColumns = thePit[0].length;
String s="";
for (int r=0;r<noRows;r++){
for (int c=0;c<noColumns;c++){
s=s + thePit[r][c] + " ";
}
s=s+"\n";
}
return(s);
}
public void notify( int i, int j){
thePit[i][j] = val;
}
public void print(){
final JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new java.io.File("."));
int returnVal = fc.showSaveDialog( null);
if( returnVal == JFileChooser.APPROVE_OPTION ){
try{
PrintWriter p = new PrintWriter(
new File( fc.getSelectedFile().getName() ) );
System.out.println(" printing");
p.println( this );
p.close();
}
catch( Exception e){
System.out.println("ERROR: file not saved");
}
}
}
public void buttonPressed(String buttonLabel, int id){
if(id == 5)
print();
else
val = id;
}
public void buttonReleased( String buttonLabel, int buttonId ){}
public void buttonClicked( String buttonLabel, int buttonId ){}
public static void main(String arg[]){
LevelDesigner levelDesigner = new LevelDesigner(4, 4);
}
}
And here is the Grid.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Grid extends JPanel implements ActionListener{
LevelDesigner grid;
int myI, myJ;
private String[] imageNames = {"dirt.png", "grass.png", "Door.png", "woodfloor.png", "32x32WoodFloor.png"};
BufferedImage gridImage;
private String imagePath;
public Grid(int i, int j, int size, LevelDesigner m){
imagePath = "";
grid = m;
myI = i;
myJ = j;
setBackground(Color.RED);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae){
grid.notify(myI, myJ);
imagePath = "Images/" + imageNames[LevelDesigner.val];
gridImage = null;
InputStream input = this.getClass().getClassLoader().getResourceAsStream(imagePath);
try{
gridImage = ImageIO.read(input);
}catch(Exception e){System.err.println("Failed to load image");}
}
public void paintComponent(Graphics g){
super.paintComponent(g); // Important to call super class method
g.clearRect(0, 0, getWidth(), getHeight()); // Clear the board
g.drawImage(gridImage, 0, 0, getWidth(), getHeight(), null);
}
}
The contains method checks if the Point is within the boundaries of the JPanel but using a coordinate system relative to the JPanel. Instead consider using findComponentAt(Point p).
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TestMouseListener {
private static final int SIDE_COUNT = 4;
private JPanel mainPanel = new JPanel();
private MyGridCell[][] grid = new MyGridCell[SIDE_COUNT][SIDE_COUNT];
public TestMouseListener() {
mainPanel.setLayout(new GridLayout(SIDE_COUNT, SIDE_COUNT));
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new MyGridCell();
mainPanel.add(grid[i][j].getMainComponent());
}
}
mainPanel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = mainPanel.findComponentAt(p);
for (MyGridCell[] gridRow : grid) {
for (MyGridCell myGridCell : gridRow) {
if (c == myGridCell.getMainComponent()) {
myGridCell.setLabelText("Pressed!");
} else {
myGridCell.setLabelText("");
}
}
}
}
});
}
public Component getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
TestMouseListener mainPanel = new TestMouseListener();
JFrame frame = new JFrame("TestMouseListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyGridCell {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
#SuppressWarnings("serial")
private JPanel mainPanel = new JPanel() {
public Dimension getPreferredSize() {
return MyGridCell.this.getPreferredSize();
};
};
private JLabel label = new JLabel();
public MyGridCell() {
mainPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.setLayout(new GridBagLayout());
mainPanel.add(label);
}
public Component getMainComponent() {
return mainPanel;
}
public void setLabelText(String text) {
label.setText(text);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Component#contains "Checks whether this component "contains" the specified point, where the point's x and y coordinates are defined to be relative to the coordinate system of this component"
This means that the contains will only return true if the Point is within the bounds of 0 x 0 x width x height.
So if the component is position at 400x200 and is sized at 200x200 (for example). When you click within in, the mouse point will be between 400x200 and 600x400, which is actually out side of the relative position of the component (200x200) - confused yet...
Basically, you either need to convert the click point to a relative coordinate within the context of the component you are checking...
Point p = SwingUtilities.convertPoint(frame, me.getPoint(), theView[i][j])
if (theView[i][j].contains(p)) {...
Or use the components Rectangle bounds...
if (theView[i][j].getBounds().contains(me.getPoint())) {...
So, remember, mouse events are relative to the component that they were generated for
I am trying to make a game named ratsuk that is like chess but only with the knight. The knight cant move were has moved before so the 1 who cant move losses.
The problem is that when i press 1 of the buttons were the knight has appears before a new knight appears. And new 1 appears in place it shouldn't witch im not sure why.
I think it may be because the button needs to work just once.
So how do i make to button to just work once?
here is muy code
package ratsuk;
import java.util.Random;
import javax.swing.JFrame;
/**
* import javax.swing.JFrame; import javax.swing.SwingUtilities; import
* javax.swing.UIManager;
*/
public class Ratsuk extends JFrame {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Random rad;
rad = new Random();
int row = rad.nextInt(8);
int column = rad.nextInt(8);
Tablero newtablero = new Tablero();
newtablero.caballo(row, column);
}
}
The accions for the buttons are in the acciones method. I havent program all the posible movements yet;
package ratsuk;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
/**
*
* #author Melvin
*/
public class Tablero {
private static final int HEIGHT = 8;
private static final int WIDTH = 8;
private JButton[][] mesa;
private Icon image;
private JPanel panel;
public Tablero() {
mesa = new JButton[HEIGHT][WIDTH];
panel = new JPanel(new GridLayout(HEIGHT, WIDTH));
image = new ImageIcon(getClass().getResource("redKnight.gif"));
crearventana();
crearmesa();
pintarmesa();
}
private void crearventana() {
JFrame ventana = new JFrame("Juego de Ratsuk");
ventana.setVisible(true);
ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ventana.setContentPane(panel);
ventana.setSize(500, 500);
ventana.setVisible(true);
}
private void crearmesa() {
for (int row = 0; row < HEIGHT; row++) {
for (int column = 0; column < WIDTH; column++) {
JButton button = new JButton();
button.setPreferredSize(new Dimension(40, 40));
mesa[row][column] = button;
panel.add(button);
}
}
}
private void pintarmesa() {
Color fondo;
for (int r = 0; r < HEIGHT; r++) {
for (int t = 0; t < WIDTH; t++) {
fondo = getBackgroundColor(r, t);
mesa[r][t].setBackground(fondo);
}
}
}
private Color getBackgroundColor(int r, int t) {
Color fondo;
if (r % 2 == 0 || r == 0) {
if (t % 2 == 0 || t == 0) {
fondo = Color.BLACK;
} else {
fondo = Color.WHITE;
}
} else {
if (t % 2 == 0 || t == 0) {
fondo = Color.WHITE;
} else {
fondo = Color.BLACK;
}
}
return fondo;
}
public void caballo(final int row, final int column) {
final JButton current = mesa[row][column];
current.setIcon(image);
panel.repaint();
acciones(row, column, current);
}
private void acciones(final int row, final int column, final JButton current) {
final int nextRow = row + 2;
final int nextColumn = column - 1;
if (tienebotton(nextRow, nextColumn)==true){
JButton next = mesa[nextRow][nextColumn];
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent d) {
current.setIcon(null);
caballo(nextRow, nextColumn);
}
});
}
final int nextColumn1 = column+ 1;
if (tienebotton(nextRow, nextColumn1)==true){
JButton next = mesa[nextRow][nextColumn1];
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent d) {
current.setIcon(null);
caballo(nextRow, nextColumn1);
}
});
}
final int nextRow1 = row- 2;
if (tienebotton(nextRow1, nextColumn)==true){
JButton next = mesa[nextRow1][nextColumn];
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent d) {
current.setIcon(null);
caballo(nextRow1, nextColumn);
}
});
}
}
private boolean tienebotton(int row, int column) {
if (row >= 0 && row < HEIGHT && column >= 0 && column < WIDTH) {
return true;
} else {
return false;
}
}
}
If some 1 can give me some pointer for my project in general I will apreaciated.
Once the button has been pressed, call setEnabled(false) on it. That's it.
public void actionPerformed(ActionEvent evt) {
// .. whatever code is needed for the button
// and then disable the button pressed
((AbstractButton)evt.getSource).setEnabled(false);
}
So, I'm making a chessboard, and whenever I try to put down the buttons, they keep reorienting and get more and more messy towards the bottom right. The first button in the top right (squareB[0][0]) looks fine, but all the other JButtons are messed up.
So my question is how do I fix this or allow me to place the button at certain coordinates?
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.io.*;
public class Test implements ActionListener
{
private JFrame frame = new JFrame();
private JPanel[][] square = new JPanel[8][8];
private JButton[][] button = new JButton[8][8];
public static void main(String[] args)
{
new Test();
}
Test()
{
frame.setLayout(new GridLayout(8,8));
for(int x=0; x<8; x++)
{
for(int y=0; y<8; y++)
{
square[x][y] = new JPanel();
frame.add(square[x][y]);
square[x][y].setSize(100,100);
square[x][y].setLayout(new GridLayout(1,1));
if(y%2==0)
if(x%2==0)
square[x][y].setBackground(Color.white);
else
square[x][y].setBackground(Color.black);
if(y%2!=0)
if(x%2==0)
square[x][y].setBackground(Color.black);
else
square[x][y].setBackground(Color.white);
button[x][y] = new JButton();
button[x][y] = new TestMethods(x,y);
square[x][y].add(button[x][y]);
button[x][y].setOpaque(false);
button[x][y].setContentAreaFilled(true);
button[x][y].setBorderPainted(true);
button[x][y].addActionListener(this);
}
}
frame.setSize(800,800);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
}
}
class TestMethods extends JButton
{
private int x, y;
public TestMethods(int x, int y)
{
this.x = x;
this.y = y;
}
public int getX() {return x;}
public int getY() {return y;}
}
I think part of your problem is related to the getX and getY methods of your TestMethods class. These are overriding methods used by the JButton to determine it's location on it's parent and you should avoid overriding them
class TestMethods extends JButton
{
private int x, y;
public TestMethods(int x, int y)
{
this.x = x;
this.y = y;
}
public int getX() {return x;}
public int getY() {return y;}
}
I would, instead, use method names that relate better to your purpose.
class TestMethods extends JButton
{
private int gridX, gridY;
public TestMethods(int x, int y)
{
this.gridX = x;
this.gridY = y;
}
public int getGridX() {return gridX ;}
public int getGridY() {return gridY ;}
}
Well, I cannot find what is going bad with your code, so I did write a method that does the same. I know this is not an answer, but may be useful:
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(800, 800));
frame.setLayout(new GridLayout(8, 8));
boolean isWhite = true;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
final JButton button = new JButton();
if (isWhite) {
button.setBackground(Color.white);
} else {
button.setBackground(Color.black);
}
isWhite = !isWhite;
frame.add(button);
}
isWhite = !isWhite;
}
frame.pack();
frame.setVisible(true);
}
Please look at the answer given by MadProgrammer. Also I have modified your example to create the chessboard. Please look at the modified way of creating chessboard pattern.
Test()
{
frame.setLayout(new GridLayout(8,8));
for(int x=0; x<8; x++)
{
for(int y=0; y<8; y++)
{
square[x][y] = new JPanel();
frame.add(square[x][y]);
square[x][y].setSize(100,100);
square[x][y].setLayout(new GridLayout(1,1));
button[x][y] = new TestMethods(x,y);
button[x][y].setOpaque(true);
button[x][y].setContentAreaFilled(true);
button[x][y].setBorderPainted(true);
button[x][y].addActionListener(this);
if((y + x)%2==0)
{
button[x][y].setBackground(Color.WHITE);
}
else
{
button[x][y].setBackground(Color.BLACK);
}
square[x][y].add(button[x][y]);
}
}
frame.setSize(800,800);
frame.setVisible(true);
}
I'm planning on making an editor for my current project and will need some java swing for it.
Basically I need a grid within some sort of frame; the single elements of the grid should be able to be selected via click and with a dropdown/selector element you should be able to change the color of the grid element
Can anyone tell me what parts of swing I'll need for that? Any help would be really appreciated ;)
Edit: let's go a bit into detail
This editor is planned to generate maps for an android strategy game I develope with some friends of mine
Let's say we have a square field of 16x16 fields which are all by default green.
By selecting the single field I want to be able to change the color of this field to something else.
In addition, every field should be able to return it's value (i.e. the color)
Your question is a little short on details, but perhaps you want a JPanel that uses GridLayout and holds an array of JLabels whose opaque property is true. You could add a MouseListener to the JLabels that shows a JPopupMenu that shows possible colors, and then depending on the selection use it to set the JLabel's background color (which shows since it has been made opaque).
For example:
Main.java
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main {
private static void createAndShowGui() {
int rows = 20;
int cols = 40;
int cellWidth = 20;
ColorGrid mainPanel = new ColorGrid(rows, cols, cellWidth);
JFrame frame = new JFrame("Color Grid Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
ColorGrid.java
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class ColorGrid extends JPanel {
private MyColor[][] myColors;
private JLabel[][] myLabels;
public ColorGrid(int rows, int cols, int cellWidth) {
myColors = new MyColor[rows][cols];
myLabels = new JLabel[rows][cols];
MyMouseListener myListener = new MyMouseListener(this);
Dimension labelPrefSize = new Dimension(cellWidth, cellWidth);
setLayout(new GridLayout(rows, cols));
for (int row = 0; row < myLabels.length; row++) {
for (int col = 0; col < myLabels[row].length; col++) {
JLabel myLabel = new JLabel();
myLabel = new JLabel();
myLabel.setOpaque(true);
MyColor myColor = MyColor.GREEN;
myColors[row][col] = myColor;
myLabel.setBackground(myColor.getColor());
myLabel.addMouseListener(myListener);
myLabel.setPreferredSize(labelPrefSize);
add(myLabel);
myLabels[row][col] = myLabel;
}
}
}
public MyColor[][] getMyColors() {
return myColors;
}
public void labelPressed(JLabel label) {
for (int row = 0; row < myLabels.length; row++) {
for (int col = 0; col < myLabels[row].length; col++) {
if (label == myLabels[row][col]) {
MyColor myColor = myColors[row][col].next();
myColors[row][col] = myColor;
myLabels[row][col].setBackground(myColor.getColor());
}
}
}
}
}
MyColor.java
import java.awt.Color;
public enum MyColor {
GREEN(Color.green, "Green", "g"), RED(Color.red, "Red", "r"),
BLUE(Color.blue, "Blue", "b"), YELLOW(Color.yellow, "Yellow", "y");
private Color color;
private String name;
private String shortName;
private MyColor(Color color, String name, String shortName) {
this.color = color;
this.name = name;
this.shortName = shortName;
}
public MyColor next() {
int index = 0;
for (int i = 0; i < MyColor.values().length; i++) {
if (MyColor.values()[i] == this) {
index = (i + 1) % MyColor.values().length;
}
}
return MyColor.values()[index];
}
public Color getColor() {
return color;
}
public String getName() {
return name;
}
public String getShortName() {
return shortName;
}
#Override
public String toString() {
return shortName;
}
}
MyMouseListener.java
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
public class MyMouseListener extends MouseAdapter {
private ColorGrid colorGrid;
public MyMouseListener(ColorGrid colorGrid) {
this.colorGrid = colorGrid;
}
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
colorGrid.labelPressed((JLabel)e.getSource());
} else if (e.getButton() == MouseEvent.BUTTON3) {
MyColor[][] myColors = colorGrid.getMyColors();
for (int row = 0; row < myColors.length; row++) {
for (int col = 0; col < myColors[row].length; col++) {
System.out.print(myColors[row][col] + " ");
}
System.out.println();
}
System.out.println();
}
}
}