'How to assign differents MouseListener to differents JTextField?
im trying to make a Sudoku game and I want to change the background color of the same box, same column and same row when I click on a JTextField. I'm trying to add multiple Mouse Listener, one for each JTextField but It doesnt work. I'm now testing changing the background color of just the JTextField that I click on.
The main problem is in here.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Panel extends JPanel {
public static final int ROWS = 3;
public static final int COLUMNS = 3;
public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];
for (int i = 0; i < ROWS*COLUMNS; i++) {
for (int j = 0; j < ROWS*COLUMNS; j++) {
fields[i][j] = new JTextField();
int finalI = i;
int finalJ = j;
fields[i][j].addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
fields[finalI][finalJ].setBackground(Color.BLUE);
}
});
}
}
}
I have also try with this but it doesn't work.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Panel extends JPanel {
public static final int ROWS = 3;
public static final int COLUMNS = 3;
public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];
for (int i = 0; i < ROWS*COLUMNS; i++) {
for (int j = 0; j < ROWS*COLUMNS; j++) {
fields[i][j] = new JTextField();
addMouseActions(i, j);
}
}
private void addMouseActions(int row, int col){
fields[row][col].addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
fields[row][col].setBackground(Color.BLUE);
}
});
}
}
Here it's the full code that I have for the Panel class.
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Panel extends JPanel {
static String[] levels = {"Easy", "Medium", "Hard"};
public static final JComboBox<String> levelsBox = new JComboBox<>(levels);
private final JButton playButton = new JButton("Play");
private final JButton checkButton = new JButton("Check");
private final JButton hintButton = new JButton("Hint");
private final JButton solveButton = new JButton("Solve");
private final JButton exitButton = new JButton("Exit");
public static final int ROWS = 3;
public static final int COLUMNS = 3;
public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];
public Panel(JFrame frame) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(600, 200);
frame.setLayout(new BorderLayout());
frame.add(new SudokuBoard());
frame.add(new MenuPane(), BorderLayout.AFTER_LINE_ENDS);
frame.pack();
frame.setVisible(true);
}
});
}
public class MenuPane extends JPanel {
public MenuPane() {
setBorder(new EmptyBorder(4, 4, 4, 4));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
JLabel diff = new JLabel("Select the difficulty: ");
diff.setFont(new Font("SansSerif",Font.BOLD,18));
add(diff, gbc);
gbc.gridx++;
levelsBox.setFont(new Font("SansSerif",Font.BOLD,16));
add(levelsBox,gbc);
gbc.gridy++;
playButton.setActionCommand("Play");
add(playButton, gbc);
gbc.gridy++;
checkButton.setActionCommand("Check");
checkButton.setEnabled(false);
add(checkButton, gbc);
gbc.gridy++;
hintButton.setActionCommand("Hint");
hintButton.setEnabled(false);
add(hintButton, gbc);
gbc.gridy++;
solveButton.setActionCommand("Solve");
solveButton.setEnabled(false);
add(solveButton, gbc);
gbc.gridy++;
exitButton.setActionCommand("Exit");
add(exitButton, gbc);
}
}
public static class SudokuBoard extends JPanel {
private SubBoard[] subBoards;
public SudokuBoard() {
setBorder(new EmptyBorder(30, 30, 30, 10));
subBoards = new SubBoard[ROWS * COLUMNS];
setLayout(new GridLayout(ROWS, COLUMNS));
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLUMNS; col++) {
int bigIndex = (row * COLUMNS) + col;
int index = (row * ROWS) + col;
SubBoard board = new SubBoard(bigIndex);
board.setBorder(new LineBorder(Color.GRAY, 3));
subBoards[index] = board;
add(board);
}
}
}
}
public static class SubBoard extends JPanel {
public SubBoard(int bigIndex) {
setLayout(new GridLayout(ROWS, COLUMNS));
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLUMNS; col++) {
int index = (row * COLUMNS) + col;
JTextField field = new JTextField();
field.setPreferredSize(new Dimension(60, 60));
field.setHorizontalAlignment(JTextField.CENTER);
field.setFont(new Font("SansSerif", Font.BOLD, 25));
field.setDocument(new JTextFieldLimit(1));
//field.setEditable(false);
fields[bigIndex][index] = field;
add(field);
}
}
}
}
public void addListeners(Controller controller) {
playButton.addActionListener(controller);
checkButton.addActionListener(controller);
hintButton.addActionListener(controller);
solveButton.addActionListener(controller);
exitButton.addActionListener(controller);
for (int i = 0; i < ROWS*COLUMNS; i++) {
for (int j = 0; j < ROWS*COLUMNS; j++) {
fields[i][j] = new JTextField();
int finalI = i;
int finalJ = j;
fields[i][j].addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
fields[finalI][finalJ].setBackground(Color.BLUE);
}
});
}
}
}
public void enableButtons(boolean enabled){
checkButton.setEnabled(enabled);
hintButton.setEnabled(enabled);
solveButton.setEnabled(enabled);
}
}
And this is the Controller Class that I'm using for Actions Events.
import pkgClient.MyClient;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Objects;
public class Controller implements ActionListener {
Panel panel;
JFrame frame;
public Controller(Panel panel, JFrame frame) {
this.frame = frame;
this.panel = panel;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("Play")){
String level = Panel.levelsBox.getItemAt(Panel.levelsBox.getSelectedIndex());
if(Objects.equals(level, "Easy")){
MyClient.out.println("easyMode");
}else if(Objects.equals(level, "Medium")){
MyClient.out.println("mediumMode");
}else if (Objects.equals(level, "Hard")){
MyClient.out.println("hardMode");
}
panel.enableButtons(true);
Panel.fields[0][0].setBackground(Color.WHITE);
} else if(e.getActionCommand().equalsIgnoreCase("Check")){
System.out.println("Comprobar");
MyClient.out.println("check");
panel.enableButtons(false);
}else if(e.getActionCommand().equalsIgnoreCase("Hint")){
System.out.println("Pista");
MyClient.out.println("hint");
} else if(e.getActionCommand().equalsIgnoreCase("Solve")){
System.out.println("Resolver");
MyClient.out.println("solve");
panel.enableButtons(false);
} else if(e.getActionCommand().equalsIgnoreCase("Exit")) {
frame.dispose();
MyClient.out.println("exit");
}else if(e.getActionCommand().equalsIgnoreCase("Text")) {
System.out.println("hola");
Panel.fields[0][0].setBackground(Color.BLACK);
}else{
System.err.println("Error: unexpected event");
}
}
}
Is there any way to set an unique Mouse Event to every single JTextField like I do with buttons and Actions in the Controller Class? Or how do I have to do it?
Thank you.
Solution 1:[1]
I finally could solve the problem, I just needed to use a FocusListener instead of a MouseListener. I can change the background color of a field int the FocusGained(FocusEvent event) method and each JTextField has an independent event. I can know which JTextField is being clicked with event.getComponent() inside of the FocusGained method.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Medicandy |
