![](/img/trans.png)
[英]Which Jbutton is being clicked, when it is an array of JButtons with the same actionlistener
[英]Checking which Jbutton (of multiple Jbuttons) was clicked
我正在制作一個棋盤游戲,一個框架中有 64 個JButton
的 8X8 矩陣。 到目前為止,我的代碼是這樣的:
public class Main {
static JFrame f = new JFrame();;
static JButton btn;
static JButton btnTemp;
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout((new GridLayout(8,8)));//size of the board
f.setTitle("ex");
f.setSize(800,800);
for (int i=0;i<=7;i++)
{
for (int j = 0; j<=7;j++)
{
btn=new JButton();
btn = new JButton(new SoliderW());
btn.setName("btn"+i+""+j);
btn.setBackground(Color.BLACK);
btn.addActionListener(actionListener); // make a listener to the button
f.add(btn);
}
}
f.setVisible(true);
我正在嘗試使用以下代碼判斷點擊了哪個 JButoon:
Component[] components = f.getContentPane().getComponents();
ActionListener actionListener = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("Hello");
}
};
for (Component component : components)
{
if (component instanceof JButton)
{
((JButton) component).addActionListener(actionListener);
}
}
然而,我不明白如何判斷哪個 Jbutton 被點擊。
讓我們從static
不是您的朋友開始,您應該避免使用它,尤其是當您嘗試跨對象邊界引用實例時。
使用匿名類,例如...
btn = new JButton();
btn = new JButton(new SoliderW());
btn.setName("btn" + i + "" + j);
btn.setBackground(Color.BLACK);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
// Do some work
}
}); // make a listener to the button
但是,老實說,因為btn
是static
,這不會幫助你
使用actionCommand
屬性
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
String command = evt.getActionCommand();
// Do more work
}
};
//...
for (int i = 0; i <= 7; i++) {
for (int j = 0; j <= 7; j++) {
btn = new JButton();
btn = new JButton(new SoliderW());
btn.setName("btn" + i + "" + j);
btn.setBackground(Color.BLACK);
// Replace the text with something that will
// uniquely identify this button
btn.setActionCommand("some cell identifier");
btn.addActionListener(actionListener); // make a listener to the button
f.add(btn);
}
}
創建一個自定義ActionListener
,它獲取所需的信息,以便它可以更好地決定要做什么(並將其與按鈕本身分離)
public class CardActionListener implements ActionListener {
private int row, col;
public CardActionListener(int row, int col) {
this.row = row;
this.col = col;
}
@Override
public void actionPerformed(ActionEvent arg0) {
// Do some work...
}
}
//...
for (int i = 0; i <= 7; i++) {
for (int j = 0; j <= 7; j++) {
btn = new JButton();
btn = new JButton(new SoliderW());
btn.setName("btn" + i + "" + j);
btn.setBackground(Color.BLACK);
btn.addActionListener(new CardActionListener(i, j)); // make a listener to the button
f.add(btn);
}
}
我個人的喜好是否會使用Action
API 。
這類似於最后一個建議,但創建了一個更加獨立的工作單元,它與調用程序分離。
public class CardAction extends AbstractAction {
private int row, col;
public CardAction(int row, int col) {
this.row = row;
this.col = col;
putValue(Action.LARGE_ICON_KEY, new SoliderW());
}
@Override
public void actionPerformed(ActionEvent evt) {
// Do some work...
}
}
//...
for (int i = 0; i <= 7; i++) {
for (int j = 0; j <= 7; j++) {
btn = new JButton(new CardAction(i, j));
f.add(btn);
}
}
我正在嘗試的一件事是將操作功能與按鈕本身分離,因此操作不依賴於按鈕,而是提供了執行操作所需的信息。
這是“模型-視圖-控制器”的核心概念,將使您的代碼更易於維護
您也可以在偵聽器中執行此操作:
Object src = e.getSource();
if ( src instanceof JButton ) {
System.out.println( "Button is: " + ((JButton)src).getName() );
}
但是最好將所有按鈕放在一個 ArrayList 中,然后只使用int index = list.indexOf(src);
可以按照MadProgrammer 的建議實現MVC 模式,如下所示:
有一個Model
類,其中包含視圖 (gui) 需要的所有信息。
有一個使用模型來顯示 gui 的View
類。
有一個Controller
模型和視圖的Controller
類。
下面的mre演示了使用 MVC 模式來實現所需的功能。
為了方便和簡單,可以將以下代碼復制粘貼到一個名為Main.java
文件中並運行:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Controller();
}
}
//used listen to changes in view
interface SelectionListener{
void selected(int row, int column);
}
/*Model contains the information for the view and information from the view
* as well as the logic.
* The model is independent of the user interface.
*/
class Model {
private final String[][] soliderNames;
Model(int size){
soliderNames = new String[size][size];
for (int i=0 ; i<size ; i++) {
for (int j=0; j<size ; j++) {
soliderNames[i][j] = i+"-"+j;
}
}
}
int getNunberOfRows(){
return soliderNames.length;
}
int getNunberOfColumns(){
return soliderNames[0].length;
}
String getName(int row, int column) {
return soliderNames[row][column];
}
}
/*View only contains the user interface part*/
class View{
private final JFrame f;
private static final int W = 50, H = 50;
View(Model model, SelectionListener selectionListener){
int rows = model.getNunberOfRows();
int cols = model.getNunberOfColumns();
JPanel view = new JPanel(new GridLayout(rows, cols));
for (int i=0 ; i < rows ; i++) {
for (int j = 0 ; j < cols ; j++) {
int finalI =i, finalJ = j;
JButton btn = new JButton();
btn = new JButton("-");
btn.setPreferredSize(new Dimension(W,H));
btn.setBackground(Color.BLACK);
btn.addActionListener( a -> selectionListener.selected(finalI, finalJ));
view.add(btn);
}
}
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("ex");
f.add(view);
f.pack();
}
void show(){
f.setVisible(true);
}
}
/* The controller controls the view and model.
* Based on the user action, the Controller calls methods in the View and Model
* to accomplish the requested action.
*/
class Controller implements SelectionListener {
private static final int SIZE = 8;
private final Model model;
Controller(){
model = new Model(SIZE);
View view = new View(model, this);
view.show();
}
@Override
public void selected(int row, int column) {
System.out.print("row: "+ row + " column: "+ column + " clicked. ");
System.out.println("Name is "+ model.getName(row, column));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.