Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 函数被无故调用两次_Java_Eclipse_Debugging_Keypress_Key Events - Fatal编程技术网

Java 函数被无故调用两次

Java 函数被无故调用两次,java,eclipse,debugging,keypress,key-events,Java,Eclipse,Debugging,Keypress,Key Events,我正在申请测验。当我按下视图中的一个键时,模型就会通过控制器更新。但是模型中的函数一开始会被调用一次。下次我按键2次,下次3次,。。。等等 我完全不知道这是怎么发生的。我试过调试它,但没有从多个地方调用它。就从1号开始。这几乎就像关键事件堆积在一起,并不断调用该方法 这是我的多个类的代码 获取关键事件的测验视图: /** * This class will show the questions and react on the keyboard events * @author Matthi

我正在申请测验。当我按下视图中的一个键时,模型就会通过控制器更新。但是模型中的函数一开始会被调用一次。下次我按键2次,下次3次,。。。等等

我完全不知道这是怎么发生的。我试过调试它,但没有从多个地方调用它。就从1号开始。这几乎就像关键事件堆积在一起,并不断调用该方法

这是我的多个类的代码

获取关键事件的测验视图:

/**
 * This class will show the questions and react on the keyboard events
 * @author Matthias Claes
 *
 */
public class QuizView extends JPanel implements View {
private Observable $model;
private Controller $controller;

private Question $question;

private boolean $isPressed; /* To check if we already listened to a key press event */


public QuizView(Observable model, Controller controller){
    setFocusable(true);

    $model = model;

    if (controller == null)
        $controller = new QuizController(model);
    else
        $controller = controller;

    $question = null;   
    $isPressed = false;

    /* Add a keylistener for every team */
    addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) {
            int teamSize; /* team size*/
            teamSize = ((QuizModel) getModel()).getTeams().size();
            if (Character.getNumericValue(e.getKeyChar()) <= teamSize) { /* If you pressed a number under the teamsize we listen to it, and there hasn't been pressed before */

                buttonPressed(Character.getNumericValue(e.getKeyChar()));

                // Else ignore the key stroke
            }
        }
    }); 

}

/**
 * If a button gets pressed we call this function
 * @param team the team that pressed their button
 */
protected void buttonPressed(int team) {
    /* Check if a button is pressed */
    if(((QuizModel) getModel()).getTeamPressed() > 0)
        $isPressed = true;
    else
        $isPressed = false;

    /* If there hasn't been pressed yet and the question is not null */
    if(!$isPressed && $question != null){
        minimizeFrame(); /* Minimize the frame */

        /* If this question has a media path we need to pause the audio/video, we also check if the user has installed vlcplayer and selected the right path */
        if($question.getMediaPath() != null && QuizSoftwareModel.$vlcPath != null)
            ((QuizController)getController()).pause(); /* Pause the video */

        /* Give a pop up message to the admin that a team has pushed their button */
        ((QuizController)getController()).showScoreView(team);
    }

}

public void update(Observable arg0, Object arg1) {
    $question = (Question) arg1;

    System.out.println("CALLED");

    if(((QuizModel) getModel()).getMaximize()) /* Only maximize the JFrame when needed */
        maximizeFrame(); /* Maximize the frame first */     

    repaint();
}


/**
 * Maximize the parent JFrame so the teams can see the question
 */
protected void maximizeFrame() {
    JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
    topFrame.setState(JFrame.MAXIMIZED_BOTH);

}

/**
 * Minimize the parent JFrame so the teams can't see the question anymore 
 */
protected void minimizeFrame() {
    JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
    topFrame.setState(JFrame.ICONIFIED);

}
测验模式:

/**
 * The model of the quiz
 * @author Matthias Claes
 *
 */

public class QuizModel extends Observable {
private ArrayList<Question> $questions;
private ArrayList<Team> $teams;
private Question $currentQuestion;
private MediaPlayer $mp;
private int $i; /* The position in the questions, at which question we are at the moment */
private int $teamPressed; /* The team that pressed their button */
private boolean $running;
private boolean $displayScoreView;
private boolean $maximize; /* A boolean that tells the QuizView if we need to maximize this JFrame again */


/**
 * Constructor for QuizModel
 * @param questions a list of questions
 */
public QuizModel(ArrayList<Question> questions){

    $mp = new MediaPlayer(this, null); /* null -> Give the default controller as parameter */
    this.addObserver($mp);

    $teams = new ArrayList<Team>();
    if (questions != null) {
        $questions = questions;
    }
    else 
        $questions = new ArrayList<Question>();

    $currentQuestion = null;

    $teamPressed = 0; /* Default value*/
    $maximize = false; /* Default value */

    $i = 0;
    $running = false;
    $displayScoreView = false;
}




/**
 * Starts the quiz
 */
public void start() {

    if (initialized()) {// quiz properly initialized
        $running = true;
        nextQuestion();

    }
    else {
        // TODO what happens when the quiz isn't properly initialized yet
    }
}


/**
 * Will create a view where the admin can choose the score if the answer was right, resume if the answer was false.
 * @param i the team that pushed the button 
 */
public void showScoreView(int i) {
    $teamPressed = i;
    setDisplayScoreView(true);

    /* Update the view */
    System.out.println("show score view");
    setChanged();
    notifyObservers($currentQuestion);

}

/**
 * Get the boolean displayScoreView
 * @return returns true of false, depending on the displayScoreView boolean
 */
public boolean getDisplayScoreView(){
    return $displayScoreView;
}

/**
 * Set the $displayScoreView boolean
 * @param displayScoreView the new value of $displayScoreView
 */
public void setDisplayScoreView(boolean displayScoreView){
    $displayScoreView = displayScoreView;
}


/**
 * Goes to the next question in the quiz
 */
public void nextQuestion(){
    if($running == true && $i < $questions.size()){
        $currentQuestion = $questions.get($i);

        $i++;
        /* This question has a mediaPath but the user doesn't have vlc installed or selected the wrong folder, so they can't use this question, so we go to the next one */
        if($currentQuestion.getMediaPath() != null && QuizSoftwareModel.$vlcPath == null){
            JOptionPane.showMessageDialog(null, QuizSoftwareModel.$messages.getString("videoDisplayError"));
            nextQuestion(); /* go the next question */

        }
        /* Display the question */ 
        else{
            System.out.println("Diplay first question");
            setChanged();
            notifyObservers($currentQuestion);
        }

    } /* End of the quiz */
    else{
        /* Show winner TODO */
    }

}


public Question getCurrentQuestion() {
    return $currentQuestion;
}

public int getI() {
    return $i;
}


/**
 * Resume the question
 */
public void resumeQuestion() {
    $teamPressed = 0; /* Reset the team that has pressed so other teams can press aswell */
    $maximize = true; /* Maximize the screen again */
    $displayScoreView = false;

    /* TODO SAVE THE TEAM INTO AN ARRAY SO THIS TEAM CAN'T PRESS AGAIN */
    System.out.println("RESUME");
    this.setChanged();
    this.notifyObservers($currentQuestion);
}


/**
 * Return the $maximize boolean
 * @return returns the $maximize boolean
 */
public boolean getMaximize() {
    return $maximize;
}

}
/**
*测验的模式
*@作者Matthias Claes
*
*/
公共类QuizModel扩展了可观察{
私人ArrayList$问题;
私人ArrayList$团队;
私人问题;私人问题;
私人媒体播放器$mp;
private int$i;/*问题中的位置,即我们目前所处的问题*/
private int$teamPressed;/*按下按钮的团队*/
私有布尔元运行;
私有布尔$displayScoreView;
私有布尔值$maximize;/*一个布尔值,告诉QuizView是否需要再次最大化此JFrame*/
/**
*QuizModel的构造函数
*@param问题一系列问题
*/
公共QuizModel(ArrayList问题){
$mp=new MediaPlayer(这个,null);/*null->将默认控制器作为参数*/
这是一个额外的观察者($mp);
$teams=newarraylist();
如果(问题!=null){
$questions=问题;
}
其他的
$questions=newarraylist();
$currentQuestion=null;
$teamPressed=0;/*默认值*/
$maximize=false;/*默认值*/
$i=0;
$running=false;
$displayScoreView=false;
}
/**
*开始测验
*/
公开作废开始(){
如果(已初始化()){//正确初始化
$running=true;
nextQuestion();
}
否则{
//TODO当测验尚未正确初始化时会发生什么
}
}
/**
*将创建一个视图,管理员可以选择分数,如果答案是正确的,继续如果答案是错误的。
*@param i按下按钮的团队
*/
公共void showScoreView(int i){
$teamPressed=i;
setDisplayScoreView(真);
/*更新视图*/
System.out.println(“显示分数视图”);
setChanged();
通知观察员(当前问题);
}
/**
*获取boolean displayScoreView
*@return返回true或false,具体取决于displayScoreView布尔值
*/
公共布尔getDisplayScoreView(){
返回$displayScoreView;
}
/**
*将$displayScoreView设置为布尔值
*@param displayScoreView$displayScoreView的新值
*/
public void setDisplayScoreView(布尔显示ScoreView){
$displayScoreView=displayScoreView;
}
/**
*转到测验中的下一个问题
*/
public void nextQuestion(){
如果($running==true&&$i<$questions.size()){
$currentQuestion=$questions.get($i);
$i++;
/*此问题有一个mediaPath,但用户没有安装vlc或选择错误的文件夹,因此他们无法使用此问题,因此我们转到下一个问题*/
if($currentQuestion.getMediaPath()!=null&&QuizSoftwareModel.$vlcPath==null){
showMessageDialog(null,QuizSoftwareModel.$messages.getString(“videoDisplayError”);
nextQuestion();/*转到下一个问题*/
}
/*显示问题*/
否则{
System.out.println(“Diplay第一个问题”);
setChanged();
通知观察员(当前问题);
}
}/*测验结束*/
否则{
/*节目赢家托多*/
}
}
公共问题getCurrentQuestion(){
返回$currentQuestion;
}
公共int getI(){
返回$i;
}
/**
*继续提问
*/
公众谘询{
$teamPressed=0;/*重置已按下的团队,以便其他团队也可以按下*/
$maximize=true;/*再次最大化屏幕*/
$displayScoreView=false;
/*TODO将团队保存到数组中,以便此团队不能再次按*/
系统输出打印号(“简历”);
这个.setChanged();
这是一个问题;
}
/**
*返回$maximize布尔值
*@return返回$maximize布尔值
*/
公共布尔getMaximize(){
收益最大化;
}
}
我得到的输出如下:
播放第一个问题
调用
显示分数视图
调用
恢复
调用
显示分数视图
调用
恢复
调用
恢复
调用

因此quizmodel中的resume方法被多次调用

我不知道是否有人能帮我,但已经谢谢了。
很抱歉,我的帖子太长了,但我不知道如何向大家展示它。

在方法
displayScoreView()
中,您正在向
$resumeButton
引用的按钮添加一个
ActionListener
,该按钮最终将调用
resumeQuestion()
方法

由于
displayScoreView()
是一个实例方法,可以多次调用(似乎会调用),而
$resumeButton
GiveScoreView
实例的整个生命周期中包含同一个按钮实例,因此可能有多个侦听器执行相同的操作(即调用
resumeQuestion()
)已在该按钮上注册


请注意,如果很难找出代码实际在做什么,您应该考虑清理它…

您正在经历的行为表明,每次程序反应时,您都在向输入添加新的侦听器。尝试移动此代码块:

        /* Add actionlisteners to the buttons */
        $resumeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if($question.getMediaPath() != null && QuizSoftwareModel.$vlcPath != null) /* If there is an audio/video piece */
                    ((GiveScoreController)getController()).resumeMP(); /* Resume the mediaplayer if there is an audio/video piece */

                ((GiveScoreController)getController()).resumeQuestion(); /* Resume the question */
                closeFrame(); /* Close the frame */
            }
        });

        $calculateButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if($question.getMediaPath() != null && QuizSoftwareModel.$vlcPath != null) /* If there is an audio/video piece */
                    ((GiveScoreController)getController()).closeMP(); /* Close the mediaplayer */
                ((GiveScoreController)getController()).nextQuestion(); /* Go on to the next question */
                closeFrame(); /* Close the frame */
            }
        });
