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
Java 以不同的长度延迟遍历文本_Java_Loops_Runnable_Bukkit - Fatal编程技术网

Java 以不同的长度延迟遍历文本

Java 以不同的长度延迟遍历文本,java,loops,runnable,bukkit,Java,Loops,Runnable,Bukkit,Bukkit/插口API- 好的,我正在尝试为我的服务器制作一个教程系统。我经常看到人们显示这样的文本: public void send(String...strings) { for (String string : strings) { player.sendMessage(string); } } public void send(String...strings) { for (String string : strings) {

Bukkit/插口API-
好的,我正在尝试为我的服务器制作一个教程系统。我经常看到人们显示这样的文本:

public void send(String...strings) {
    for (String string : strings) {
        player.sendMessage(string);
    }
}
public void send(String...strings) {
    for (String string : strings) {
        new BukkitRunnable() {
            @Override
            public void run() {
                player.sendMessage(string);
            }
        }.runTaskLater(my_plugin_instance, (string.length()*2));
    }
}
private void send(final Player player, String...messages) {

    long delaySum = 0;

    for (final String message : messages) {
        Runnable myTask = new Runnable() {
            public void run() {
                player.sendMessage(message);
            }
        };

        this.getServer().getScheduler().runTaskLater(this, myTask, delaySum);
        delaySum += message.length() * 2;
    }
}
。。这太可怕了。如你所知,它会垃圾邮件聊天,使其不可读。
因此,我使用runnables以一定的延迟显示文本。我可以很容易地使用相同的特定延迟(即30个滴答声)创建一个runnable,但是我希望runnable能够基于字符串的长度()创建延迟

我试着这样做:

public void send(String...strings) {
    for (String string : strings) {
        player.sendMessage(string);
    }
}
public void send(String...strings) {
    for (String string : strings) {
        new BukkitRunnable() {
            @Override
            public void run() {
                player.sendMessage(string);
            }
        }.runTaskLater(my_plugin_instance, (string.length()*2));
    }
}
private void send(final Player player, String...messages) {

    long delaySum = 0;

    for (final String message : messages) {
        Runnable myTask = new Runnable() {
            public void run() {
                player.sendMessage(message);
            }
        };

        this.getServer().getScheduler().runTaskLater(this, myTask, delaySum);
        delaySum += message.length() * 2;
    }
}
这样,是的,它将采用字符串的长度,但是
for循环
将在runnable显示文本之前继续到下一个字符串。
例如,如果我有这些句子(按照正确的顺序):

  • 欢迎来到服务器,玩家
  • 这台服务器是关于bla、This和that的,还有更多关于that和This的内容
  • 接受本教程?

订单将是

  • 接受本教程?
  • 欢迎来到服务器,玩家
  • 这台服务器是关于bla、This和that的,还有更多关于that和This的内容


我该怎么办


嗯,没有人回答。。最后我自己解决了这个问题,但我并不以代码为荣。必须使用2个runnables。。
如果有人感兴趣,我会把代码留在这里

public void send(Player player,  long delay, String basecolor, String... strings) {
    List<String> str = Arrays.asList(strings);
    new BukkitRunnable() {
        int ind = 0;
        boolean next = true;
        @Override
        public void run() {
            String s = str.get(ind);
            if (next) {
                next = false;
                Bukkit.getScheduler().runTaskLater(YOUR_PLUGIN_INSTANCE, new Runnable() {
                    @Override
                    public void run() {
                            player.sendMessage(ChatColor.translateAlternateColorCodes('&',
                                    basecolor + s.replace("%p", player.getName()).replace("%s", server_name)));
                        next = true;
                    }
                }, (ind == 0 ? 0 : (str.get(ind - 1).length())));
                if (ind + 1 < str.size()) {
                    ind++;
                } else {
                    cancel();
                }
            }
        }
    }.runTaskTimer(YOUR_PLUGIN_INSTANCE, delay, 10);
}
public void send(播放器、长延迟、字符串基色、字符串…字符串){
List str=Arrays.asList(字符串);
新的bukkitrunable(){
int ind=0;
布尔下一步=真;
@凌驾
公开募捐{
字符串s=str.get(ind);
如果(下一个){
下一个=假;
Bukkit.getScheduler().runtaskletter(您的插件实例,new Runnable()){
@凌驾
公开募捐{
player.sendMessage(ChatColor.translateAlternateColorCodes(“&”,
basecolor+s.replace(“%p”,player.getName()).replace(“%s”,server_name));
next=真;
}
},(ind==0?0:(str.get(ind-1.length());
如果(ind+1
例如,可以如下所示:

send(播放器,30,“&a”,“欢迎使用%s,%p!”,“输入要在此处显示的内容!”,“它们的顺序都正确!”) 

您可能想考虑使用一个单一对象(ie. Singleton)作为打印机来打印所有消息。这将避免创建太多线程

下面的解决方案使用BlockingQueue使打印线程等待下一条消息。当消息不在队列中时,run()方法将在不消耗大量CPU的情况下等待

解决方案有两种风格: -如果您取消注释第一个msgQueue-您将得到sendMessage的阻塞行为;该方法将等待所有项目打印完毕。 -如果取消修复第二个msgQueue-消息将被添加到队列中,而无需等待打印

我添加了ExecutorService来管理线程,因为Oracle/Java认为这是使用ExecutorServices管理线程的一个良好实践。一旦不需要MessagePrinter,它将由“executor.shutdownNow();”发出信号,并和平结束

希望这有帮助

package stackoverflow;

import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

class MessagePrinter implements Runnable {

    private static MessagePrinter instance;
    private MessagePrinter() {};

    // Uncomment the one below to make sendText wait until methods until all items are printed:
    // BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>(1);

    // Uncomment the one below to make sendText not wait until messages are printed:
    BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>(1);

    public void run() {
        try {
            while (true) { 
                String str = msgQueue.take();
                Thread.sleep( str.length() );
                TimeUnit.MILLISECONDS.sleep( str.length() * 10 );

                System.out.println(str);
            }
        } catch (InterruptedException e) {
            System.out.println("Quitting...");
            return;
        }
    }

    public void sendText(String... txt) {
        Arrays.asList(txt).stream().forEach(t -> {
            try {
                msgQueue.put(t);
            } catch (InterruptedException e) {
                // Received request to terminate.
                return;
            }
        });
    }

    synchronized public static MessagePrinter getInstance() {
        if (instance == null)
            instance = new MessagePrinter();
        return instance;
    }
}

public class VarDelay {

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        MessagePrinter msp = MessagePrinter.getInstance(); 

        executor.submit(msp);

        msp.sendText(new String[] {"Welcome to the server, player!",
                "This server is about blablabla, this and that and a bit more of that and this",
                "Accept the tutorial?" });

        msp.sendText("More text to follow");

        // Shutdown:
        executor.shutdown();
        if (!executor.awaitTermination(2, TimeUnit.SECONDS)) {
            executor.shutdownNow();
        }
    }
}
包堆栈溢出;
导入java.util.array;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.LinkedBlockingQueue;
导入java.util.concurrent.TimeUnit;
类MessagePrinter实现可运行{
私有静态消息打印机实例;
私有MessagePrinter(){};
//取消对以下方法的注释,使sendText在打印所有项目之前等待方法:
//BlockingQueue msgQueue=新的LinkedBlockingQueue(1);
//取消对以下内容的注释,使sendText不会等待消息打印完成:
BlockingQueue msgQueue=新的LinkedBlockingQueue(1);
公开募捐{
试一试{
虽然(正确){
String str=msgQueue.take();
睡眠(str.length());
时间单位毫秒睡眠(str.length()*10);
系统输出打印项次(str);
}
}捕捉(中断异常e){
System.out.println(“退出…”);
返回;
}
}
公共void sendText(字符串…txt){
Arrays.asList(txt.stream().forEach(t->{
试一试{
msgQueue.put(t);
}捕捉(中断异常e){
//收到终止请求。
返回;
}
});
}
同步的公共静态MessagePrinter getInstance(){
if(实例==null)
instance=newmessageprinter();
返回实例;
}
}
公共类可变延迟{
公共静态void main(字符串[]args)引发InterruptedException{
ExecutorService executor=Executors.newSingleThreadExecutor();
MessagePrinter msp=MessagePrinter.getInstance();
执行人提交(msp);
msp.sendText(新字符串[]{“欢迎来到服务器,播放器!”,
“这个服务器是关于BlaBla,这个,那个,还有更多的东西,”,
“接受教程?”});
msp.sendText(“更多要关注的文本”);
//关闭:
executor.shutdown();
如果(!执行器等待终止(2,时间单位秒)){
执行者。关机现在();
}
}
}

可能就是这样的事情:

public void send(String...strings) {
    for (String string : strings) {
        player.sendMessage(string);
    }
}
public void send(String...strings) {
    for (String string : strings) {
        new BukkitRunnable() {
            @Override
            public void run() {
                player.sendMessage(string);
            }
        }.runTaskLater(my_plugin_instance, (string.length()*2));
    }
}
private void send(final Player player, String...messages) {

    long delaySum = 0;

    for (final String message : messages) {
        Runnable myTask = new Runnable() {
            public void run() {
                player.sendMessage(message);
            }
        };

        this.getServer().getScheduler().runTaskLater(this, myTask, delaySum);
        delaySum += message.length() * 2;
    }
}
这样,每个消息都会被之前计算的所有延迟延迟延迟