问题有以下两个
1.如何将时间显示出来,而且是倒计时的... 2.当我连续多次点击菜单栏"重新游戏"或者"开始新游戏",那么游戏时间到达后,它会弹出多个如下代码所示的框JOptionPane.showMessageDialog(MainFrame.this, "时间到了!!");int result = JOptionPane.showConfirmDialog(MainFrame.this,
                                          "重玩一次?", "Again", 
                                           JOptionPane.YES_NO_CANCEL_OPTION);而不是一个,我尽力了,只能请求大家帮忙.
  会出现这样的结果我估计是重载游戏时,没有将Timer.stop().无论我如何调试都是这种问题
 代码如下:import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;import cn.elva.Settings;
import cn.elva.model.Map;public class MainFrame extends JFrame
{ private static final long serialVersionUID = 1L; //炸弹的次数
private int bombCount = Settings.BOMBCOUNT;

private JPanel jContentPane = null; private JMenuBar menuBar = null; private JMenu fileMenu = null; private JMenuItem reloadItem = null; private JMenuItem startItem = null;
//炸弹
private JMenuItem bombItem = null;

private JMenuItem exitItem = null; private MapUI mapUI = null;
// 游戏开始时间
private long startTime; // 结束时间
private long endTime; private Timer timer = null; // private JMenuItem ti
private JMenuBar initMenuBar()
{
if (menuBar == null)
{
menuBar = new JMenuBar();
fileMenu = new JMenu("文件"); startItem = new JMenuItem("开始游戏");
startItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
reload();
}
});
reloadItem = new JMenuItem("重来一次");
reloadItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
reload();
}
}); bombItem = new JMenuItem("炸弹");
bombItem.addActionListener(new ActionListener(){
public void actionPerformed( ActionEvent e )
{
if( bombCount==0 )
{
JOptionPane.showMessageDialog(MainFrame.this,"你已经没有炸弹可用了!!!" );
bombItem.setEnabled(false);
return;
}
mapUI.bomb();
bombCount--;
}
});
exitItem = new JMenuItem("退出");
exitItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}); fileMenu.add(startItem);
fileMenu.add(reloadItem);
fileMenu.add( bombItem );
fileMenu.add(exitItem);
menuBar.add(fileMenu);
} return menuBar;
} /**
 * @param args
 */
public static void main(String[] args)
{
// PAN_TODO 自动生成方法存根
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
MainFrame thisClass = new MainFrame();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
} /**
 * This is the default constructor
 */
public MainFrame()
{
super();
initialize();
} /**
 * This method initializes this
 * 
 * @return void
 */
private void initialize()
{
this.setSize(900, 900);
this.setTitle("llk");
this.setJMenuBar(initMenuBar());
// this.setContentPane(getJContentPane());
this.setTitle("连连看");
} private void reload()
{
mapUI = new MapUI();
startTime = System.currentTimeMillis() / 1000; endTime = startTime + Settings.PERTIME; // jContentPane.setVisible(true);
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(mapUI); this.setContentPane(jContentPane);
this.validate();
Map.LEFTCOUNT = Settings.ROWS * Settings.COLUMNS;
initTimer();

bombItem.setEnabled(true);
bombCount=Settings.BOMBCOUNT;
} private void initTimer()
{
ActionListener actionListener = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
startTime = System.currentTimeMillis() / 1000; if (startTime == endTime)
{
JOptionPane.showMessageDialog(MainFrame.this, "时间到了!!");
int result = JOptionPane.showConfirmDialog(MainFrame.this,
"重玩一次?", "Again", JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
reload();
}
else
{
jContentPane.setVisible(false);
validate();
}
}
}
};
timer = new javax.swing.Timer(500, actionListener);
timer.start();
}
}