要在构造函数内部,请在代码下方执行以下操作:

    $resumeButton = new JButton("Resume question"); /* TODO messagebundle */
    $calculateButton = new JButton("Calculate score"); /* TODO messagebundle */

这样,您只需为每个按钮创建一个侦听器。

为什么要对所有变量名使用
$
?这是非常糟糕的Java风格。这听起来像是调试器非常有用的情况……你会有更好的选择
        /* Add actionlisteners to the buttons */
        $resumeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if($question.getMediaPath() != null && QuizSoftwareModel.$vlcPath != null) /* If there is an audio/video piece */
                    ((GiveScoreController)getController()).resumeMP(); /* Resume the mediaplayer if there is an audio/video piece */

                ((GiveScoreController)getController()).resumeQuestion(); /* Resume the question */
                closeFrame(); /* Close the frame */
            }
        });

        $calculateButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if($question.getMediaPath() != null && QuizSoftwareModel.$vlcPath != null) /* If there is an audio/video piece */
                    ((GiveScoreController)getController()).closeMP(); /* Close the mediaplayer */
                ((GiveScoreController)getController()).nextQuestion(); /* Go on to the next question */
                closeFrame(); /* Close the frame */
            }
        });
    $resumeButton = new JButton("Resume question"); /* TODO messagebundle */
    $calculateButton = new JButton("Calculate score"); /* TODO messagebundle */