Отключить один JButton, когда включен другой JBUtton - PullRequest
0 голосов
/ 25 мая 2018

Я пытаюсь построить простую игру в кости для своего задания.Там будет 2 игрока.В моем коде я пытаюсь использовать метод getSource(), чтобы при включении игрока roll JButton кнопка другого игрока была отключена, но когда я запускаю игру, кнопки обоих игроков по-прежнему включены.Вот мой код:

Die.java

import java.util.*;
public class Die
{
    private final int MAX = 6;
    private int die1;
    Random rand = new Random();

    //Constructor
    public Die()
    {
        die1 = 1;
    }// end Constructor

    public int Roll()
    {
        die1 = rand.nextInt(MAX)+1;
        return die1;
    }
}

DisplaySixNumbersPanel.java

import java.awt.*;
import javax.swing.*;
public class DisplaySixNumbersPanel
{
    public static void main(String[ ] args) 
    {
        JFrame w1 = new JFrame("Six Numbers Game");
        w1.setLayout(new GridLayout(1,2));
        SixNumbersPanel2 player1 =new SixNumbersPanel2();
        SixNumbersPanel2 player2 =new SixNumbersPanel2();
        w1.add(player1);
        w1.add(player2);
        w1.setSize(540, 350);
        w1.setVisible(true);
        w1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    } //end main
} //end class

SixNumbersPanel2.java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class SixNumbersPanel2 extends JPanel implements ActionListener
{
    private JTextField text1;
    private boolean flag = false;
    private boolean checkflag[] = {false,false,false,false,false,false,false};
    private JLabel label;
    private JLabel label1;
    public JButton roll;
    private JButton restartButton;
    private JTextArea display;
    private JTextField[] fields = new JTextField[7];
    private Die dice = new Die();
    private int key;
    private int count;
    private int count1;
    private Player player1 = new Player();
    private Player player2 = new Player();
    private int check;
    private int[] list = new int [7];
    //private SixNumbersPanel2 player2panel;
    public SixNumbersPanel2()
    {
        label= new JLabel ("A number between 1 to 6 wil appear");
        label1 = new JLabel("once in each of the following textfields");
        roll = new JButton("Roll dice");
        restartButton = new JButton("Restart Game");
        text1 = new JTextField(3);
        display = new JTextArea(10,15);
        add(label);
        add(label1);
        for(int i=1;i<7;i++)
        {
            fields[i] = new JTextField(3);
            add(fields[i]);
        }
        add(roll);
        add(text1);
        add(display);
        display.setEditable(false);      
        restartButton.setVisible(false);
        add(restartButton);
        restartButton.addActionListener(this);
        roll.addActionListener(this);        
    }
    public void restart()
    {
       display.setText("");
       text1.setText("");
       for(int i=1; i<7; i++)
       {
           fields[i].setText("");
       }
       count=0;
       count1=0;
       Arrays.fill(checkflag,false);
       Arrays.fill(list,0);
       flag = false;
       restartButton.setVisible(false);
       rollenable(); 

    }


    public void actionPerformed(ActionEvent event)
    {
        if(event.getSource() == roll)
        {
            player2.rolldisable();
        }

        key=dice.Roll();
        count++;
        String toScreen= "Number of rolls: "+count;
        display.setText(toScreen);
        text1.setText(""+key);
        check = player1.Check(list,key);
        if(check < 0)
        {
            count1++;
            for(int i=1;i<7;i++)
            {
                if(key == i)
                {
                    list[i] = key;
                    checkflag[i]=true;
                    fields[i].setText(""+key);
                    if(checkflag[i] == true)
                    {
                        flag = true;
                        for(int a=1; a<7; a++)
                        {
                            if(checkflag[a]==false)
                            {
                                flag=false;
                            }
                        }
                    }
                }
                if(flag == true)
                {
                    display.setText("Congratulation, you have \ntaken "+count+" rolls to get one of \neach number between 1 and 6");
                    rolldisable();
                    restartButton.setVisible(true);                   
                }
            }
        }
        if(event.getSource() == restartButton)
        {
            restart();
        }
    }
    public void rollenable()
    {
        roll.setEnabled(true);
    }
    public void rolldisable()
    {
        roll.setEnabled(false);
    }
    public JButton getSubButton()
    {
        return this.roll;
    }
}

