Как выполнить прослушиватель действий JButton определенное количество раз

У меня есть код, в котором у меня есть код с 5 JButtons, и у меня есть отдельный массив, который генерирует случайное число от 1 до 6 (бросок игральных костей), а внутри прослушивателя действий у меня есть только та часть, которая добавляет мою кнопку на мою панель (panel. add(roll1)) и перед прослушивателем действий у меня есть массив, который генерирует случайное число, а затем у меня есть переключатель, говорящий, что если случайное число равно 1, то установите изображение в dice1, если массив равен 2, установите изображение в dice2. Итак, у меня все это работает сейчас, так как я делаю игру yahtzee, мне нужно знать, как сделать так, чтобы она запускалась максимум 3 раза за ход. Прямо сейчас JButton нажимается только один раз, и он выводит другие JButton со случайными изображениями игральных костей, но когда я снова нажимаю кнопку броска, кости не бросаются, они остаются прежними. Как бы вы это сделали?

public static void randomRoll(final JPanel panel) throws Exception
  {

    final ImageIcon icon = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Dice-1.png/45px-Dice-1.png"));
    final ImageIcon icon1 = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Dice-2.png/45px-Dice-2.png"));
    final ImageIcon icon2 = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Dice-3.png/45px-Dice-3.png"));
    final ImageIcon icon3 = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Dice-4.png/45px-Dice-4.png"));
    final ImageIcon icon4 = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Dice-5.png/45px-Dice-5.png"));
    final ImageIcon icon5 = new ImageIcon(new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Dice-6.png/45px-Dice-6.png"));

    final ImageIcon [] diceIcons = {icon, icon1, icon2, icon3, icon4, icon5};

    int array [] = new int [5];


    for(int i = 0; i < 5; i++)
    {
      array [i]= (int) (Math.random () * 6) + 1;
      System.out.println(array[i]);
    }

    final JButton roll1 = new JButton(diceIcons[array[0]-1]);
    final JButton roll2 = new JButton(diceIcons[array[1]-1]);
    final JButton roll3 = new JButton(diceIcons[array[2]-1]);
    final JButton roll4 = new JButton(diceIcons[array[3]-1]);
    final JButton roll5 = new JButton(diceIcons[array[4]-1]);
    final JButton dice = new JButton ("Roll Dice");

    dice.setBounds(40, 40, 100, 30);
    panel.add(dice);
    panel.setLayout(null);

    dice.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        roll1.setBounds(40, 100, 70, 70);
        roll2.setBounds(40, 180, 70, 70);
        roll3.setBounds(40, 260, 70, 70);
        roll4.setBounds(40, 340, 70, 70);
        roll5.setBounds(40, 420, 70, 70);

        //Adding to JFrame
        panel.add(roll1);
        panel.add(roll2);
        panel.add(roll3);
        panel.add(roll4);
        panel.add(roll5);
        panel.doLayout();
        panel.repaint();
        panel.revalidate();
     }
    });


  }

Обновлять

dice.addActionListener(new ActionListener()
{
  public void actionPerformed(ActionEvent e)
  {
    int array [] = new int [5];

    for(int i = 0; i < 5; i++)
    {
      array [i]= (int) (Math.random () * 6) + 1;
      System.out.println(array[i]);
    }
final JButton roll1 = new JButton(diceIcons[array[0]-1]);
final JButton roll2 = new JButton(diceIcons[array[1]-1]);
final JButton roll3 = new JButton(diceIcons[array[2]-1]);
final JButton roll4 = new JButton(diceIcons[array[3]-1]);
final JButton roll5 = new JButton(diceIcons[array[4]-1]);


    roll1.setBounds(40, 100, 70, 70);
    roll2.setBounds(40, 180, 70, 70);
    roll3.setBounds(40, 260, 70, 70);
    roll4.setBounds(40, 340, 70, 70);
    roll5.setBounds(40, 420, 70, 70);

    //Adding to JFrame
    panel.add(roll1);
    panel.add(roll2);
    panel.add(roll3);
    panel.add(roll4);
    panel.add(roll5);
    panel.doLayout();
    panel.repaint();
    panel.revalidate();
 }
});

