2016-09-02 7 views
2

私はテキストアドベンチャーゲームを作っていて、自分の好きな方法で自分のテキスト表示を得ることができない問題に遭遇しました。いくつかの言葉を入力すると、プレイヤーは新しい部屋の導入を開始することができます。私はこの紹介に「タイプライター」効果を持たせたいと思っています。このイベントは私のプログラムのActionPerformedメソッドで発生する必要があります。たとえば、ユーザーが「移動」してからEnterキーを押すと、結果のテキストが一度に1文字ずつ印刷されます。私はそれが私のスレッドを妨げないように、同様の方法は、Timerクラスを使用することで動作するように取得できますかタイマーを使用してJTextAreaでタイプライターエフェクトを実現するには?

public void slowPrint(String message, long millisPerChar) 
{ 
    //makes it so that the player cannot input while the text is being displayed 
    userinput.setEditable(false); 
    String o; 
     for (int i = 0; i < message.length(); i++) 
     { 
      //adds each letter one-by-one 
      o = "" + message.charAt(i); 
      output.append(o); 

      //moves the JTextArea to the bottom 
      output.setCaretPosition (output.getDocument().getLength()); 

      //delay so that you can see each letter being added 
      try { 
       Thread.sleep(millisPerChar);; 
       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); } 
     } 
    //after the text is displayed allow the user to input again 
    userinput.setEditable(true); 
    } 

:ここ

は、私はこの効果を達成するためのactionPerformedの外で使う現在の方法であり、 GUIの更新から

これは私のアクションは、関連するメソッドを持つようなルックスを行っです:

public void actionPerformed(ActionEvent e) 
{ 
     s = userinput.getText(); 
     output.append("\n"); 
     userinput.setText(""); 

     for (int i = 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; 
       } 
      } 
     } 

    } 

そして「controlOne()」メソッド:

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)); 
} 

の代わりに私が使用したいすべての時間を追加私の "slowPrint"メソッドに似たものです。

うまくいけば、これはいくらか意味があり、助けがあれば大いに感謝するだろう。 Timer

答えて

5

2つの本質的な価値は、あなたがあなたのslowPrintメソッドの内部タイマーを作成した場合、それへの参照を維持することが重要である遅延

  • ActionListener
    1. です、後でそれをやめることができます。したがって、後でActionListenerを追加する必要があります。 ActionListenerの中では、現在のテキスト位置を追加変数で追跡することができます(for-loopについては忘れてください)。次に、すべてのテキストが印刷されているかどうかを手動でチェックし、それに応じてタイマーを停止するだけです。

      最初に遅延を発生させたい場合は、timer.setInitialDelay(delay)に電話してください。

      GIF


      あなたslowPrint方法に変更と例:

      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 is a 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(); 
          } 
      
      } 
      
    関連する問題