Player.java

import java.util.*;
import javax.swing.*;
public class Player
{

    private final int MAX = 100;
    private Die play = new Die();
    private boolean[] results = {false,false,false,false,false,false,false};
    private int count;
    private int key;
    private boolean check = false;
    //private JButton roll;
    public Player()
    {
        count=0;
        key=0;
    }
    public void Play()
    {
        for(int i=0;i<MAX;i++)
        {
            key=play.Roll();
            System.out.print("\nNumber rolled: "+key); 
            count++; 
            for(int a=1;a<7;a++)
            {
                if(a==key)
                {
                    results[a]=true;
                    System.out.print("\nSo far, you have rolled ");  
                    if(results[a]==true)
                    {
                        check=true;
                        for(int k=1;k<7;k++)
                        {
                            if(results[k] ==true)
                        {
                            System.out.print(" "+k+" ");
                        }
                        if(results[k] == false)
                        check=false;
                        }
                    }        
                }
            }  
            if(check==true)
            {
                System.out.print("\nCongratulations, you have taken "+count+" rolls to get one of each number between 1 and 6");
                break;
            }         
        }             
    }

    public int Check(int []check,int key)
    {
        int check1= Arrays.binarySearch(check,key);
        return check1;   
    }

    //public JButton getButton()
    //{
       // JButton button = null;
        //SixNumbersPanel2 roll = new SixNumbersPanel2();
        //return roll.roll = button;
    //}
    public void rolldisable() 
    {
        SixNumbersPanel2 dis = new SixNumbersPanel2();
        dis.getSubButton().setEnabled(false);
    }
}

Также с помощью кнопки restartButton JButton он не перезапускает всю игру, а только для игрока, который щелкает по ней.Любое предложение о том, как сделать так, чтобы он перезапускал весь графический интерфейс, было бы замечательно.

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 25 мая 2018

Это ...

public void rolldisable() 
{
    SixNumbersPanel2 dis = new SixNumbersPanel2();
    dis.getSubButton().setEnabled(false);
}

неправильно, в основном вы создаете новый экземпляр SixNumbersPanel2 и пытаетесь изменить его состояние, но на самом деле оно не отображается на экране и не отображает егоиметь какое-либо отношение к тому, что отображается на экране.

Это решение не простое.Вам нужна какая-то модель / контроллер, которая может использоваться двумя экземплярами SixNumbersPanel2 и которая генерирует соответствующие события состояния, на которые они могут реагировать.

Вам нужно будет разработать какой-то способ определения того, какиеигрок - это то, что каждый SixNumbersPanel2 знает, какого игрока он представляет и какой игрок в данный момент активен

Обновлено ...

Для того, чтобы реализовать необходимые изменения функции, вам нужно что-то вроде "центральный "хаб", который управляет основной функциональностью и может генерировать уведомления / события, когда состояние изменяется каким-либо значимым образом (как следующий ход игроков)

В общих чертах, они охватываются:

Сначала нам нужно начать с некоторого видатокен, чтобы различать игроков ...

enum Player {
    ONE, TWO;
}

Далее нам понадобится какая-то «модель», которая используется для управления данными и основными функциями

public interface SixNumbersModel {        
    public Player getCurrentTurn();        
    public Player nextTurn();        
    public int roll();        
    public boolean hasWon(Player player);        
    public Set<Integer> getPlayerResults(Player player);
    public int getTurnsCount(Player player);        
    public void addChangeListener(ChangeListener listener);
    public void removeChangeListener(ChangeListener listener);
}

nb: На самом деле у вас может быть «модель игрока», которая управляет результатами, но я ленивый

Причина, по которой я начал с interface, заключается в том, что пользователи моделине должно заботиться о том, как реализована модель (реализации могут разделять управление результатами каждого игрока на отдельные модели, но пользователям SixNumbersModel это не нужно)

public class DefaultSizeNumbersModel implements SixNumbersModel {

    private List<ChangeListener> changeListeners;
    private Die die = new Die();

    private Player turn;

    private Map<Player, Set<Integer>> results;
    private Map<Player, Integer> turns;

    public DefaultSizeNumbersModel() {
        changeListeners = new ArrayList<>(2);
        results = new HashMap<>();
        results.put(Player.ONE, new HashSet<>(6));
        results.put(Player.TWO, new HashSet<>(6));
        turns = new HashMap<>(2);
        turns.put(Player.ONE, 0);
        turns.put(Player.TWO, 0);
        setCurrentTurn(Player.ONE);
    }

    @Override
    public Player getCurrentTurn() {
        return turn;
    }

    protected void setCurrentTurn(Player player) {
        turn = player;
    }

    @Override
    public Player nextTurn() {
        switch (getCurrentTurn()) {
            case ONE:
                setCurrentTurn(Player.TWO);
                break;
            case TWO:
                setCurrentTurn(Player.ONE);
                break;
            default:
                setCurrentTurn(Player.ONE);
                break;
        }
        fireStateChanged();
        return getCurrentTurn();
    }

    @Override
    public int roll() {
        incrementTurnCount(getCurrentTurn());
        int result = die.Roll();
        Set<Integer> playerResults = results.get(getCurrentTurn());
        playerResults.add(result);
        return result;
    }

    @Override
    public boolean hasWon(Player player) {
        Set<Integer> playerResults = results.get(getCurrentTurn());
        return playerResults.size() == 5; // 0...5
    }

    @Override
    public Set<Integer> getPlayerResults(Player player) {
        Set<Integer> actualResults = results.get(player);
        Set<Integer> copy = new HashSet<>(actualResults);
        return copy;
    }

    @Override
    public int getTurnsCount(Player player) {
        return turns.get(player);
    }

    protected void setTurnsCount(Player player, int count) {
        turns.put(player, count);
    }

    protected void incrementTurnCount(Player player) {
        int count = getTurnsCount(player);
        count++;
        setTurnsCount(player, count);
    }

    @Override
    public void addChangeListener(ChangeListener listener) {
        changeListeners.add(listener);
    }

    @Override
    public void removeChangeListener(ChangeListener listener) {
        changeListeners.remove(listener);
    }

    protected void fireStateChanged() {
        ChangeEvent evt = new ChangeEvent(this);
        for (ChangeListener listener : changeListeners) {
            listener.stateChanged(evt);
        }
    }
}

Тогда нам нужен какой-то вид"view" ...

public class SixNumbersPanel extends JPanel {

    private Player player;
    private SixNumbersModel model;

    private JButton roll;
    private JTextArea ta;

    public SixNumbersPanel(Player player, SixNumbersModel model) {
        this.player = player;
        this.model = model;

        model.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                roll.setEnabled(player == model.getCurrentTurn());
            }
        });

        roll = new JButton("Roll");
        ta = new JTextArea(5, 10);

        roll.setEnabled(player == model.getCurrentTurn());

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(new JLabel(player.name()), gbc);
        add(roll, gbc);

        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.fill = GridBagConstraints.BOTH;
        add(new JScrollPane(ta), gbc);

        roll.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int result = model.roll();
                ta.append(Integer.toString(result) + "\n");
                if (model.hasWon(player)) {
                    JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
                }
                model.nextTurn();
            }
        });

    }

}

Ладно, очень просто, но в нем просто есть кнопка и текстовая область.Он регистрирует интерес к модели, которая будет уведомлена при изменении состояния, и гарантирует, что кнопка активна только в том случае, если игрок, которого она представляет, является текущим игроком.

Rolly Polly

