So I have my images stored as ImageIcon's on JButtons. I want the user to click on the JButton of the piece they want to use and then click on another JButton to move it there, how would I do this?
I've tried using an actionListener to get the ImageIcon but its proving very complicated especially because I have an 2d array of JButton Images.
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
System.out.println(actionEvent.getActionCommand());
}
};
JButton[][] squares = new JButton[8][8];
Border emptyBorder = BorderFactory.createEmptyBorder();
for (int row = 0; row < squares.length; row++) {
for (int col = 0; col < squares[row].length; col++) {
JButton tempButton = new JButton();
tempButton.setBorder(emptyBorder);
tempButton.setSize(64, 64);
squares[row][col] = tempButton;
squares[row][col].addActionListener(actionListener);
panel.add(squares[row][col]);
squares[0][0].setIcon(new ImageIcon(BoardGUI.class.getResource("castle.png"), "castle"));
}
}
Try the following code. I don't know the exact code for working with ImageIcons on JButtons, but this gets the ideas across:
JButton pieceToMoveButton = null; //variable that persists between actionPerformed calls
public void actionPerformed(ActionEvent actionEvent)
{
JButton button = (JButton)actionEvent.getSource();
if (pieceToMoveButton == null) //if this button press is selecting the piece to move
{
//save the button used in piece selection for later use
pieceToMoveButton = button;
}
else //if this button press is selecting where to move
{
//move the image to the new button (the one just pressed)
button.imageIcon = pieceToMoveButton.imageIcon
pieceToMoveButton = null; //makes the next button press a piece selection
}
}
Not sure if this is what you are looking for but is one way of moving the position of a JButton to another:
Now as an example pretend that there is already code declaring and initializing a JButton (JButton thatotherbutton = new JButton...etc.). Moving it to a certain location can be done as such:
Rectangle rect = thatotherbutton.getBounds();
xcoordinate = (int)rect.getX();
ycoordinate = (int)rect.getY();
chesspiecebutton.setBounds(xcoordinate, ycoordinate, xlengthofbutton, ylengthofbutton);
Use these coordinates to set the new bounds (in other words, the position) of your JButton upon clicking on another JButton.
Related
I am currently coding a game and part of it consist of having different tiles to be put in a board. I plan on simulating this by having different buttons that will be used to represent the tiles with their corresponding coordinates. For example, one button will say "A1", "A2", etc. What I would like to accomplish, is to have the user click on the "A1" tile and then the button on the board that represents "A1" will change colors, is there any way to go through the buttons on the board and compare its text to the selection of the user? The following is what I used to create the board:
JButton[][] buttons = new JButton[9][12];
JPanel panel = new JPanel(new GridLayout(9,12,5,5));
panel.setBounds(10, 11, 800, 600);
frame.getContentPane().add(panel);
//board
for (int r = 0; r < 9; r++)
{
for (int c = 0; c < 12; c++)
{
buttons[r][c] = new JButton("" + (c + 1) + numberList[r]);
buttons[r][c].setBackground(Color.WHITE);
panel.add(buttons[r][c]);
}
}
This is what I wrote on the code of one of the tiles
JButton tile1 = new JButton ("A1");
tile1.setBounds(60,725,60,60);
frame.getContentPane().add(tile1);
tile1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String buttonText = tile1.getText();
// iterating through all buttons:
for(int i=0;i<buttons.length;i++){
for(int j=0;j<buttons[0].length;j++)
{
JButton b = buttons[i][j];
String bText = b.getText();
if(buttonText.equals(bText))
{
[i][j].setBackground(Color.BLACK);
}
}
}
}
} );
However, it is given me an error saying that there is an action expected after "{"
You may add an action listener to each of the JButton you are creating in the loop like below:
buttons[r][c].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// your code here
}
} );
Placing the listener in your code may look like
JButton[][] buttons = new JButton[9][12];
JPanel panel = new JPanel(new GridLayout(9,12,5,5));
panel.setBounds(10, 11, 800, 600);
frame.getContentPane().add(panel);
//board
for (int r = 0; r < 9; r++)
{
for (int c = 0; c < 12; c++)
{
buttons[r][c] = new JButton("" + (c + 1) + numberList[r]);
buttons[r][c].setBackground(Color.WHITE);
buttons[r][c].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
String buttonText = button.getText();
// now iterate over all the jbuttons you have
for(int i=0;i<buttons.length;i++){
for(int j=0;j<buttons[0].length;j++){
JButton b = buttons[i][j];
String bText = b.getText();
if(buttonText.equals(bText)){
// you found a match here
// and you have the positions i, j
//
}
}
}
}
} );
panel.add(buttons[r][c]);
}
}
And you could store the the colors to be changed to in global static array, and use that array in your action listener.
For information on adding listener to the JButton, you may refer this thread How do you add an ActionListener onto a JButton in Java
Hope this helps!
You need listeners.
Implement ActionListener to your class. This will require you to add public void actionPerformed(ActionEvent e) {} to your class.
Every JButton you use should have an action listener.
Apply one like that:
JButton but = new JButton();
but.addActionListener(this);
Finally, in the actionPerformed method we added, you need to add something like that:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == but)
but.setBackground(Color.BLACK);
}
P.S. you can get a button's text value by the means of:
but.getText();
I have a gridLayout of JButtons. I'd like to distinguish every JButton from each other in the actionPerformed function.
I don't want to "name" each JButton. The user press a JButton randomly. Is there any method to know which button has been pressed?
It is possible?
[....]
tUsuariCPU = new JButton[mida][mida];
for (int i=0;i<size;i++){
for (int j=0;j<size;j++){
JButton temp = new JButton();
tUsuariCPU[i][j] = temp;
temp.addActionListener(this);
panel.add(temp);
}
}
}
public void actionPerformed(ActionEvent e) {}
[....]
}
If you wish to use a single ActionListener, you can check which Component fired the event by using the getSource button and comparing the instance to the JButton instances. Below uses a loop to loop over the 2D array of JButtons:
public void actionPerformed(ActionEvent e) {}
for ( int i = 0; i < tUsuariCPU.length; i++ ){
for ( int j = 0; j < tUsuariCPU[i].length; j++ ){
if ( e.getSource() == tUsuariCPU[i][j] ){
//do something
}
}
}
}
Alternatively, you can add a single ActionListener per button, or set the ActionCommand of the JButton and use this value to determine which JButton fired the event (e.getActionCommand().equals(myButton.getActionCommand()))
Ok so I'm building to show students how a loop goes through an array, I have added 2 images to help explain and the code, the first is the result I get after I click go then it freezes . The Second image is what I'd like it to do after you put in the values of 1 in start, 15 in stop, 3 in step and click the Go Button. And then to be cleared on the click of Clear button. I think they probably related. Can anyone see the problem? Thanks in advanced!
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import javax.swing.JOptionPane;
public class Checkerboard extends Frame implements ActionListener
{
int[] blocksTextField = new int[15];
Panel blocksPanel = new Panel();
TextArea blocksDisplay[] = new TextArea[16];
TextField start = new TextField (3);
TextField stop = new TextField (3);
TextField step = new TextField (3);
//Colors
Color Red = new Color(255, 90, 90);
Color Green = new Color(140, 215, 40);
Color white = new Color(255,255,255);
//textField ints
int inputStart;
int inputStop;
int inputStep;
//Lables
Label custStartLabel = new Label ("Start : ");
Label custStopLabel = new Label ("Stop : ");
Label custStepLabel = new Label ("Step : ");
//Buttons
Button goButton = new Button("Go");
Button clearButton = new Button("Clear");
//panel for input textFields and lables
Panel textInputPanel = new Panel();
//Panel for buttons
Panel buttonPanel = new Panel();
public Checkerboard()
{//constructor method
//set the 3 input textFields to 0
inputStart = 0;
inputStop = 0;
inputStep = 0;
//set Layouts for frame and three panels
this.setLayout(new BorderLayout());
//grid layout (row,col,horgap,vertgap)
blocksPanel.setLayout(new GridLayout(4,4,10,10));
textInputPanel.setLayout(new GridLayout(2,3,20,10));
buttonPanel.setLayout(new FlowLayout());
//setEditable()
//setText()
//add components to blocks panel
for (int i = 0; i<16; i++)
{
blocksDisplay[i] = new TextArea(null,3,5,3);
if(i<6)
blocksDisplay[i].setText(" " +i);
else
blocksDisplay[i].setText(" " +i);
blocksDisplay[i].setEditable(false);
// blocksDisplay[i].setBackground(Red);
blocksPanel.add(blocksDisplay[i]);
}//end for
//add componets to panels
//add text fields
textInputPanel.add(start);
textInputPanel.add(stop);
textInputPanel.add(step);
//add lables
textInputPanel.add(custStartLabel);
textInputPanel.add(custStopLabel);
textInputPanel.add(custStepLabel);
//add button to panel
buttonPanel.add(goButton);
buttonPanel.add(clearButton);
//ADD ACTION LISTENRS TO BUTTONS (!IMPORTANT)
goButton.addActionListener(this);
clearButton.addActionListener(this);
add(blocksPanel, BorderLayout.NORTH);
add(textInputPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
//overridding the windowcClosing() method will allow the user to clisk the Close button
addWindowListener(
new WindowAdapter()
{
public void windowCloseing(WindowEvent e)
{
System.exit(0);
}
}
);
}//end of constructor method
public void actionPerformed(ActionEvent e)
{
//if & else if to see what button clicked and pull user input
if(e.getSource() == goButton) //if go clicked ...
{
System.out.println("go clicked");
try{
String inputStart = start.getText();
int varStart = Integer.parseInt(inputStart);
if (varStart<=0 || varStart>=15 )throw new NumberFormatException();
System.out.println("start = " + varStart);
// roomDisplay[available].setBackground(lightRed);
String inputStop = stop.getText();
int varStop = Integer.parseInt(inputStop);
if (varStop<=0 || varStart>=15 )throw new NumberFormatException();
System.out.println("stop = " + varStop);
String inputStep = step.getText();
int varStep = Integer.parseInt(inputStep);
if (varStep<=0 || varStep>=15 )throw new NumberFormatException();
System.out.println("step = " + varStep);
for (int i = varStart; i<varStop; varStep++)//ADD WHILE LOOP
{
blocksDisplay[i].setBackground(Red);
blocksDisplay[i].setText(" " +i);
}
}
catch (NumberFormatException ex)
{
JOptionPane.showMessageDialog(null, "You must enter a Start, Stop and Step value greater than 0 and less than 15",
"Error",JOptionPane.ERROR_MESSAGE);
}
}
else if(e.getSource() == clearButton ) //else if clear clicked ...
{
System.out.println("clear clicked");
}
//int available = room.bookRoom(smoking.getState());
//if (available > 0)//Rooms is available
}//end action performed method
public static void main(String[]args)
{
Checkerboard frame = new Checkerboard ();
frame.setBounds(50, 100, 300, 410);//changed size to make text feilds full charater size
frame.setTitle("Checkerboarder Array");
frame.setVisible(true);
}//end of main method
}
The problem is your loop: your loop variable name is i but you change the varStep variable instead of i so basically the loop variable never changes and thus the exit condition will never be true.
I believe you want to step i with varStep, so change your loop to:
for (int i = varStart; i<varStop; i += varStep)
// stuff inside loop
Take a look at this loop.
for (int i = varStart; i<varStop; varStep++)//ADD WHILE LOOP
{
blocksDisplay[i].setBackground(Red);
blocksDisplay[i].setText(" " +i);
}
It ends when i >= varStop, but neither i nor varStop change as a consequence of its execution, so it can never stop. You only increment varStep.
I think you want to increment i by varStep on each iteration instead, i.e. i += varStep
You use varStep++ in your for loop. I think you meant to do i+varStep.
The application freezes because you're never increasing i, resulting in an endless loop.
In short, I would like to accumulate a bunch of JButton's to an array, and create one ActionListener class for the array.
I'm trying to create a calculator, and all the numbered buttons, such as "6", are in a JButton array, because I would like to have it input the set number into a temporary int, and it would be easier to create one method, instead of 10. I also have 40 other buttons, that I would like to apply the same principal to, but in a different array, so it would be much faster and easier to put these into a couple of ActionListener methods where the buttons data is implemented to that method.
this is the code I have:
private JButton num0, num1, num2, num3, num4, num5, num6, num7, num8, num9;
private JButton numArray[] = {num0, num1, num2, num3, num4, num5, num6, num7, num8, num9};
public GUI(){
numArray.AddActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
}
});
}
You can consider the proposal of Newb Monad. However, you can use the same listener for all your buttons, as in the following example.
public static void main(String[] args) {
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
String text = ((JButton) e.getSource()).getText();
JOptionPane.showMessageDialog(null, text);
}
}
};
JPanel panel = new JPanel(new GridLayout(4,3));
JButton[] array = new JButton[10];
for (int i = 0; i < array.length; i++) {
array[i] = new JButton(String.valueOf(i));
array[i].addActionListener(listener);
panel.add(array[i]);
}
JOptionPane.showMessageDialog(null, panel);
}
You have the right idea. However, array objects do not have an addActionListener() method. You must add an action listener to each JButton individually. You can use the same listener for every button, but then you have to figure out which button was clicked inside the actionPerformed() method. IMO, a cleaner solution is to assign a separate listener to each JButton because that way each ActionListener can know which number is pressed without checking the source of the event. For example, you can create a NumberButtonListener class which takes an int as the only argument to its constructor. You can then create the JButtons and the corresponding NumberButtonListeners at the same time in a small loop.
This seems to work well for me.
I essentially loop through all of the buttons while checking it against the action (e.getSource()).
public void actionPerformed(ActionEvent e){
//loop through allbuttons to check if clicked
for(int i = 0; i < buttonArr.length; i++){
for(int j = 0; j < buttonArr[0].length; j++){
if(e.getSource() == buttonArr[i][j]){
//do stuff
}
}
}
}
I had a similar problem with a 2D array of buttons for a game of "Connect Four". I was able to use a for loop inside ActionListener to test which of my buttons had been pushed. The key was modifying the toString() method from my button class to supply the array element as a string:
Within the JPanel class definition:
...
discs = new RoundButton[6][7]; //my 2D array
...
public class RoundButton extends JButton {
...
public String toString() {
return "discs["+i+"]["+j+"]";
}
...
}
private class ButtonListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent event) {
for (int i = 0; i < discs.length; i++){
for (int j= 0; j < discs[i].length; j++){
if (event.getSource() == discs[i][j]){
discs[i][j].setIcon(yellowDisc); //my particular action for that button
}
}
Sorry this is messy. I've never posted on here before.
I am working on a program that needs to determine which JCheckBox was selected. I am using three different button groups, two of which have overlapping text. I need to be able to determine which triggered the event so I can add the appropriate charge (COSTPERROOM vs COSTPERCAR) to the total(costOfHome). What I cant figure out is how to differentiate the checkbox source if the text is the same. I was thinking of trying to change the text on one button group to strings like "one" "two" etc, but that introduces a bigger problem with how I have created the checkboxes in the first place. Any ideas would be appreciated, thanks in advance!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JMyNewHome extends JFrame implements ItemListener {
// class private variables
private int costOfHome = 0;
// class arrays
private String[] homeNamesArray = {"Aspen", "Brittany", "Colonial", "Dartmour"};
private int[] homeCostArray = {100000, 120000, 180000, 250000};
// class constants
private final int MAXROOMS = 3;
private final int MAXCARS = 4;
private final int COSTPERROOM = 10500;
private final int COSTPERCAR = 7775;
JLabel costLabel = new JLabel();
// constructor
public JMyNewHome ()
{
super("My New Home");
setSize(450,150);
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Font labelFont = new Font("Time New Roman", Font.BOLD, 24);
setJLabelString(costLabel, costOfHome);
costLabel.setFont(labelFont);
add(costLabel);
JCheckBox[] homesCheckBoxes = new JCheckBox[homeNamesArray.length];
ButtonGroup homeSelection = new ButtonGroup();
for (int i = 0; i < homeNamesArray.length; i++)
{
homesCheckBoxes[i] = new JCheckBox(homeNamesArray[i], false);
homeSelection.add(homesCheckBoxes[i]);
homesCheckBoxes[i].addItemListener(this);
add(homesCheckBoxes[i]);
}
JLabel roomLabel = new JLabel("Number of Rooms in Home");
add(roomLabel);
ButtonGroup roomSelection = new ButtonGroup();
JCheckBox[] roomCheckBoxes = new JCheckBox[MAXROOMS];
for (int i = 0; i < MAXROOMS; i++)
{
String intToString = Integer.toString(i + 2);
roomCheckBoxes[i] = new JCheckBox(intToString);
roomSelection.add(roomCheckBoxes[i]);
roomCheckBoxes[i].addItemListener(this);
add(roomCheckBoxes[i]);
}
JLabel carLabel = new JLabel("Size of Garage (number of cars)");
add(carLabel);
ButtonGroup carSelection = new ButtonGroup();
JCheckBox[] carCheckBoxes = new JCheckBox[MAXCARS];
for (int i = 0; i < MAXCARS; i++)
{
String intToString = Integer.toString(i);
carCheckBoxes[i] = new JCheckBox(intToString);
carSelection.add(carCheckBoxes[i]);
carCheckBoxes[i].addItemListener(this);
add(carCheckBoxes[i]);
}
setVisible(true);
}
private void setJLabelString(JLabel label, int cost)
{
String costOfHomeString = Integer.toString(cost);
label.setText("Cost of Configured Home: $ " + costOfHomeString + ".00");
invalidate();
validate();
repaint();
}
public void itemStateChanged(ItemEvent e) {
JCheckBox source = (JCheckBox) e.getItem();
String sourceText = source.getText();
//JLabel testLabel = new JLabel(sourceText);
//add(testLabel);
//invalidate();
//validate();
//repaint();
for (int i = 0; i < homeNamesArray.length; i++)
{
if (sourceText == homeNamesArray[i])
{
setJLabelString(costLabel, costOfHome + homeCostArray[i]);
}
}
}
}
I would
Use JRadioButtons for this rather than JCheckBoxes since I think it is GUI standard to have a set of JRadioButtons that only allow one selection rather than a set of JCheckBoxes.
Although you may have "overlapping text" you can set the button's actionCommand to anything you want to. So one set of buttons could have actionCommands that are "room count 2", "room count 3", ...
But even better, the ButtonGroup can tell you which toggle button (either check box or radio button) has been selected since if you call getSelection() on it, it will get you the ButtonModel of the selected button (or null if none have been selected), and then you can get the actionCommand from the model via its getActionCommand() method. Just first check that the model selected isn't null.
Learn to use the layout managers as they can make your job much easier.
For instance, if you had two ButtonGroups:
ButtonGroup fooBtnGroup = new ButtonGroup();
ButtonGroup barBtnGroup = new ButtonGroup();
If you add a bunch of JRadioButtons to these ButtonGroups, you can then check which buttons were selected for which group like so (the following code is in a JButton's ActionListener):
ButtonModel fooModel = fooBtnGroup.getSelection();
String fooSelection = fooModel == null ? "No foo selected" : fooModel.getActionCommand();
ButtonModel barModel = barBtnGroup.getSelection();
String barSelection = barModel == null ? "No bar selected" : barModel.getActionCommand();
System.out.println("Foo selected: " + fooSelection);
System.out.println("Bar selected: " + barSelection);
Assuming of course that you've set the actionCommand for your buttons.
Checkboxes have item listeners like any other swing component. I would decouple them, and simply add listeners to each
{
checkBox.addActionListener(actionListener);
}
http://www.java2s.com/Code/Java/Swing-JFC/CheckBoxItemListener.htm