i making text adventure game , have run issue cannot of text display in fashion want to. when entering words player initiate introduction of new room. want introduction have "typewriter" effect. event need take place in programs actionperformed method. example when user types "move" , hits enter, want resulting text print 1 character @ time.
here current method use outside of actionperformed achieve effect:
public void slowprint(string message, long millisperchar) { //makes player cannot input while text being displayed userinput.seteditable(false); string o; (int = 0; < message.length(); i++) { //adds each letter one-by-one o = "" + message.charat(i); output.append(o); //moves jtextarea bottom output.setcaretposition (output.getdocument ().getlength ()); //delay can see each letter being added try { thread.sleep(millisperchar);; } catch (interruptedexception e) { // todo auto-generated catch block e.printstacktrace(); } } //after text displayed allow user input again userinput.seteditable(true); }
how can similar method work use of timer class not prevent thread updating gui.
this action performed looks relevant methods:
public void actionperformed(actionevent e) { s = userinput.gettext(); output.append("\n"); userinput.settext(""); (int = 0; i<whatroom.length; i++) { if (whatroom[i]) { switch(i) { case 0: controlone(s); break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; } } } }
and "controlone()" method:
private void controlone(string s) { if(one.gethaslight() == true) { if(!one.getpushyes()) { output.append(one.dealwithlight(s, output)); } else output.append(one.commands(s)); } else output.append(one.commands(s)); }
instead of appending time want use similar "slowprint" method.
hopefully made sense , appreciated.
the 2 essential values of timer
- the delay
- the
actionlistener
if create timer inside slowprint
method, important keep reference it, can stop later. therefore must add actionlistener
later. inside actionlistener
keep track of current text position additional variable (forget for-loop). have check manually if text has been printed, , stop timer accordingly.
if want delay take place initially, call timer.setinitialdelay(delay)
.
example slowprint
method modified:
import java.awt.borderlayout; import java.awt.eventqueue; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.io.ioexception; import javax.swing.jframe; import javax.swing.jpanel; import javax.swing.jtextarea; import javax.swing.jtextfield; import javax.swing.timer; public class foo { private jtextfield input; private jtextarea output; public static void main(string[] args) throws ioexception { eventqueue.invokelater(() -> new foo().createandshowgui()); } public void createandshowgui() { output = new jtextarea(); output.seteditable(false); input = new jtextfield(); input.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { slowprint("this test answer.\n", 100); } }); jpanel contentpane = new jpanel(new borderlayout(5, 5)); contentpane.add(input, borderlayout.north); contentpane.add(output); jframe frame = new jframe("example"); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.setcontentpane(contentpane); frame.setsize(800, 600); frame.setvisible(true); } public void slowprint(string message, int millisperchar) { input.seteditable(false); input.setfocusable(false); timer timer = new timer(millisperchar, null); timer.addactionlistener(new actionlistener() { int counter = 0; @override public void actionperformed(actionevent e) { output.append(string.valueof(message.charat(counter++))); output.setcaretposition(output.getdocument().getlength()); if (counter >= message.length()) { timer.stop(); input.seteditable(true); input.setfocusable(true); input.requestfocusinwindow(); } } }); timer.start(); } }
Comments
Post a Comment