Sanchit Batra Sanchit Batra - 22 days ago 7
Java Question

Changing border color of the selected jbutton without naming the button

So this application fires up a JFrame that has 25 buttons arranged in a 5 by 5 grid. It is supposed to be a game like candy crush, where you win if you manage to get three similarly colored buttons in a row or column. When I select a button, the border color changes to blue. Is there a way I can change the border color to red? I don't know how to change the border of a button that is currently selected without using names for each button, and I've been asked not to do that. The buttons have been created using a for loop so they don't have names. Also, the code is from a previous project and is being adapted for this one, so there may be some pieces that aren't necessary for this one or may have to be changed. Ignore all that, for now I just want to figure out how to change the border color of the selected button.

This is the class that handles the setting up of the initial state of the game.

package code.model;

import java.util.ArrayList;
import java.util.Random;

import code.ui.UI;

public class Model {

private UI _observer; // initialized by setObserver method
private Random _rand; // for randomization
private ArrayList<String> _imageFileNames; // the names of the image files
private ArrayList<String> _spinnerCurrentValues; // the image files to display in the UI

public Model() {
_rand = new Random();

_imageFileNames = new ArrayList<String>();
_imageFileNames.add("Tile-0.png");
_imageFileNames.add("Tile-1.png");
_imageFileNames.add("Tile-2.png");
_imageFileNames.add("Tile-3.png");
_imageFileNames.add("Tile-4.png");
_imageFileNames.add("Tile-5.png");

_spinnerCurrentValues = new ArrayList<String>();
for(int i=0; i<25; i=i+1) {
_spinnerCurrentValues.add(i,null);
}
System.out.println(_spinnerCurrentValues);

spin(); // randomly select which images to display
}

public void spin() {
for(int i=0; i<25; i=i+1) {
_spinnerCurrentValues.set(i, _imageFileNames.get(_rand.nextInt(_imageFileNames.size())));
}
stateChanged(); // tell the UI that the model's state has changed
}

public boolean jackpot() {
for (int i=1; i<_spinnerCurrentValues.size(); i=i+1) {
if ( ! _spinnerCurrentValues.get(i-1).equals(_spinnerCurrentValues.get(i)) ) {
return false;
}
}
return true; // all three spinners are displaying the same image (based on image file name)
}

public void addObserver(UI ui) {
_observer = ui;
}

public void stateChanged() {
if (_observer != null) {
_observer.setIcon(); // tell the UI to update
}
}

public String getImageFileName(int i) {
return _spinnerCurrentValues.get(i);
}


}




This class sets up the user interface.

package code.ui;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import code.model.Model;

public class UI implements Runnable {

private JFrame _frame;
private Model _model;
private JButton _currentButton;

private ArrayList<JButton> _buttons;
private JButton _spin;

@Override public void run() {
_frame = new JFrame("Sanchit Batra's Lab 8");
_frame.getContentPane().setLayout(new GridLayout(5, 5, 10, 10));

_buttons = new ArrayList<JButton>();
for (int i=0; i<25; i++) {
JButton button = new JButton();
ActionListener x = new EventHandler(_model);
button.addActionListener(x);
_buttons.add(button);
_frame.getContentPane().add(button);
}

_model = new Model(); // create the model for this UI
_model.addObserver(this);


// standard JFrame method calls
_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
_frame.pack();
_frame.setVisible(true);
_model.spin();
}

public void setIcon() {
// update the icon on each label
for (int i=0; i<25; i=i+1) {
_buttons.get(i).setIcon(new ImageIcon("Images/"+_model.getImageFileName(i)));
}

// make sure JFrame is appropriately sized (needed when _spin text changes)
_frame.pack();
}

public JButton getCurrentButton(){
return _currentButton;
}


}

This class handles the event.

package code.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import code.model.Model;

public class EventHandler implements ActionListener {

private Model _model;

public EventHandler(Model m) {
_model = m;
}

@Override public void actionPerformed(ActionEvent e) {



}


}

And this class has the main method.

package code;

public class Driver {

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new code.ui.UI());
}


}

Answer

When I select a button, the border color changes to blue.

You can't select a button. I think you mean when the mouse hovers over the button.

Is there a way I can change the border color to red? I don't know how to change the border of a button that is currently selected without using names for each button,

So to listen for the mouse entering and exiting a component you need to use a MouseListener and implement the mouseEntered(...) and mouseExited() methods.

Then in the listener code you can use:

JButton button = (JButton)event.getSource();
button.setBorder(...);

When you use this approach you can create a single MouseListener that is shared by all buttons.