Okay, I want to create a Tic Tac Toe(X-O) game with GUI, I have drawn it but I'm somehow unable to function it. I do know how to use .addActionListener, and I can set a certain button to "X" or "O", but how do I make it so the first button click turns it to X, the second to O and so on. .addActionListener wont work properly because I have to use it on a certain button, but I don't know which button will be pressed.
Here's the code I've written.
public class XO {
public static void main(String[] args) {
JFrame myForm=new JFrame("X-O");
myForm.setSize(255, 300);
myForm.setLocation(0, 0);
JButton []buttons=new JButton[10];
int x=40, y=0;
for(int i=0;i<10;i++)
{
if(i%3==0)
{
y+=50; x=40;
}
buttons[i]=new JButton((i+1)+"");
buttons[i].setSize(50, 50);
buttons[i].setLocation(x, y);
myForm.add(buttons[i]);
x+=50;
}
buttons[9].setText("Start Over");
buttons[9].setLocation(80, 205);
buttons[9].setSize(70, 50);
buttons[9].setMargin(new Insets(0, 0, 0, 0));
buttons[0].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
buttons[0].setText("X");
buttons[0].setForeground(Color.BLUE);
buttons[0].setFont(new Font("Arial", Font.PLAIN, 30));
buttons[0].setMargin(new Insets(0, 0, 0, 0));
buttons[0].setEnabled(false);
}
});
myForm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myForm.setLayout(null);
myForm.setVisible(true);
}
}
As you can see, I will have to use .setActionListener on a specific button, but I dont know which button will be pressed. I hope you get what I mean.
Thanks in advance.
Outside of your main method, you can declare a static counter to determine whose move it is:
private static int turnCount = 0;
Add the action listeners for each of your buttons within your loop, and determine what to set the button text as based on the counter. Be sure to increment your turnCount variable within the action listener:
for(int i=0;i<10;i++)
{
if(i%3==0)
{
y+=50; x=40;
}
buttons[i]=new JButton((i+1)+"");
buttons[i].setSize(50, 50);
buttons[i].setLocation(x, y);
int butNum = i;
buttons[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String currentPlayer = turnCount % 2 == 0 ? "X" : "O";
buttons[butNum].setText(currentPlayer);
buttons[butNum].setForeground(Color.BLUE);
buttons[butNum].setFont(new Font("Arial", Font.PLAIN, 30));
buttons[butNum].setMargin(new Insets(0, 0, 0, 0));
buttons[butNum].setEnabled(false);
turnCount++;
}
});
myForm.add(buttons[i]);
x+=50;
}
You can get the button that was pressed from the ActionEvent via the getSource method - just cast it to a JButton.
for (JButton button : buttons) { // one listener per button
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource(); // which button
button.setText(getPlayer()); // get X or O
button.setForeground(Color.BLUE);
button.setFont(new Font("Arial", Font.PLAIN, 30));
button.setMargin(new Insets(0, 0, 0, 0));
button.setEnabled(false);
togglePlayer(); // toggle between X and O
}
});
}
I moved the body of your code to a run method and added methods to get the player and toggle the player.
public static void main(String[] args) {
XO game = new XO();
game.run();
}
private String player = "X";
private String getPlayer() {
return player;
}
private void togglePlayer() {
player = "X".equals(player) ? "O" : "X";
}
public void run() {
JFrame myForm = new JFrame("X-O");
// rest of your code
// plus my actionListener changes
// ...
}
Related
I have a small program, that creates a something, that could be considered a joystick. Everything works, but there is a glitch, I can't work out how to fix. If mouse moves too fast, the JLabel that I'm dragging around, sticks, as mouse has moved outside of the drawn box. I could increase the size of Jlabel, but then the "O" is offset too much from mouse. (I'd rather even decrease the size, but with this implementation, maximum mouse speed is too low).
Any ideas how to fix this?
This is the whole code, btw, anyone can go ahead and compile, to see what is the problem exactly, when mouse moves too fast.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainClass implements ActionListener, MouseListener, MouseMotionListener
{
int labelSize = 20;
int screenOffsetX = 58;
int screenOffsetY = 130;
JFrame frame;
JLabel xAxis;
JLabel move;
JLabel drag;
JLabel yAxis;
JLabel xAxisDrag;
JLabel yAxisDrag;
JLabel radio;
JLayeredPane panel;
Robot rob;
public static void main(String[] args)
{
new MainClass();
}
public MainClass()
{
frame = new JFrame("app");
frame.setLayout(null);
frame.setBounds(20, 20, 400, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
move = new JLabel("Movement");
move.setBounds(150, 0, 100, 15);
frame.add(move);
xAxis = new JLabel("X");
xAxis.setBounds(100, 20, 50, 15);
frame.add(xAxis);
yAxis = new JLabel("Y");
yAxis.setBounds(200, 20, 50, 15);
frame.add(yAxis);
drag = new JLabel("Dragging");
drag.setBounds(150, 40, 100, 15);
frame.add(drag);
xAxisDrag = new JLabel("X");
xAxisDrag.setBounds(100, 60, 50, 15);
frame.add(xAxisDrag);
yAxisDrag = new JLabel("Y");
yAxisDrag.setBounds(200, 60, 50, 15);
frame.add(yAxisDrag);
radio = new JLabel("O");
radio.setBounds(0, 0, labelSize, labelSize);
radio.setOpaque(false);
radio.setEnabled(false);
panel = new JLayeredPane();
panel.setBounds(50, 100, 257, 257);
panel.setLayout(null);
panel.setBackground(new Color((float)1.0,(float)1.0,(float)1.0));
panel.setOpaque(true);
panel.add(radio);
radio.setLocation(128, 128);
frame.add(panel);
panel.addMouseMotionListener(this);
panel.addMouseListener(this);
frame.revalidate();
frame.repaint();
}
#Override
public void actionPerformed(ActionEvent e) {}
#Override
public void mouseDragged(MouseEvent e)
{
if(!(e.getPoint().x<0 || e.getPoint().y<0 || e.getPoint().x>257 || e.getPoint().y>257))
{
xAxis.setText("X: "+((e.getPoint().x/4)-32));
yAxis.setText("Y: "+((e.getPoint().y/4)-32));
}
if(e.getPoint().x<0 || e.getPoint().y<0 || e.getPoint().x>257 || e.getPoint().y>257)
{ //Neļauj iziet ārpus paneļa;
try
{
rob = new Robot();
if(e.getPoint().x<0)
rob.mouseMove((screenOffsetX+frame.getX()), (e.getPoint().y+screenOffsetY+frame.getY()));
if(e.getPoint().y<0)
rob.mouseMove((e.getPoint().x+screenOffsetX+frame.getX()), (screenOffsetY+frame.getY()));
if(e.getPoint().x>257)
rob.mouseMove((257+screenOffsetX+frame.getX()), (e.getPoint().y+screenOffsetY+frame.getY()));
if(e.getPoint().y>257)
rob.mouseMove((e.getPoint().x+screenOffsetX+frame.getX()), (257+screenOffsetY+frame.getY()));
}
catch (AWTException e1)
{
e1.printStackTrace();
}
}
if( (e.getPoint().x>=radio.getX() && e.getPoint().x<=radio.getX()+labelSize) &&
(e.getPoint().y>=radio.getY() && e.getPoint().y<=radio.getY()+labelSize)
)
{ //Ja kursors ir uz JLabel, tad pārvieto;
xAxisDrag.setText("X: "+((e.getPoint().x/4)-32));
yAxisDrag.setText("Y: "+((e.getPoint().y/4)-32));
radio.setBounds(e.getPoint().x-(labelSize/2), e.getPoint().y-(labelSize/2), labelSize, labelSize);
}
}
#Override
public void mouseMoved(MouseEvent e)
{
xAxis.setText("X: "+((e.getPoint().x/4)-32));
yAxis.setText("Y: "+((e.getPoint().y/4)-32));
}
#Override
public void mouseClicked(MouseEvent arg0) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e)
{
radio.setLocation(124, 124);
xAxisDrag.setText("X: "+0);
yAxisDrag.setText("Y: "+0);
}
}
Replace
if( (e.getPoint().x>=radio.getX() && e.getPoint().x<=radio.getX()+labelSize) &&
(e.getPoint().y>=radio.getY() && e.getPoint().y<=radio.getY()+labelSize)
)
{ //Ja kursors ir uz JLabel, tad pārvieto;
xAxisDrag.setText("X: "+((e.getPoint().x/4)-32));
yAxisDrag.setText("Y: "+((e.getPoint().y/4)-32));
radio.setBounds(e.getPoint().x-(labelSize/2), e.getPoint().y-(labelSize/2), labelSize, labelSize);
}
by:
if( (e.getPoint().x>=radio.getX() && e.getPoint().x<=radio.getX()+labelSize) &&
(e.getPoint().y>=radio.getY() && e.getPoint().y<=radio.getY()+labelSize)
)
{
//Has the mouse been clicked inside the radio before grabbing started ?
if(grab==0) //if it is the first iteration of the function mousedragged
grab=2; //proceed to "grab"
}
if(grab==2 && (e.getPoint().x>=0 && e.getPoint().x<panel.getWidth()) &&
(e.getPoint().y>=0 && e.getPoint().y<panel.getHeight())
)
{ //Ja kursors ir uz JLabel, tad pārvieto;
System.out.println(radio.getX()+" "+radio.getY());
xAxisDrag.setText("X: "+((e.getPoint().x/4)-32));
yAxisDrag.setText("Y: "+((e.getPoint().y/4)-32));
radio.setBounds(e.getPoint().x-(labelSize/2), e.getPoint().y-(labelSize/2), labelSize, labelSize);
}
if(grab!=2) // if grabbing is not started
grab=1; // first iteration is over
Update MouseReleased function to:
#Override
public void mouseReleased(MouseEvent e)
{
//this a new line
//grabbing is over
grab=0; // go back to idle state
radio.setLocation(124, 124);
xAxisDrag.setText("X: "+0);
yAxisDrag.setText("Y: "+0);
}
Finally , add a new field called grab to your class MainClass:
private int grab=0; //idle state
The meaning of grab:
1. grab=0 => It is the first time that the function MouseDragged is executed and "grabbing" is not started yet. In fact when you drag the mouse this function is iterated like an infinite loop until you release the mouse. So it is important to know when it has started.
2. grab=1 => Iteration has started but there is no "grabbing"
3. grab=2 => "grabbing" has started. You can notice the condition grab==0 before the affectation. In fact I tried to avoid the case when the mouse is dragged from somewhere else and goes through "radio" and then the radio is "grabbed". That's why I checked that it is the first iteration. In this case we have grab=1 => the radio is not grabbed
There are many questions about this, but they are all coming up with revalidate stuff.. my code works from within one class but doesnt if it gets triggered from another class.
I have a JPanel, i want to add a JPanel to it.
I have a method startGame() witch should remove the panel added to it currently.
The method startGame() works if i call it directly from the constructor.
The method startGame() does not work if i call it from another class.
public TopMenu topMenu;
public JPanel welcomeScreen;
public JPanel gameScreen;
public WelcomePanel() {
setLayout(null);
setSize(1000, 700);
init();
setBackground(Color.ORANGE);
}
public void init() {
topMenu = new TopMenu(this);
welcomeScreen = new WelcomeScreen();
gameScreen = new Game();
add(topMenu);
add(this.welcomeScreen);
}
public void startGame() {
remove(this.welcomeScreen);
add(gameScreen);
revalidate();
}
so if - after init - i would call startGame() it works, and it removes the welcomeScreen and adds gameScreen.
If i call that from an actionlistener in topMenu, it doesnt do anything. Neighter remove the old panel, or add the new one over the old panel.
Other classes:
WelcomeScreen
public class WelcomeScreen extends JPanel {
public WelcomeScreen()
{
setBounds(0, 50, GameBase.gameWidth, GameBase.gameHeight - 50);
setBackground(Color.GREEN);
}
}
Game
public class Game extends JPanel {
public Image background;
public Game()
{
background = new ImageIcon("src/game/images/mainMenu/MainMenu.png").getImage();
setBounds(50, 50, 700, 650);
setBackground(Color.GREEN);
}
public void paintComponent(Graphics g) {
g.drawImage(background, 0, 0, null);
}
}
TopMenu (basically: the actionlistener calls the startGame method on a button - tested and works.)
public class TopMenu extends JPanel implements ActionListener {
public topMenuButton playButton;
public topMenuButton forwardButton;
public topMenuButton menuButton;
public topMenuButton goToTheGameButton;
public Image background;
public static boolean playingNow = false;
public static boolean changingSettings = false;
public static boolean inTheMenu = true;
WelcomePanel welcomePanel;
public TopMenu(WelcomePanel welcomePanel) {
this.welcomePanel = welcomePanel;
background = new ImageIcon("src/game/images/TopBalk/Topbalk.png").getImage();
setLayout(null);
setSize(new Dimension(1000, 50));
setBackground(Color.GRAY);
setButtons();
}
public void setButtons() {
//initialise all buttons
playButton = new topMenuButton("src/game/images/TopBalk/Play_Button.png", "src/game/images/TopBalk/PlayGlow_Button.png", 110, 9, 43, 48, 0, "", 30, 34);
forwardButton = new topMenuButton("src/game/images/TopBalk/Forward_Button.png", "src/game/images/TopBalk/ForwardGlow_Button.png", 150, 9, 59, 48, 0, "", 30, 34);
menuButton = new topMenuButton("src/game/images/TopBalk/Menu_Button.png", "src/game/images/TopBalk/MenuGlow_Button.png", 20, 4, 109, 48, 0, "", 38, 86);
goToTheGameButton = new topMenuButton("src/game/images/TopBalk/goToTheGame_Button_needsRework.gif", "src/game/images/TopBalk/goToTheGameGlow_Button_needsRework.gif", 400, 4, 109, 48, 0, "", 38, 86);
//add actionlisteners to buttons
playButton.addActionListener(this);
forwardButton.addActionListener(this);
menuButton.addActionListener(this);
goToTheGameButton.addActionListener(this);
//add buttons that are needed now
addUsefulButtons();
}
public void addUsefulButtons() {
//add the usefull buttons
if (playingNow) {
add(playButton);
add(forwardButton);
}
if (inTheMenu) {
add(goToTheGameButton);
}
if(!inTheMenu){
add(menuButton);
}
if(changingSettings)
{
}
}
public void removeButtons() {
remove(playButton);
remove(forwardButton);
remove(menuButton);
}
#Override
public void actionPerformed(ActionEvent e) {
//If the player hits play or pause
if (e.getSource().toString().contains("Play") || e.getSource().toString().contains("Pauze")) {
//change the pause state of the game
GameLoop.paused = !GameLoop.paused;
//check if the game is paused
if (GameLoop.paused)
//change the play button image
playButton.setImage("src/game/images/TopBalk/Pauze_Button.png", "src/game/images/TopBalk/PauzeGlow_Button.png");
else {
//change the play button image
playButton.setImage("src/game/images/TopBalk/Play_Button.png", "src/game/images/TopBalk/PlayGlow_Button.png");
}
//if the player hits fast forward
} else if (e.getSource().toString().contains("Forward")) {
//do stuff to fast forward
System.out.println("Forward");
}
//if the player hits the menu button
else if (e.getSource().toString().contains("Menu_Button.png")) {
//do stuff to show the menu
System.out.println("Menu");
}
//if the goToTheGame button is pressed
else if (e.getSource().toString().contains("goToTheGame")){
welcomePanel.startGame();
}
//if there is no recognised action command
else{
//just display a message in the console.. WTF??
System.out.println("TopMenuActionlistener has unknown potentials!! Check the actionPerformed plz..");
}
}
public void paintComponent(Graphics g) {
g.drawImage(background, 0, 0, null);
}
}
Validating a component means laying out its subcomponents, which will then repaint them if they they need to move. Since you are using absolute positioning rather than a layout manager, this isn't going to do anything for you.
Instead of calling revalidate(), call repaint().
I have a Java program with two textareas and a button. I want to allow the user to write one one textarea using a touch pen or mouse and when he/she clicks the button, the drawn content should be send to textarea no 2.
So the textarea where the user is writing on, I gave a mousemotion listener with paintComponent method in it.
When I run the application, I have realized that texarea method getText() and setText() can't set or get the drawn content.
Is there way I can achieve the above task? I have also tried JPanel but it doesn't have the setContent() method.
I appreciate any help.
This is my first textarea where user is writing on with touchpen.
public class Area1 extends JTextArea {
int pointcount = 0;
Point[] points = new Point[10000];
public Area1() {
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent event) {
if (pointcount < points.length) {
points[pointcount] = event.getPoint();
++pointcount;
repaint();
}
}
});
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < pointcount; i++) {
g.fillOval(points[i].x, points[i].y, 4, 4);
}
}
}
this is my overall application with textarea2 and button
public class Handwriting extends JFrame {
private JTextArea area2;
private JButton b1;
Area1 area1;
public Handwriting() {
Box box = Box.createHorizontalBox();
area1 = new Area1();
area1.setRows(30);
area1.setColumns(30);
area2 = new JTextArea(30, 30);
b1 = new JButton("Copy");
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == b1) {
area2.setText(area1.getText());
}
}
});
box.add(area1);
box.add(b1);
box.add(area2);
add(box);
}
public static void main(String[] args) {
Handwriting hand = new Handwriting();
hand.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
hand.setSize(500, 500);
hand.setVisible(true);
}
}
One possible solution would be to make one class as a Inner Class of the other , that way even private instance fields can be accessed
I have been making an applet for a project for my school but I stumbled upon a nasty error. My problem is probably quite common but I can't seem to find an answer for it. I have been getting the error:
The type Pyramid must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent)
but I have already implemented the method in there and it's spelling is correct. I checked so many times that my head hurts. My project has frozen at this process for like 3 hours now and I have no idea how to get it to work. Oh and also do you think that using 3 polygons to draw a pyramid is the best way to do it in java?
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Pyramid extends Applet implements ActionListener {
int n = 3; // vurhove
double a, k;
double Sok, S, V;
public void init()
{
setLayout(null);
TextField aT; // textbox za osn. rub
aT = new TextField("Osnoven rub", 20);
aT.setBounds(20, 410, 125, 20);
TextField lT; // textbox za ok. rub
lT = new TextField("Okolen rub", 20);
lT.setBounds(20, 460, 125, 20);
TextField SokT; // textbox S ok.
SokT = new TextField("Okolna povurhnina", 20);
SokT.setBounds(20, 510, 125, 20);
TextField ST; // textbox S1
ST = new TextField("Osnovna povurhnina", 20);
ST.setBounds(20, 560, 125, 20);
TextField VT; // textbox za obema
VT = new TextField("Obem", 20);
VT.setBounds(20, 610, 125, 20);
Button ochButton; // izchertava piramidata
ochButton = new Button("Izchertai");
ochButton.setBounds(700, 435, 100, 30);
ochButton.addActionListener(ActionOchButton);
Button oznButton; // ozna4ava vurhovete, izpisva velichinite
oznButton = new Button("Oznachi cherteja");
oznButton.setBounds(700, 510, 100, 30);
oznButton.addActionListener(ActionOznButton);
Button iButton; // iz4islqva veli4inite
iButton = new Button("Izchisli");
iButton.setBounds(700, 585, 100, 30);
iButton.addActionListener(ActioniButton);
add(aT);
add(lT);
add(SokT);
add(ST);
add(VT);
add(ochButton);
add(oznButton);
add(iButton);
Color bg;
bg = new Color(168,168,168);
setBackground(bg);
}
ActionListener ActionOchButton = new ActionListener() {
public void actionPerformed(ActionEvent e){
Graphics g = getGraphics();
int px[] = {340, 440, 490};
int py[] = {235, 335, 235};
g.drawPolygon(px, py, 3);
int px1[] = {340, 415, 490};
int py1[] = {235, 60, 235};
g.drawPolygon(px1, py1, 3);
int px2[] = {440, 415, 490};
int py2[] = {335, 60, 235};
g.drawPolygon(px2, py2, 3);
}
};
ActionListener ActionOznButton = new ActionListener() {
public void actionPerformed(ActionEvent e){
}
};
ActionListener ActioniButton = new ActionListener() {
public void actionPerformed(ActionEvent e){
}
};
public void paint(Graphics g)
{
g.setColor(Color.white);
g.drawRect(20, 20, 780, 370);
}
}
You have not implemented the method, plain and simple.
You need to have that method defined in your class. You're adding a bunch of other action listeners, but nowhere in your class do you implement the required method.
To clarify further, on the same level as your init() method, you need a public void actionPerformed(ActionEvent e) { /* ... */ } method.
You have not impleented ActionListener.actionPerformed(ActionEvent) in Pyramid, only in the three anonymous instances of ActionListener. For Pyramid to implement ActionListener, you must implement this method in th class, not in some local variable.
You should implement the method in your class. For example, here it is at the end of your Pyramid class:
#Override
public void actionPerformed(ActionEvent e) {
}
} //End of Pyramid class
Now, in this actionPerformed() method, you can determine which button was clicked and do the appropriate action. But you'll have to change a few things:
//make these instance variables
Button ochButton; // izchertava piramidata
Button oznButton; // ozna4ava vurhovete, izpisva velichinite
Button iButton; // iz4islqva veli4inite
Add action listener this way...
ochButton.addActionListener(this);
oznButton.addActionListener(this);
iButton.addActionListener(this);
Implement actionPerformed()...
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == ochButton) {
System.out.println("ochButton clicked");
} else if (e.getSource() == oznButton) {
System.out.println("oznButton clicked");
} else if (e.getSource() == iButton) {
System.out.println("iButton clicked");
}
}
Regarding drawing a pyramid, perhaps you can draw the base triangle and the top point. Then draw lines from the top point to each point of the triangle.
Okay so I am making a 2d array of JToggleButtons. I got the action listener up and going, but I have no way to tell which button is which.
If I click one, all it returns is something like
javax.swing.JToggleButton[,59,58,19x14,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#53343ed0,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=]
Is there anyway to stick some sort of item or number in the button object to associate each button?
And then when the button is clicked I can retrieve that item or number that was given to it?
Here is my button generator code. (How could I make "int l" associate (and count) to each button made, when it is called, it will return that number, or something along those lines.
JToggleButton buttons[][] = new JToggleButton[row][col];
int l = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
buttons[i][j] = new JToggleButton("");
buttons[i][j].setSize(15,15);
buttons[i][j].addActionListener(new e());
panel.add(buttons[i][j]);
l++;
}
}
ActionListner
public class e implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
System.out.println(source);
}
}
variable "source" is what I use to get my data, so how can int l, be returned through "source" (as its unique value for the unique button clicked) as a button is clicked?
Thanks,
-Austin
very simple way is add ClientProperty to the JComponent, add to your definition into loop e.g.
buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());
rename e to the MyActionListener and change its contents
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JToggleButton btn = (JToggleButton) e.getSource();
System.out.println("clicked column " + btn.getClientProperty("column")
+ ", row " + btn.getClientProperty("row"));
}
EDIT:
for MinerCraft clone isn't required to implements ony of Listeners, there is only about Icon, find out that in this code (don't implement any of Listeners anf remove used ItemListener)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonsIcon extends JFrame {
private static final long serialVersionUID = 1L;
private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ButtonsIcon t = new ButtonsIcon();
}
});
}
public ButtonsIcon() {
setLayout(new GridLayout(2, 2, 4, 4));
JButton button = new JButton();
button.setBorderPainted(false);
button.setBorder(null);
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon((errorIcon));
button.setRolloverIcon((infoIcon));
button.setPressedIcon(warnIcon);
button.setDisabledIcon(warnIcon);
add(button);
JButton button1 = new JButton();
button1.setBorderPainted(false);
button1.setBorder(null);
button1.setFocusable(false);
button1.setMargin(new Insets(0, 0, 0, 0));
button1.setContentAreaFilled(false);
button1.setIcon((errorIcon));
button1.setRolloverIcon((infoIcon));
button1.setPressedIcon(warnIcon);
button1.setDisabledIcon(warnIcon);
add(button1);
button1.setEnabled(false);
final JToggleButton toggleButton = new JToggleButton();
toggleButton.setIcon((errorIcon));
toggleButton.setRolloverIcon((infoIcon));
toggleButton.setPressedIcon(warnIcon);
toggleButton.setDisabledIcon(warnIcon);
toggleButton.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton.isSelected()) {
} else {
}
}
});
add(toggleButton);
final JToggleButton toggleButton1 = new JToggleButton();
toggleButton1.setIcon((errorIcon));
toggleButton1.setRolloverIcon((infoIcon));
toggleButton1.setPressedIcon(warnIcon);
toggleButton1.setDisabledIcon(warnIcon);
toggleButton1.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton1.isSelected()) {
} else {
}
}
});
add(toggleButton1);
toggleButton1.setEnabled(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
Just add the row and column data to each listener. You could add an explicit constructor, but I suggest adding a little method (which may have more added to it later).
buttons[i][j].addActionListener(e(i, j));
...
private ActionListener e(final int i, final int j) {
return new ActionListener() {
// i and j available here
...
(In JDK8 you should be able to use a lambda to reduce the syntax clutter.)
And then renaming it with a better name.
I made a minesweeper game and ran into a similar problem. One of the only ways you can do it, is to get the absolute location of the clicked button, then divide that by the x and y between buttons, so for me it was
if ((e.getComponent().getX() != (randx) * 25 && e.getComponent().getY() != (randy) * 25) &&bomb[randx][randy] == false) {
This code was to check if the area had bombs. So I had 25 x and y difference between location of bombs. That will just give you a general idea on how to do this.
I believe: (x - x spacing on left side) / buffer - 1 would work.
Instead of 'e.getSource()' you can always call 'e.getActionCommand()'. For each button you can specify this by:
JButton button = new JButton("Specify your parameters here"); /*you get these from getActionCommand*/
button.setText("title here"); /*as far as I remember*/