Last active
October 21, 2018 02:40
-
-
Save rbrick/19636182062754980ab99ea6747757fc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.concurrent.TimeUnit; | |
| public final class TestClass { | |
| public static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + | |
| "In in pellentesque sem, quis iaculis sapien. Quisque ut velit vel ex facilisis euismod in et " + | |
| "neque. Donec eget ex in nisl dapibus congue id ultricies odio. Nulla et nibh nec nunc pretium aliquet " + | |
| "in quis augue. Aenean sit amet nisi eu tortor malesuada tincidunt. Fusce in pulvinar sapien, vitae mollis orci. " + | |
| "Donec sed purus luctus, convallis metus sit amet, volutpat turpis. Sed quis nunc id nisl fringilla tincidunt a ut urna."; | |
| public static void main(String[] args) throws InterruptedException { | |
| Marquee marquee = Marquee.newMarquee() | |
| .text(LOREM_IPSUM) // the text we want to scroll | |
| .limit(32) // The character limit to display | |
| .interval(500, TimeUnit.MILLISECONDS) // The update interval | |
| .create(); | |
| for (String text : marquee) { | |
| System.out.println('\r' + text); | |
| // This will constantly be rewriting the line, and not look nice. | |
| // To fix this, we sleep for a few hundred milliseconds | |
| Thread.sleep(250); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.google.common.base.Preconditions; | |
| import javax.annotation.Nonnull; | |
| import java.util.Iterator; | |
| import java.util.concurrent.TimeUnit; | |
| public final class Marquee implements Iterator<String>, Iterable<String> { | |
| public interface Factory { | |
| @Nonnull | |
| Marquee create(); | |
| } | |
| private String text; | |
| private int limit; | |
| private long interval; | |
| private String currentText; | |
| private int currentIndex; | |
| private long lastSent; | |
| private Marquee(String text, int limit, long interval) { | |
| this.text = text; | |
| this.limit = limit; | |
| this.interval = interval; | |
| } | |
| @Override | |
| public boolean hasNext() { | |
| return true; | |
| } | |
| @Override | |
| public String next() { | |
| if (this.text.length() - 1 <= limit) { | |
| return this.text; | |
| } else { | |
| // only update the current text if the time has passed. | |
| if (System.nanoTime() >= lastSent + interval || lastSent <= 0) { | |
| if (this.currentIndex >= this.text.length() - 1) { | |
| this.currentIndex = 0; | |
| } | |
| int finalLimit = Math.min(this.currentIndex + limit, this.text.length()); | |
| if (finalLimit <= this.text.length()) { | |
| if (finalLimit == this.text.length()) { | |
| int diff = (this.currentIndex + limit) - this.text.length(); | |
| String endText = text.substring(this.currentIndex, finalLimit); | |
| String startText = text.substring(0, diff); | |
| this.currentText = String.valueOf(endText + " " + startText).substring(0, limit); | |
| } else { | |
| this.currentText = text.substring(this.currentIndex, finalLimit); | |
| } | |
| } | |
| this.currentIndex++; | |
| if (this.interval > 0) { | |
| this.lastSent = System.nanoTime(); | |
| } | |
| } | |
| return this.currentText; | |
| } | |
| } | |
| @Override | |
| @Nonnull | |
| public Iterator<String> iterator() { | |
| return this; | |
| } | |
| @Nonnull | |
| public static Builder newMarquee() { | |
| return new Builder(); | |
| } | |
| public static final class Builder implements Factory { | |
| private String text; | |
| private int limit; | |
| private long interval; | |
| public Builder text(String text) { | |
| Preconditions.checkArgument(text != null && !text.isEmpty(), "text cannot be null or empty!"); | |
| this.text = text; | |
| return this; | |
| } | |
| public Builder limit(int limit) { | |
| Preconditions.checkArgument(limit >= 16 && limit <= 32, "limit not in range (must be between 16 & 32)!"); | |
| this.limit = limit; | |
| return this; | |
| } | |
| public Builder interval(long time, TimeUnit unit) { | |
| this.interval = unit.toNanos(time); | |
| return this; | |
| } | |
| @Override | |
| @Nonnull | |
| public Marquee create() { | |
| return new Marquee(this.text, this.limit, this.interval); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment