启用另一个JBUtton时禁用一个JButton

时间:2018-05-25 03:53:48

标签: java swing jbutton

我试图为我的作业构建一个简单的滚动骰子游戏。将有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,它不会重启整个游戏,但仅适用于点击它的玩家。任何关于如何重新启动整个GUI的建议都会很棒。

所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

此...

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

是错误的,基本上你正在创建SixNumbersPanel2的新实例,并试图改变它的状态,但它实际上并没有在屏幕上显示,也没有与屏幕上显示的内容有关。

这个解决方案并不简单。您需要的是某种模型/控制器,它可以在SixNumbersPanel2的两个实例之间共享,并生成可以响应的适当状态事件。

你需要设计一些识别哪个玩家的方法,以便每个SixNumbersPanel2知道它代表哪个玩家以及哪个玩家当前有效

更新...

为了实现所需的功能更改,您需要某种&#34; central&#34; hub,管理核心功能,当状态以某种有意义的方式发生变化时(如下一个玩家转向),可以生成通知/事件

从广义上讲,这些内容包括:

首先,我们需要从某种令牌开始,以区分玩家......

enum Player {
    ONE, TWO;
}

接下来,我们需要某种&#34;模型&#34;,用于管理数据和核心功能

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:你实际上可以拥有一个&#34;播放器模型&#34;管理结果,但我一直懒惰

我开始使用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);
        }
    }
}

然后我们需要某种&#34;视图&#34; ...

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();
                }
            });

        }

    }

}