Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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 如何阻止JButton执行无止境循环_Java_Loops_Jbutton - Fatal编程技术网

Java 如何阻止JButton执行无止境循环

Java 如何阻止JButton执行无止境循环,java,loops,jbutton,Java,Loops,Jbutton,基本上,我试图做的是当用户单击按钮时,不断地将一个文本字符串附加到JTextPane中。只有当用户再次单击按钮时,循环才会停止。这是我的按钮的actionPerformed方法: StyledDocument xpInfo = txtXPInfo.getStyledDocument(); if (btnGo.getText().equals("Go Adventure!")) { btnGo.setText("Stop Adventure"); try { do

基本上,我试图做的是当用户单击按钮时,不断地将一个文本字符串附加到JTextPane中。只有当用户再次单击按钮时,循环才会停止。这是我的按钮的actionPerformed方法:

StyledDocument xpInfo = txtXPInfo.getStyledDocument();
if (btnGo.getText().equals("Go Adventure!")) {
    btnGo.setText("Stop Adventure");

    try {
        do {
            xpInfo.insertString(xpInfo.getLength(), "Some string\n", null);
            txtXPInfo.update(txtXPInfo.getGraphics());
            Thread.sleep(1000);
        } while (btnGo.getText().equals("Stop Adventure"));
    } catch (BadLocationException e) {
        System.out.println(e);
    } catch (InterruptedException ex) {
        Logger.getLogger(FrmPlay.class.getName()).log(Level.SEVERE, null, ex);
    }

} else if (btnGo.getText().equals("Stop Adventure")) {
    btnGo.setText("Go Adventure!");
}

我写的代码似乎是一个无止境的循环。我想这可能是因为我在button的actionPerformed方法中做了所有这些,但我不知道如何做。如果这是个愚蠢的问题,我很抱歉。我提前向任何愿意回答这个问题的人表示感谢

我认为您的问题是您正在阻止
事件线程
。在Swing中,操作系统只使用一个线程来调度UI事件(如按下按钮)

在您的例子中,您似乎在该线程上无限循环。如果是,则其他按钮将永远不会注册,因为该线程正忙于执行
do/while
循环


您真正想要做的是启动一个不同的线程(有很多这样的例子)来执行追加循环,并留下
事件线程来调度UI事件。

我认为您的问题是您正在阻止
事件线程。在Swing中,操作系统只使用一个线程来调度UI事件(如按下按钮)

在您的例子中,您似乎在该线程上无限循环。如果是,则其他按钮将永远不会注册,因为该线程正忙于执行
do/while
循环


您真正想要做的是启动另一个执行追加循环的线程(有很多这样的例子),并将
事件线程
留给调度UI事件。

您可以使用
ScheduledExecutorService
,因为它的主要目的是在具有指定时间间隔的单独线程上执行任务。但是您需要记住,所有与UI相关的操作都必须从EDT完成,因此您应该将
txtXPInfo
更新操作包装为
SwingUtilities.invokeLater()

private final scheduledexecutor服务xpInfoScheduledExecutor=Executors.newSingleThreadScheduledExecutor();
私有计划未来xpinfoupdatefuture;
已执行的公共无效操作(){
StyledDocument xpInfo=txtXPInfo.getStyledDocument();
if(btnGo.getText().equals(“Go Adventure!”){
btnGo.setText(“停止冒险”);
xpinfoupdatefuture=xpInfoScheduledExecutor.scheduleAtFixedRate(
新的XpInfoUpdater(),0,1,TimeUnit.SECONDS);
}else if(btnGo.getText().equals(“停止冒险”)){
xpinfoupdatefuture.cancel(true);
btnGo.setText(“去冒险!”);
}
}
私有类XpInfoUpdater实现可运行{
@凌驾
公开募捐{
SwingUtilities.invokeLater(()->{
试一试{
xpInfo.insertString(xpInfo.getLength(),“某些字符串\n”,null);
txtXPInfo.update(txtXPInfo.getGraphics());
}捕获(错误位置异常e){
系统输出打印ln(e);
}
});
}
}

您可以使用
ScheduledExecutorService
,因为它的主要用途是在具有指定时间间隔的单独线程上执行任务。但是您需要记住,所有与UI相关的操作都必须从EDT完成,因此您应该将
txtXPInfo
更新操作包装为
SwingUtilities.invokeLater()

private final scheduledexecutor服务xpInfoScheduledExecutor=Executors.newSingleThreadScheduledExecutor();
私有计划未来xpinfoupdatefuture;
已执行的公共无效操作(){
StyledDocument xpInfo=txtXPInfo.getStyledDocument();
if(btnGo.getText().equals(“Go Adventure!”){
btnGo.setText(“停止冒险”);
xpinfoupdatefuture=xpInfoScheduledExecutor.scheduleAtFixedRate(
新的XpInfoUpdater(),0,1,TimeUnit.SECONDS);
}else if(btnGo.getText().equals(“停止冒险”)){
xpinfoupdatefuture.cancel(true);
btnGo.setText(“去冒险!”);
}
}
私有类XpInfoUpdater实现可运行{
@凌驾
公开募捐{
SwingUtilities.invokeLater(()->{
试一试{
xpInfo.insertString(xpInfo.getLength(),“某些字符串\n”,null);
txtXPInfo.update(txtXPInfo.getGraphics());
}捕获(错误位置异常e){
系统输出打印ln(e);
}
});
}
}

我不在事件线程上这样做Swing、Sleep或循环是个坏主意@沃尔特:我查过了,我可能会把它改成计时器。除了使用Thread.sleep()之外,我不知道如何延迟,所以我使用了Thread.sleep()。我知道循环是个坏主意,我只是不知道如何让它工作。无论如何,谢谢你的推荐!虽然我不在事件线程上做这样的摆动、睡眠或循环是个坏主意@沃尔特:我查过了,我可能会把它改成计时器。除了使用Thread.sleep()之外,我不知道如何延迟,所以我使用了Thread.sleep()。我知道循环是个坏主意,我只是不知道如何让它工作。无论如何,谢谢你的推荐!恐怕我不懂事件线索。你有没有建议我应该在哪里读这本书?不幸的是,我已经试着读了,但有太多的东西我不明白。我以后可能会再读一次。无论如何谢谢你的推荐,学习新东西很好!恐怕我不懂事件线索。你有没有建议我应该在哪里读这本书?不幸的是,我已经试着读了,但有太多的东西我不明白。我以后可能会再读一次。无论如何谢谢你的推荐,学习新东西很好!
private final ScheduledExecutorService xpInfoScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> xpInfoUpdatingFuture;

public void actionPerformed() {
    StyledDocument xpInfo = txtXPInfo.getStyledDocument();
    if (btnGo.getText().equals("Go Adventure!")) {
        btnGo.setText("Stop Adventure");
        xpInfoUpdatingFuture = xpInfoScheduledExecutor.scheduleAtFixedRate(
                new XpInfoUpdater(), 0, 1, TimeUnit.SECONDS);
    } else if (btnGo.getText().equals("Stop Adventure")) {
        xpInfoUpdatingFuture.cancel(true);
        btnGo.setText("Go Adventure!");
    }
}

private class XpInfoUpdater implements Runnable {
    @Override
    public void run() {
        SwingUtilities.invokeLater(() -> {
            try {
                xpInfo.insertString(xpInfo.getLength(), "Some string\n", null);
                txtXPInfo.update(txtXPInfo.getGraphics());
            } catch (BadLocationException e) {
                System.out.println(e);
            }
        });
    }
}