person Lebron    schedule 16.01.2015    source источник
comment
Не могли бы вы показать нам код, демонстрирующий проблему   -  person Rika    schedule 17.01.2015
comment
Не могли бы вы помочь сейчас? Я просто хочу, чтобы JButton можно было щелкнуть максимум 3 раза, и сделать то же самое, чтобы он сгенерировал еще 5 случайных кубиков.   -  person Lebron    schedule 17.01.2015


Ответы (2)


Вы можете установить для каждой JButton actionCommand, используя setActionCommand("add" + "1");//скажем, что «1» — это ваше значение «i» из цикла for

Затем в реализованном методе из ActionListiner:

@Override
public void actionPerformed(ActionEvent e) {

    String cmd = e.getActionCommand();

    if (cmd.equals("add1")){
        System.out.println("from add1");
    }


}
person roeygol    schedule 16.01.2015

Ваш код рандомизации,

int array [] = new int [5];


for(int i = 0; i < 5; i++)
{
  array [i]= (int) (Math.random () * 6) + 1;
  System.out.println(array[i]);
}

вызывается в вашем методе randomRoll(...), но не вызывается в ActionListener JButton. Если вы хотите, чтобы нажатие кнопки выполняло рандомизацию, тогда код рандомизации должен находиться внутри прослушивателя, который срабатывает при нажатии кнопки.

Другие вопросы, не связанные с вашей проблемой:

  • Избегайте пустых макетов и setBounds(...), так как это вызовет бесконечное разочарование из-за плохо выглядящего графического интерфейса, который сложно отлаживать или улучшать. Вместо этого используйте макеты, здесь GridLayout отлично подойдет для хранения изображений игральных костей.
  • Возможно, вам будет лучше отображать свои кубики в JLabels, а не в JButtons, если только вам не нужно делать их «нажимаемыми».
  • Вы захотите прочитать изображения в свои ImageIcons один раз при запуске программы и сохранить значения в поле.
  • Ваш метод randomRoll(...) является статическим, что говорит о том, что ваша программа, возможно, чрезмерно использует статический модификатор.

Обратите внимание, чтобы ограничить количество нажатий кнопок до 3, поместите счетчик внутри ActionListener вашей кнопки, а затем либо отключите кнопку, когда количество достигнет 3, либо выйдите из прослушивателя действий, когда количество больше 3. Например, в мой код, у меня есть что-то вроде:

private class ButtonAction extends AbstractAction {
  private Random random = new Random();
  private int buttonPressCount = 0;

  public ButtonAction(String name) {
     super(name);
     int mnemonic = (int) name.charAt(0);
     putValue(MNEMONIC_KEY, mnemonic);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
     // check if number of presses exceeds max
     if (buttonPressCount >= BUTTON_PRESS_TOTAL_COUNT) {
        return; // we've exceeded our max
     }
     for (JLabel jLabel : dieLabels) {
        int index = random.nextInt(dieImageList.size());
        jLabel.setIcon(dieImageList.get(index));
     }

     buttonPressCount++;

     // or do this -- disable the button
     if (buttonPressCount >= BUTTON_PRESS_TOTAL_COUNT) {
        setEnabled(false);
     }
  }
}

