【问题标题】:Checking which Jbutton (of multiple Jbuttons) was clicked检查哪个Jbutton(多个Jbuttons)被点击
【发布时间】:2020-04-12 09:56:10
【问题描述】:

我正在制作一个棋盘游戏,8X8 矩阵,在一个框架中有 64 个JButtons。 到目前为止,我的代码是这样的:

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。

【问题讨论】:

标签: java swing user-interface jframe jbutton


【解决方案1】:

让我们开始吧static 不是您的朋友,您应该避免使用它,尤其是当您尝试跨对象边界引用实例时。

你可以...

例如使用Anonymous Classes...

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

但是,说实话,因为 btnstatic,这对你没有帮助

你可以...

利用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);
    }

}

什么是重要的...

我正在尝试的一件事是将操作功能与按钮本身分离,因此操作不依赖于按钮,而是提供了执行操作所需的信息。

这是“模型-视图-控制器”的核心概念,将使您的代码更易于维护

【讨论】:

    【解决方案2】:

    你也可以在监听器中这样做:

    Object src = e.getSource();
    if ( src instanceof JButton ) {
       System.out.println( "Button is: " + ((JButton)src).getName() );
    }
    

    但最好将所有按钮放在一个 ArrayList 中,然后使用 int index = list.indexOf(src);

    【讨论】:

      【解决方案3】:

      按照MadProgrammer 的建议实施MVC Pattern 可以如下完成:
      有一个 Model 类,其中包含视图 (gui) 所需的所有信息。
      有一个使用模型显示 gui 的 View 类。
      有一个控制模型和视图的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));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-16
        • 1970-01-01
        • 2012-04-17
        • 2015-07-18
        • 2022-01-05
        • 2016-08-14
        • 1970-01-01
        相关资源
        最近更新 更多