I'm trying to make a simple paint program in Java. It has 3 colors and a JField to enter the thickness. It works, except every time I enter a button, an image of that button shows up in the JPanel that contains the drawing portion.
I know that I can set the paintPane JPanel to opaque, but it relies on drawing over it self for the painting to work - otherwise it just drags a point around the screen. Thanks!!!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class SimplePainting
{
//The main method simply creates a frame, and terminates the program
//once that frame is closed.
public static void main (String [] args)
{
PaintFrame frame = new PaintFrame();
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
}
class PaintFrame extends JFrame implements ActionListener
{
JPanel pane;
PaintPane drawPane;
Color paintColor = Color.black;
private int radius = 5;
//holds the thickness of the line
JTextField thick;
public PaintFrame ()
{
//We use the JFrame consturctor to add a title to the frame
super("Windows Paint");
//set the main content pane
pane = (JPanel)getContentPane();
pane.setLayout(new BorderLayout());
//make a pane to hold the drawing
drawPane = new PaintPane();
drawPane.addMouseMotionListener(drawPane);
//Make a JPanle to hold all of the buttons
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new GridLayout(1,6));
//add the buttons
JButton black = new JButton("Black");
buttonPane.add(black);
JButton red = new JButton("Red");
buttonPane.add(red);
JButton green = new JButton("Green");
buttonPane.add(green);
//Make a field to re-enter the thickness
thick = new JTextField(3);
thick.setText("5");
JButton thickness = new JButton("Reset Thickness");
thickness.addActionListener(this);
buttonPane.add(thickness);
buttonPane.add(thick);
JButton reset = new JButton("New Drawing");
reset.addActionListener(this);
buttonPane.add(reset);
black.addActionListener(this);
red.addActionListener(this);
green.addActionListener(this);
pane.add(drawPane, BorderLayout.CENTER);
pane.add(buttonPane, BorderLayout.SOUTH);
setSize(500,200);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("Black"))
paintColor = Color.black;
else if (e.getActionCommand().equals("Red"))
paintColor = Color.red;
else if (e.getActionCommand().equals("Green"))
paintColor = Color.green;
else if (e.getActionCommand().equals("Reset Thickness"))
{
if (thick.getText() != "")
{
int lineThickness = Integer.parseInt(thick.getText());
radius = lineThickness;
}
}
else if (e.getActionCommand().equals("New Drawing"))
{
drawPane.startPaint = false;
drawPane.repaint();
}
}
class PaintPane extends JPanel implements MouseMotionListener
{
private int x;
private int y;
// don't paint a point until mouse is dragged
boolean startPaint = false;
public PaintPane()
{
setBackground(Color.white);
}
//paints a circle centered at x,y
public void paint(Graphics g)
{
//recall that the frist (x,y) coordiantes represent the top left
//corner of a box holding the circle
g.setColor(paintColor);
if (startPaint)
g.fillOval(x-radius,y-radius, 2*radius, 2*radius);
else
super.paintComponent(g);
}
public void mouseDragged(MouseEvent e)
{
startPaint = true;
x = e.getX();
y = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e)
{
}
}
}
I am trying to change the color of an icon using 3 different JButtons, each for a different color.
The icon is a circle that starts out as red default. When the user clicks the button called "blue" the circle changes color to blue, same idea for "green".
To update this icon color, i am supposed to use the repaint() method.
Here is my method to create the red circle icon.
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class ColorIcon implements Icon
{
private int width;
private Color color;
private ChangeColor c;
public ColorIcon(int aWidth, ChangeColor c)
{
this.c = c;
width = aWidth;
color = Color.RED;
}
public int getIconWidth()
{
return width;
}
public int getIconHeight()
{
return width / 2;
}
public void setColor(Color c)
{
color = c;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
color = c.color;
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double ellipse = new Ellipse2D.Double(x,y, width, width);
g2.setColor( color );
g2.fill( ellipse );
}
}
And here is the class i use to test it. This class is the one with the event handler that creates the buttons that when pressed should change the color of the icon.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class TestColorIcon{
public java.awt.Color color = java.awt.Color.RED;
public Component createComponents()
{
JButton buttonRed = new JButton("Red");
JButton buttonBlue = new JButton("Blue");
JButton buttonGreen = new JButton("Green");
final ColorIcon icon = new ColorIcon( 20);
final JLabel label = new JLabel( icon );
JPanel panel = new JPanel();
panel.setLayout( new GridLayout(0, 3) );
panel.add( buttonRed );
panel.add( buttonBlue );
panel.add( buttonGreen );
panel.add( label );
buttonRed.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
color = Color.RED;
label.repaint();
}
});
buttonBlue.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
color = Color.BLUE;
label.repaint();
}
});
buttonGreen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
color = Color.GREEN;
label.repaint();
}
});
return panel;
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
ChangeColor changeColor = new ChangeColor();
Component content = changeColor.createComponents();
frame.getContentPane().add( content );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
}
When I run this, i get an error saying compiler cannot resolve class ColorIcon.
I am not sure how to fix this error and get the desired output.
The code has gotten a bit long so i am unable to pinpoint the exact reason for the error, so any help is appreciated.
You never seem to change the color of the ColorIcon itself
buttonRed.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
color = Color.RED;
label.repaint();
}
});
Instead, make sure you are applying the color to the icon as well.
buttonRed.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
color = Color.RED;
icon.setColor(color);
label.repaint();
}
});
Icon should not be relying on any other information other then what it's provide for itself, so instead of trying to get the color from yet another source, simply use the support that the ColorIcon already has
When I run this, i get an error saying compiler cannot resolve class
ColorIcon.
Your constructor of the ColorIcon class is
public ColorIcon(int aWidth, ChangeColor c)
It expects one int and one ChnageColor arguments.
And you are calling it with wrong parameters.
final ColorIcon icon = new ColorIcon(20);
I am trying to do a JPanel that could change its size each time a click on a button. My approach to it has been to create 2 different panel with different size each. Once clicked one would became visible, and the other one invisible. SO far I have managed to make the first one invisible, but i am stuck there. Is my approach any good? What Am i missing? Here the code...
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GrowAndShrinkSquareGUI {
JFrame frame;
SquareDrawPanel greenPanel;
SquareDrawPanel greenPanel2;
public class SquareDrawPanel extends JPanel {
int locationX;
int locationY;
int width;
int height;
SquareDrawPanel(int x, int y, int w, int h) {
locationX = x;
locationY = y;
width = w;
height = h;
}
public void paintComponent(Graphics g) {
g.setColor(Color.green);
g.fillRect(locationX, locationY, width, height);
}
}
public class growAndShrinkListener implements ActionListener {
JButton button;
public growAndShrinkListener() {
JButton button = new JButton("Click me to grow the Square");
frame.add(button, BorderLayout.NORTH);
button.addActionListener(this);}
#Override
public void actionPerformed(ActionEvent e) {
System.out.print("clicked");
greenPanel.setVisible(false);
greenPanel2.setVisible(true);
}}
public static void main(String[] args) {
GrowAndShrinkSquareGUI test = new GrowAndShrinkSquareGUI();
test.go();
}
public void go() {
frame = new JFrame();
frame.setSize(500, 500);
frame.setVisible(true);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel(greenPanel);
drawPanel(greenPanel2);
growAndShrinkListener button = new growAndShrinkListener();
//addButton(CreateJButton());
}
private JPanel createRectPanel(int x, int y) {
greenPanel = new SquareDrawPanel(x, y, 100, 100);
return greenPanel;
}
private JPanel createRectPanel2(int x, int y) {
greenPanel2 = new SquareDrawPanel(x, y, 200, 200);
return greenPanel2;
}
private void drawPanel(JPanel panel) {
panel = createRectPanel(setLocationX(), setLocationY());
frame.add(panel, BorderLayout.CENTER); // DoesNot run properly
}
private int setLocationX() {
int centeredX = frame.getWidth() / 2 - 50;
return centeredX;
}
private int setLocationY() {
int centeredY = frame.getHeight() / 2 - 75;
return centeredY;
}
}
public class CustomFrame extends JFrame implements ActionListener
{
//Creating an object of this class shows a frame which toggles
//between these two sizes on a button click
private static final Dimension FIRST_SIZE = new Dimension(200, 200);
private static final Dimension SECOND_SIZE = new Dimension(400, 400);
public CustomFrame()
{
//Add a button to the frame and register an action listener
//to the current object
JButton button = new JButton("Change size");
button.addActionListener(this);
getContentPane().add(button);
//Make the frame visible
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae)
{
//This gets executed when the button is clicked
//
//We're setting the size to a new value;
//first, we fetch the current size and
//check if it's equal to the first size
setSize(getSize().equals(FIRST_SIZE)
//If so, set the frame to the second size
? SECOND_SIZE
//In all other cases, make the frame's
//size the value of FIRST_SIZE
: FIRST_SIZE);
}
}
I have created a custom jTabbedPane class which extends BasicTabbedPaneUI and have successfully created my desired jTabbedPane but now the problem is that how can I set Hand cursor for each tab in my custom jTabbedPane?
I tried to set cursor with this
tabbedPane.setUI(new CustomMainMenuTabs());
tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
this sets the cursor for whole of jTabbedPane but I want to set the cursor when mouse hovers over any of tab in it only.
How can I set Hand cursor for tabs in my jTabbedPane?
My Code is
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
public class HAAMS
{
//My Custom class for jTabbedPane
public static class CustomMainMenuTabs extends BasicTabbedPaneUI
{
protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected)
{
Graphics2D g2 = (Graphics2D) g;
Color color;
if (isSelected) { color = new Color(74, 175, 211); }
else if (getRolloverTab() == tabIndex) { color = new Color(45, 145, 180); }
else {color = new Color(68, 67, 67);}
g2.setPaint(color);
g2.fill(new RoundRectangle2D.Double(x, y, w, h, 30, 30));
g2.fill(new Rectangle2D.Double(x + 100,y,w,h));
}
}
public static void main(String[] args)
{
JFrame MainScreen = new JFrame("Custom JTabbedPane");
MainScreen.setExtendedState(MainScreen.getExtendedState() | JFrame.MAXIMIZED_BOTH);
//Setting UI for my jTabbedPane implementing my custom class CustomMainMenuTabs
JTabbedPane jtpane = new JTabbedPane(2);
jtpane.setUI(new CustomMainMenuTabs());
jtpane.add("1st Tabe", new JPanel());
jtpane.add("2nd Tabe", new JPanel());
jtpane.add("3rd Tabe", new JPanel());
MainScreen.getContentPane().add(jtpane);
MainScreen.setVisible(true);
}
}
How to set cursor to HAND_CURSOR cursor when mouse hovers over any tab only not jpanel or any other component. It would be great if done without a mouse listener.
I see a lot of answers here that are WAY too complicated (custom UIs, extra listeners, Graphics stuff, etc.).
Basically, camickr spelled it out for you. Here's a simple demo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class JTabbedPaneCursorDemo implements Runnable
{
JTabbedPane tabbedPane;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new JTabbedPaneCursorDemo());
}
public void run()
{
JPanel panelA = new JPanel();
JPanel panelB = new JPanel();
tabbedPane = new JTabbedPane();
tabbedPane.addTab("A", panelA);
tabbedPane.addTab("B", panelB);
tabbedPane.addMouseMotionListener(new MouseMotionListener()
{
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e)
{
adjustCursor(e);
}
});
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void adjustCursor(MouseEvent e)
{
TabbedPaneUI ui = tabbedPane.getUI();
int index = ui.tabForCoordinate(tabbedPane, e.getX(), e.getY());
if (index >= 0)
{
tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
}
else
{
tabbedPane.setCursor(null);
}
}
}
I want to set the cursor when mouse moves over any of tab in it.
I would guess you need to add a MouseMotionListener to the tabbed pane. Then when the mouseMoved(...) event is generated you check if the mouse is over a tab.
You should be able to use the tabForCoordinate(...) method of the BasicTabbePaneUI to determine if the mouse is over a tab or not.
Steps:
Create a MouseMotionListener and add it to your JTabbedPane
Inside the listener -> mouseMoved method, chec kif the current position of the mouse is inside the bounds of your tabs
If true, then change the cursor to a hand cursor
else show the default cursor
1.Method to check if the mouse is within the bounds of the tabs:
private static int findTabPaneIndex(Point p, JTabbedPane tabbedPane) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
if (tabbedPane.getBoundsAt(i).contains(p.x, p.y)) {
return i;
}
}
return -1;
}
2.The mouse listener:
MouseMotionListener listener = new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
if (findTabPaneIndex(e.getPoint(), tabbedPane) > -1) {
tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
} else {
tabbedPane.setCursor(new Cursor((Cursor.DEFAULT_CURSOR)));
}
}
};
3.To add the listener to the JTabbedPane:
jtpane.addMouseMotionListener(listener);
Related Documentation:
MouseMotionListener
How to Write a Mouse-Motion Listener
The final code:
Putting all the peices together, you get the following:
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
public class HAAMS {
// My Custom class for jTabbedPane
public static class CustomMainMenuTabs extends BasicTabbedPaneUI {
protected void paintTabBackground(Graphics g, int tabPlacement,
int tabIndex, int x, int y, int w, int h, boolean isSelected) {
Graphics2D g2 = (Graphics2D) g;
Color color;
if (isSelected) {
color = new Color(74, 175, 211);
} else if (getRolloverTab() == tabIndex) {
color = new Color(45, 145, 180);
} else {
color = new Color(68, 67, 67);
}
g2.setPaint(color);
g2.fill(new RoundRectangle2D.Double(x, y, w, h, 30, 30));
g2.fill(new Rectangle2D.Double(x + 100, y, w, h));
}
}
public static void main(String[] args) {
JFrame MainScreen = new JFrame("Custom JTabbedPane");
MainScreen.setExtendedState(MainScreen.getExtendedState()
| JFrame.MAXIMIZED_BOTH);
JTabbedPane jtpane = new JTabbedPane(2);
jtpane.setUI(new CustomMainMenuTabs());
MouseMotionListener listener = new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
if (findTabPaneIndex(e.getPoint(), tabbedPane) > -1) {
tabbedPane.setCursor(new Cursor((Cursor.HAND_CURSOR)));
} else {
tabbedPane.setCursor(new Cursor((Cursor.DEFAULT_CURSOR)));
}
}
};
jtpane.add("1st Tabe", new JPanel());
jtpane.add("2nd Tabe", new JPanel());
jtpane.add("3rd Tabe", new JPanel());
jtpane.addMouseMotionListener(listener);
MainScreen.getContentPane().add(jtpane);
MainScreen.setVisible(true);
}
private static int findTabPaneIndex(Point p, JTabbedPane tabbedPane) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
if (tabbedPane.getBoundsAt(i).contains(p.x, p.y)) {
return i;
}
}
return -1;
}
}
You can use:
public void setTabComponentAt(int index,
Component component)
And then you do
component.addMouseListener(yourListener)
I have changed main menthod according to your need that Hand cursor will be visible only on tab header . check if it solve your problem
Working Code
public static void main(String[] args)
{
JFrame MainScreen = new JFrame("Custom JTabbedPane");
MainScreen.setExtendedState(MainScreen.getExtendedState() | JFrame.MAXIMIZED_BOTH);
MouseListener listener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
JTabbedPane jp=(JTabbedPane)(e.getComponent().getParent().getParent());
jp.setSelectedIndex(jp.indexAtLocation(e.getComponent().getX(),e.getComponent().getY()));
}
#Override
public void mouseEntered(MouseEvent e) {
e.getComponent().setCursor(new Cursor((Cursor.HAND_CURSOR)));
}
};
JLabel jlabel1=new JLabel("1st Tabe");
jlabel1.addMouseListener(listener);
JLabel jlabel2=new JLabel("2nd Tabe");
jlabel2.addMouseListener(listener);
JLabel jlabel3=new JLabel("3rd Tabe");
jlabel3.addMouseListener(listener);
//Setting UI for my jTabbedPane implementing my custom class CustomMainMenuTabs
JTabbedPane jtpane = new JTabbedPane(2);
jtpane.setUI(new CustomMainMenuTabs());
jtpane.add("1st Tabe", new JPanel());
jtpane.setTabComponentAt( 0, jlabel1);
jtpane.add("2nd Tabe", new JPanel());
jtpane.setTabComponentAt(1, jlabel2);
jtpane.add("3rd Tabe", new JPanel());
jtpane.setTabComponentAt( 2, jlabel3);
MainScreen.getContentPane().add(jtpane);
MainScreen.setVisible(true);
}
Short
Just add this code to your CustomMainMenuTabs:
public static class CustomMainMenuTabs extends BasicTabbedPaneUI
{
protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected)
{
// ...
}
private static final Cursor DEFAULT_CURSOR = Cursor.getDefaultCursor();
private static final Cursor HAND_CURSOR = new Cursor((Cursor.HAND_CURSOR));
protected void setRolloverTab(int index) {
tabPane.setCursor((index != -1) ? HAND_CURSOR : DEFAULT_CURSOR);
super.setRolloverTab(index);
}
}
Explanation
Since you're already extending BasicTabbedPaneUI you can simply extend the mechanics for painting the rollover tab, which is already implemented there without the need of using more listeners or calculating coordinates yourself.
The rolling over is a mechanic that has been present in the component since Java 5 and this is a proper extension, just need to override and extend the method. This method is called whenever the mouse moves in the tab component (it affects the tab area but does not affect the children) and and it's kept updated.
I've tried your code snippet with this addition and worked fine.
It's actually a lot easier than installing a custom UI delegate.
You can install your own labels as the tab components (the components inside the tab handles), which will have their own cursors. Following is a simple example with 3 tabs, and a different cursor for the body of the tabbed pane and each of the tabs:
import java.awt.*;
import javax.swing.*;
public class TestTabCursor extends JFrame {
private JTabbedPane contentPane;
public TestTabCursor() {
super("Test tab cursor");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(640, 480);
setLocation(100, 100);
createContentPane();
setCursors();
}
private void createContentPane() {
contentPane = new JTabbedPane();
addTab(contentPane);
addTab(contentPane);
addTab(contentPane);
setContentPane(contentPane);
}
private void addTab(JTabbedPane tabbedPane) {
int index = tabbedPane.getTabCount() + 1;
JLabel label = new JLabel("Panel #" + index);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setFont(label.getFont().deriveFont(72f));
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(Color.white);
panel.add(label, BorderLayout.CENTER);
JLabel title = new JLabel("Tab " + index);
tabbedPane.add(panel);
tabbedPane.setTabComponentAt(index - 1, title);
}
private void setCursors() {
contentPane.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
contentPane.getTabComponentAt(0).setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
contentPane.getTabComponentAt(1).setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
contentPane.getTabComponentAt(2).setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new TestTabCursor();
frame.setVisible(true);
}
});
}
}
I am trying to write a Battleship program using Java Swing and currently I have a class that makes two grids. I am trying to find out the location of which button was clicked so I can use this later to place shots etc... Unfortunately I am having a fair bit of trouble with this.
I have got the object to print out every thing that is in it by using the actionPerformed method but I only want the grid[x][y]. How do I go about this?
Thanks in advance for any help.
package testapp;
/**
*
* #author Craig
*/
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.Border;
public class menu extends JPanel implements ActionListener{
JButton[][] grid;
TextField text = new TextField(20);
public menu(int width, int length) {
Border playerBorder = BorderFactory.createTitledBorder("Player");
Border comBorder = BorderFactory.createTitledBorder("Com");
JPanel player = new JPanel();
player.setBorder(playerBorder);// set border round player grid
player.setLayout(new GridLayout(4,4));
grid=new JButton[width][length]; //allocate the size of grid
for(int y=0; y<length; y++){
for(int x=0; x<width; x++){
grid[x][y]=new JButton(); //creates new button
player.add(grid[x][y]); //adds button to grid
grid[x][y].setBackground(Color.BLUE);//sets grid background colour
grid[x][y].setPreferredSize(new Dimension(40, 40));//sets each grid buttons dimensions
add(text);
grid[x][y].addActionListener(this);
}
}
JPanel com = new JPanel();
com.setBorder(comBorder);// set border round com grid
com.setLayout(new GridLayout(4,4));
grid=new JButton[width][length]; //allocate the size of grid
for(int y=0; y<length; y++){
for(int x=0; x<width; x++){
grid[x][y]=new JButton(); //creates new button
com.add(grid[x][y]); //adds button to grid
grid[x][y].setBackground(Color.BLUE);//sets grid background colour
grid[x][y].setPreferredSize(new Dimension(40, 40));//sets each grid buttons dimensions
}
}
//this.setLayout(new FlowLayout());
this.add(player);
this.add(com);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof JButton) {
JButton btn = (JButton)source;
text.setText("IN THE BOX ");
}
}
}
There are different options. Extending JButton should IMHO be the last resort, and hardly ever necessary. Looping through the grid[][] array and checking whether they are the source of the respective event may be OK. But another (IMHO simple and elegant) solution is to use anonymous listeners:
// Where the grid buttons are created:
....
grid[x][y].addActionListener(createActionListener(x, y));
private ActionListener createActionListener(final int x, final int y)
{
return new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
clickedButton(x, y);
}
};
}
private void clickedButton(int x, int y)
{
System.out.println("Clicked "+x+" "+y);
}
EDIT: Again, in form of a http://sscce.org/ (you could have created one, then I could have integrated my answer in your example...)
/**
*
* #author Craig and me :D
*/
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.Border;
public class menu extends JPanel {
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new menu(4,4));
f.setLocationRelativeTo(null);
f.pack();
f.setVisible(true);
}
JButton[][] grid;
TextField text = new TextField(20);
public menu(int width, int length) {
Border playerBorder = BorderFactory.createTitledBorder("Player");
Border comBorder = BorderFactory.createTitledBorder("Com");
JPanel player = new JPanel();
player.setBorder(playerBorder);// set border round player grid
player.setLayout(new GridLayout(4,4));
grid=new JButton[width][length]; //allocate the size of grid
for(int y=0; y<length; y++){
for(int x=0; x<width; x++){
grid[x][y]=new JButton(); //creates new button
player.add(grid[x][y]); //adds button to grid
grid[x][y].setBackground(Color.BLUE);//sets grid background colour
grid[x][y].setPreferredSize(new Dimension(40, 40));//sets each grid buttons dimensions
add(text);
grid[x][y].addActionListener(
createActionListener(x, y, "Player"));
}
}
JPanel com = new JPanel();
com.setBorder(comBorder);// set border round com grid
com.setLayout(new GridLayout(4,4));
grid=new JButton[width][length]; //allocate the size of grid
for(int y=0; y<length; y++){
for(int x=0; x<width; x++){
grid[x][y]=new JButton(); //creates new button
com.add(grid[x][y]); //adds button to grid
grid[x][y].setBackground(Color.BLUE);//sets grid background colour
grid[x][y].setPreferredSize(new Dimension(40, 40));//sets each grid buttons dimensions
grid[x][y].addActionListener(
createActionListener(x, y, "Computer"));
}
}
//this.setLayout(new FlowLayout());
this.add(player);
this.add(com);
}
private ActionListener createActionListener(
final int x, final int y, final String name)
{
return new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
clickedButton(x, y, name);
}
};
}
private void clickedButton(int x, int y, String name)
{
System.out.println("Clicked "+x+" "+y+" for "+name);
}
}