Пример, в котором используются JLabels и менеджеры компоновки:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class DiceRoller extends JPanel {
   private static final String BASE_PATH = "http://upload.wikimedia.org/wikipedia/commons/thumb/";
   private static final String[] DICE_PATH = {
      "c/c5/Dice-1.png/45px-Dice-1.png",
      "1/18/Dice-2.png/45px-Dice-2.png",
      "7/70/Dice-3.png/45px-Dice-3.png",
      "a/a9/Dice-4.png/45px-Dice-4.png",
      "6/6c/Dice-5.png/45px-Dice-5.png",
      "5/5c/Dice-6.png/45px-Dice-6.png"
 };
   private static final int BUTTON_PRESS_TOTAL_COUNT = 3;
   private static final int BUTTON_COUNT = 5;

   private List<Icon> dieImageList = new ArrayList<>();
   private Icon emptyIcon;
   private JLabel[] dieLabels = new JLabel[BUTTON_COUNT];

   public DiceRoller() throws IOException {
      for (String dicePath : DICE_PATH) {
         String path = BASE_PATH + dicePath;
         URL url = new URL(path);
         BufferedImage img = ImageIO.read(url);
         dieImageList.add(new ImageIcon(img));
      }

      int biWidth = dieImageList.get(0).getIconWidth();
      int biHeight = dieImageList.get(0).getIconHeight();
      BufferedImage emptyImage = new BufferedImage(biWidth, biHeight,
            BufferedImage.TYPE_INT_ARGB);
      emptyIcon = new ImageIcon(emptyImage);

      int gap = 8;
      JPanel btnPanel = new JPanel(new GridLayout(0, 1, 0, gap));
      btnPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
      for (int i = 0; i < dieLabels.length; i++) {
         dieLabels[i] = new JLabel(emptyIcon);
         btnPanel.add(dieLabels[i]);
      }

      JPanel topPanel = new JPanel();
      topPanel.add(new JButton(new ButtonAction("Roll")));

      setLayout(new BorderLayout());
      add(topPanel, BorderLayout.PAGE_START);
      add(btnPanel, BorderLayout.CENTER);
   }

   private class ButtonAction extends AbstractAction {
      private Random random = new Random();
      private int buttonPressCount = 0;

      public ButtonAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         if (buttonPressCount >= BUTTON_PRESS_TOTAL_COUNT) {
            return; // we've exceeded our max
         }
         for (JLabel jLabel : dieLabels) {
            int index = random.nextInt(dieImageList.size());
            jLabel.setIcon(dieImageList.get(index));
         }

         buttonPressCount++;

         if (buttonPressCount >= BUTTON_PRESS_TOTAL_COUNT) {
            setEnabled(false);
         }
      }
   }

   private static void createAndShowGui() {
      DiceRoller roller = null;
      try {
         roller = new DiceRoller();
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
      JFrame frame = new JFrame("Roll");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(roller);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
person Hovercraft Full Of Eels    schedule 16.01.2015
comment
Но это работает один раз с этим текущим кодом. Вы хотите сказать, что мне придется это сделать, если я захочу выполнить рандомизацию более одного раза? - person Lebron; 17.01.2015
comment
@Lebron: он работает один раз, потому что он вызывается только один раз, когда вызывается этот метод, и это не имеет смысла для ваших целей. Вы хотите, чтобы рандомизация происходила при каждом нажатии кнопки, поэтому рандомизация должна войти в код слушателя. - person Hovercraft Full Of Eels; 17.01.2015
comment
Я сделал то, что вы сказали, он выполняет код рандомизации, но не помещает его в jbutton, у меня есть system.out.println с массивом, и он будет показывать числа при каждом нажатии, но jbuttons не меняется. Я добавлю обновление - person Lebron; 17.01.2015
comment
@Lebron: вам нужно добавить кнопки до того, как вы начнете прокручивать, и добавлять каждую кнопку только один раз, а не с каждым прокруткой. В прокрутке ActionListener все, что вам нужно сделать, это установить значки кнопок, которые уже есть на месте, и опять же, избегайте пустых макетов. Кроме того, при публикации кода старайтесь размещать короткий код, который компилируется и запускается для нас. Например, посмотрите мой пример кода выше. Он использует JLabels, но JButtons будет работать так же. - person Hovercraft Full Of Eels; 17.01.2015