解决方案 »

  1.   

    Settings  MapUI 是你自己写的?没法测试
      

  2.   

    这是MapUI.java
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import cn.elva.Settings;
    import cn.elva.model.ArrayPoint;
    import cn.elva.model.Map;
    public class MapUI extends JPanel implements ActionListener
    { private static final long serialVersionUID = 1L; //private int bombCount = Settings.BOMBCOUNT;
    // 棋子数组,用按钮来表示
    private ChessButton[] chesses = null; // 数据模型
    private Map map = new Map(); // 判断当前点击的棋子是否是第二次选中的
    private boolean two = false; // 前面点的那个棋子
    private ArrayPoint priviousPoint; // 第二次选中的棋子
    private ArrayPoint currPoint; /**
     * 构造函数
     */
    public MapUI()
    {
    super();
    initialize();
    } /**
     * 初始化函数
     * 
     * @return void
     */
    private void initialize()
    {
    initChesses();
    GridLayout gridLayout = new GridLayout(Settings.ROWS + 2,
    Settings.COLUMNS + 2);
    gridLayout.setHgap(2);
    gridLayout.setVgap(2);
    this.setLayout(gridLayout);
    this.setSize(300, 200);
    // 放置按钮,按行
    for (int row = 0; row < Settings.ROWS + 2; row++)
    {
    for (int col = 0; col < Settings.COLUMNS + 2; col++)
    {
    add(chesses[row * (Settings.COLUMNS + 2) + col]);
    }
    }
    } private void initChesses()
    {
    int[][] values = map.getMap();
    // 初始化棋子,和数据模型里保持一样
    this.chesses = new ChessButton[(Settings.ROWS + 2)
    * (Settings.COLUMNS + 2)]; for (int row = 0; row < 10; row++)
    {
    for (int col = 0; col < 10; col++)
    {
    // 通过二维的数据模型坐标得到一维的棋子坐标
    int index = row * (Settings.COLUMNS + 2) + col;
    // 对棋子的数据模型,即ArrayPoint对象进行设置,指定此棋子具体的位置和值
    chesses[index] = new ChessButton(row, col, values[row][col]);
    // 添加监听器
    chesses[index].addActionListener(this);
    // 将外围的一圈设为不可见,行,列为0 和为最大值的情况
    if (row == 0 || row == (Settings.ROWS + 2 - 1) || col == 0
    || col == (Settings.COLUMNS + 2 - 1))
    {
    chesses[index].setVisible(false);
    }
    }
    }
    } public void clearCheese(ArrayPoint priviousPoint, ArrayPoint currPoint)
    {
    // 处理匹配,看两点中否联通

    // 获得数据模型中的数组
    int[][] values = map.getMap();
    // 将模型中对应的棋子设为0
    values[priviousPoint.getI()][priviousPoint.getJ()] = 0;
    values[currPoint.getI()][currPoint.getJ()] = 0; // 使两个已经消除的按钮不可见
    int index1 = priviousPoint.getI() * (Settings.COLUMNS + 2)
    + priviousPoint.getJ();
    int index2 = currPoint.getI() * (Settings.COLUMNS + 2)
    + currPoint.getJ();
    chesses[index1].setVisible(false);
    chesses[index2].setVisible(false);
    // 如果棋子总数已为0,则程序结束
    if (map.LEFTCOUNT == 0)
    {

    JOptionPane.showMessageDialog(this, "恭喜您通过!!");
    }
    } /**
     * 事件监听器处理函数,也是处理棋子消除的地方
     */
    public void actionPerformed(ActionEvent e)
    {
    // 获得当前的柜子
    ChessButton button = (ChessButton) e.getSource();
    // 获得当前棋子的数据结构
    ArrayPoint p = button.getPoint(); // 如果已有两个棋子选中, 则进行判断操作
    if (two)
    {
    currPoint = p;
    if( map.match(this.priviousPoint, this.currPoint))
    {
    clearCheese(this.priviousPoint, this.currPoint);
    }

    // 设置为没有两个按钮的选中的状态
    two = false;
    }
    else
    {
    // 将当前点击的棋子赋给变量priviousPoint
    this.priviousPoint = p;
    // 标志位设为TRUE,用于点击下个棋子的时候使用
    two = true;
    } } /**
     * 炸弹的功能
     * 
     */
    public void bomb()
    {
    int[][] values = map.getMap();
    ArrayPoint p1 = null;
    ArrayPoint p2 = null; for (int row = 1; row < Settings.ROWS + 1; row++)
    {
    for (int col = 1; col < Settings.COLUMNS + 1; col++)
    {
    if (values[row][col] != 0)
    {
    p1 = new ArrayPoint(row, col, values[row][col]);

    for (int i = 1; i < Settings.ROWS + 1; i++)
    {
    for (int j = 1; j < Settings.COLUMNS + 1; j++)
    {
    if (values[i][j] != 0)
    {
    p2 = new ArrayPoint(i, j, values[i][j]);
    }
    else
    {
    continue;
    } //System.out.println(p1 + "|" + p2); if (map.match(p1, p2))
    {
    clearCheese(p1, p2);
    return;
    }
    }
    }
    }
    }
    }
    }
    }
      

  3.   


    这是ChessButton.javaimport java.net.URL;import javax.swing.ImageIcon;
    import javax.swing.JButton;import cn.elva.Settings;
    import cn.elva.model.ArrayPoint;public class ChessButton extends JButton
    {
    // 按钮所对应的数组中的值和位置,用ArrayPoint结构来表示
    protected ArrayPoint point = null; /**
     * 构造函数,指定按钮所代表的值和位置
     * 
     * @param row
     *              所在行号
     * @param col
     *              所在列号
     * @param value
     *              代表的值
     */
    public ChessButton(int row, int col, int value)
    {
    this(new ArrayPoint(row, col, value));
    } /**
     * 构造函数
     * 
     * @param point
     *              值和位置的数据结构
     */
    public ChessButton(ArrayPoint point)
    {
    this.point = point;
    String name ="Resource/"+point.getValue() + Settings.RELEX;
    URL url = ChessButton.class.getResource(name);
    // System.out.println(url);
    ImageIcon icon = new ImageIcon( url );
    this.setIcon(icon);
    } /**
     * 构造函数,使用默认值
     */
    public ChessButton()
    {
    this(new ArrayPoint(0, 0, 0));
    } /**
     * 返回当前按钮代表的位置和值
     * 
     * @return point
     */
    public ArrayPoint getPoint()
    {
    return point;
    } /**
     * 设置此按钮所代表的位置和值
     * 
     * @param point
     *              要设置的 point
     */
    public void setPoint(ArrayPoint point)
    {
    this.point = point;
    }
    }
      

  4.   

    import cn.elva.Settings;
    import cn.elva.model.ArrayPoint;
    import cn.elva.model.Map;这三个类没有
      

  5.   

    1 自己设个Label,设置一个timer,每秒改变一下Label的显示
    for example
    int hh = 1;
    int mm = 0;
    int ss = 0;
    JLabel lbl = JLabel();
    String s = String.format("%02d:%02d:%02d", hh, mm, ss);
    lbl.setText(s);
    Timer timer2 = new javax.swing.Timer(1000, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (ss = 0) {
                if (mm==0 && hh==0) {
                    timer2.stop(); //如果时间结束则停止Timer
                } else if (mm == 0) {
                    mm = 59;
                    hh--;
                } else {
                    mm--;
                }
            } else {
                ss--;
            }
            lbl.setText(String.format("%02d:%02d:%02d", hh, mm, ss));
        }
    });2 把JOptionPane.showMessageDialog(MainFrame.this, "时间到了!!");换成JDialog,然后用模态对话框,即dialog.setModal(true); dialog.show();这样能保证先提示时间结束,再提示是否重玩。同时你的Timer也要停止,否则还会继续触发事件,继续弹出对话框的

    if (startTime == endTime)
    {
        timer.stop(); //程序的此处还需要追加这个
    ...
      

  6.   

    1 自己设个Label,设置一个timer,每秒改变一下Label的显示
    for example
    Java codeint hh = 1;
    int mm = 0;
    int ss = 0;
    JLabel lbl = JLabel();
    String s = String.format("%02d:%02d:%02d", hh, mm, ss);
    lbl.setText(s);
    Timer timer2 = new javax.swing.Timer(1000, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (ss = 0) {
                if (mm==0 && hh==0) {
                    timer2.stop(); //如果时间结束则停止Timer
                } else if (mm == 0) {
                    mm = 59;
                    hh--;
                } else {
                    mm--;
                }
            } else {
                ss--;
            }
            lbl.setText(String.format("%02d:%02d:%02d", hh, mm, ss));
        }
    });
    2 把JOptionPane.showMessageDialog(MainFrame.this, "时间到了!!");换成JDialog,然后用模态对话框,即dialog.setModal(true); dialog.show();这样能保证先提示时间结束,再提示是否重玩。同时你的Timer也要停止,否则还会继续触发事件,继续弹出对话框的

    if (startTime == endTime)
    {
      timer.stop(); //程序的此处还需要追加这个
    ...
    五楼这个可以试试。