Пример запуска ...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    enum Player {
        ONE, TWO;
    }

    public interface SixNumbersModel {

        public Player getCurrentTurn();

        public Player nextTurn();

        public int roll();

        public boolean hasWon(Player player);

        public Set<Integer> getPlayerResults(Player player);

        public int getTurnsCount(Player player);

        public void addChangeListener(ChangeListener listener);

        public void removeChangeListener(ChangeListener listener);
    }

    public class DefaultSizeNumbersModel implements SixNumbersModel {

        private List<ChangeListener> changeListeners;
        private Die die = new Die();

        private Player turn;

        private Map<Player, Set<Integer>> results;
        private Map<Player, Integer> turns;

        public DefaultSizeNumbersModel() {
            changeListeners = new ArrayList<>(2);
            results = new HashMap<>();
            results.put(Player.ONE, new HashSet<>(6));
            results.put(Player.TWO, new HashSet<>(6));
            turns = new HashMap<>(2);
            turns.put(Player.ONE, 0);
            turns.put(Player.TWO, 0);
            setCurrentTurn(Player.ONE);
        }

        @Override
        public Player getCurrentTurn() {
            return turn;
        }

        protected void setCurrentTurn(Player player) {
            turn = player;
        }

        @Override
        public Player nextTurn() {
            switch (getCurrentTurn()) {
                case ONE:
                    setCurrentTurn(Player.TWO);
                    break;
                case TWO:
                    setCurrentTurn(Player.ONE);
                    break;
                default:
                    setCurrentTurn(Player.ONE);
                    break;
            }
            fireStateChanged();
            return getCurrentTurn();
        }

        @Override
        public int roll() {
            incrementTurnCount(getCurrentTurn());
            int result = die.Roll();
            Set<Integer> playerResults = results.get(getCurrentTurn());
            playerResults.add(result);
            return result;
        }

        @Override
        public boolean hasWon(Player player) {
            Set<Integer> playerResults = results.get(getCurrentTurn());
            return playerResults.size() == 5; // 0...5
        }

        @Override
        public Set<Integer> getPlayerResults(Player player) {
            Set<Integer> actualResults = results.get(player);
            Set<Integer> copy = new HashSet<>(actualResults);
            return copy;
        }

        @Override
        public int getTurnsCount(Player player) {
            return turns.get(player);
        }

        protected void setTurnsCount(Player player, int count) {
            turns.put(player, count);
        }

        protected void incrementTurnCount(Player player) {
            int count = getTurnsCount(player);
            count++;
            setTurnsCount(player, count);
        }

        @Override
        public void addChangeListener(ChangeListener listener) {
            changeListeners.add(listener);
        }

        @Override
        public void removeChangeListener(ChangeListener listener) {
            changeListeners.remove(listener);
        }

        protected void fireStateChanged() {
            ChangeEvent evt = new ChangeEvent(this);
            for (ChangeListener listener : changeListeners) {
                listener.stateChanged(evt);
            }
        }
    }

    public class Die {

        private final int MAX = 6;
        private int die1;
        Random rand = new Random();

        //Constructor
        public Die() {
            die1 = 1;
        }// end Constructor

        public int Roll() {
            die1 = rand.nextInt(MAX) + 1;
            return die1;
        }
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Roll Six");
                frame.setLayout(new GridLayout(2, 0));

                SixNumbersModel model = new DefaultSizeNumbersModel();
                SixNumbersPanel onePane = new SixNumbersPanel(Player.ONE, model);
                SixNumbersPanel twoPane = new SixNumbersPanel(Player.TWO, model);

                frame.add(onePane);
                frame.add(twoPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SixNumbersPanel extends JPanel {

        private Player player;
        private SixNumbersModel model;

        private JButton roll;
        private JTextArea ta;

        public SixNumbersPanel(Player player, SixNumbersModel model) {
            this.player = player;
            this.model = model;

            model.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    roll.setEnabled(player == model.getCurrentTurn());
                }
            });

            roll = new JButton("Roll");
            ta = new JTextArea(5, 10);

            roll.setEnabled(player == model.getCurrentTurn());

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(new JLabel(player.name()), gbc);
            add(roll, gbc);

            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(new JScrollPane(ta), gbc);

            roll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int result = model.roll();
                    ta.append(Integer.toString(result) + "\n");
                    if (model.hasWon(player)) {
                        JOptionPane.showMessageDialog(SixNumbersPanel.this, player + " has won");
                    }
                    model.nextTurn();
                }
            });

        }

    }

}
...