2-мерный массив и JApplet: видимость кнопки и изменение метки

У меня есть 2 несколько простых проблемы:

1) Я пытаюсь установить btns[0][0] (строка 0, столбец 0) единственной видимой кнопкой в ​​моей сетке кнопок 00-99, и после того, как я нажимаю кнопку, те, которые касаются ее, становятся видимыми, и процесс продолжается до тех пор, пока все кнопки не будут видимый.

2) После нажатия каждой кнопки кнопка (именно нажатая, а не каждая кнопка) меняет свою цифровую метку на смайлик, setLabel(":)").

public class Project5 extends JApplet implements ActionListener {

    JButton button;
    Container contentPane;
    JButton[][] btns = new JButton[10][10];
    int clicks = 0;

    public void init() {

        setSize(600, 600);
        contentPane = getContentPane();
        contentPane.setBackground(Color.WHITE); 


        GridLayout grid = new GridLayout(10,10,0,4);
        contentPane.setLayout(grid);
        clicks = 0;

        for (int i = 0; i < 10; i++) {

            for (int j = 0; j < 10; j++) {

                btns[i][j] = new JButton();                
                button = new JButton(""+i+j);
                button.addActionListener(this);
                contentPane.add(button);
                //button.setVisible(false);
            }
        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Container contentPane = getContentPane();

        btns[0][0].setVisible(true);

        String button_label = e.getActionCommand();

        int row = Character.getNumericValue(button_label.charAt(0));
        int column = Character.getNumericValue(button_label.charAt(1));          


        clicks++;

        if (clicks % 5 == 0) {
            contentPane.setBackground(Color.PINK);
        } else if (clicks % 5 == 1) {
            contentPane.setBackground(Color.GREEN);
        } else if (clicks % 5 == 2) {
            contentPane.setBackground(Color.BLUE);
        } else if (clicks % 5 == 3) {
            contentPane.setBackground(Color.YELLOW);
        } else if (clicks % 5 == 4) {
            contentPane.setBackground(Color.RED);          
        }

    }

    public void checkDone() {
        //if all buttons visible, change contentPane color to black.

    }

}

person user3597420    schedule 03.05.2014    source источник


Ответы (2)


Ваша проблема с видимостью кнопок связана с тем, что вы создаете две кнопки в своем цикле.
Вы помещаете одну из них в свой массив и выполняете всю свою работу над другой.

Вместо этого

btns[i][j] = new JButton();                
button = new JButton(""+i+j);

ты хочешь сделать это

button = new JButton(""+i+j);  
btns[i][j] = button; 

Что касается вашего метода actionPerformed(), всякий раз, когда нажимается кнопка, он создает ActionEvent и «запускает» его для своих слушателей. Это означает, что он пройдет через всех этих прослушивателей и вызовет actionPerformed() для каждого из них. Всякий раз, когда вызывается слушатель, событие, которое передается ему, имеет внутри себя специальный Object, называемый источник (т. е. независимо от того, что вызвало событие).

В вашем случае источником будет кнопка, на которую нажали, и вы можете получить кнопку, на которую нажали, и получить текст ее метки следующим образом:

    JButton button = (JButton) e.getSource();
    String label = button.getText();
    button.setText(":)");

Затем все, что вам нужно сделать, это проанализировать label, чтобы получить координаты нажатой кнопки.
Получив координаты, вы можете вычислить соседей и сделать их видимыми.

person azurefrog    schedule 03.05.2014

Это работает:

public class Project5 extends JApplet implements ActionListener {

    Container contentPane = getContentPane();
    JButton[][] btns = new JButton[10][10];
    int clicks = 0;
    static Map<Integer, Color> colors = new HashMap<>();

    public void init() {

        colors.put(0, Color.PINK);
        colors.put(1, Color.GREEN);
        colors.put(2, Color.BLUE);
        colors.put(3, Color.YELLOW);
        colors.put(4, Color.RED);

        setSize(600, 600);
        contentPane.setBackground(Color.WHITE);
        contentPane.setLayout(new GridLayout(10, 10, 0, 4));

        for (int i = 0; i<10; i++) {
            for (int j = 0; j<10; j++) {
                JButton button = new JButton(""+i+j);
                button.addActionListener(this);
                button.setVisible(false);
                btns[i][j] = button;
                contentPane.add(button);
            }
        }
        btns[0][0].setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        JButton source = (JButton) e.getSource();
        String text = source.getText();
        if (text.equals(":)"))
            return;
        int row = Integer.valueOf(text.substring(0, 1));
        int col = Integer.valueOf(text.substring(1, 2));    
        try {
            btns[row][col+1].setVisible(true);
            btns[row+1][col].setVisible(true);
            btns[row][col-1].setVisible(true);
            btns[row-1][col].setVisible(true);
        } catch (ArrayIndexOutOfBoundsException e2) {}
        source.setText(":)");

        contentPane.setBackground(colors.get(clicks++%5));
    }

    public void checkDone() {

        // if all buttons visible, change contentPane color to black.
    }
}

Заметки:

  • Я помещаю ваши цвета в Map, чтобы потом было легче управлять.
  • Я изменил некоторые определения полей.
  • Я предположил, что если пользователь нажимает уже нажатую кнопку, ничего не происходит.
  • Я выбрал опрометчивый ярлык с блоком try-catch, чтобы игнорировать исключения ArrayOutOfBounds для кнопок по краям. Вместо этого рассмотрите возможность реальной проверки их положения и настройки видимости только правильных кнопок.
  • Я определил расположение кнопки источника по ее метке. Хотя хорошо, если все кнопки имеют 2 цифры строки-столбца, безопаснее перебрать массив и найти кнопку с btns[i][j].equals(source) и прочитать позицию таким образом.
person user1803551    schedule 03.05.2014
comment
@user3597420 user3597420 Если этот ответ решил вашу проблему, подумайте о том, чтобы принять его или проголосовать за него, если он был полезен. - person user1803551; 12.05.2014