2008-10-04 9 views
1

Je suis en train d'écrire un jeu en Java, et je veux que l'utilisateur puisse fournir une entrée depuis la ligne de commande et mon interface graphique. À l'heure actuelle, j'utilise cette méthode pour obtenir l'entrée:
Émulation de l'entrée utilisateur pour java.util.Scanner

static String getInput(){ 
     System.out.println("Your move:"); 
     Scanner sc = new Scanner(System.in); 
     return sc.nextLine(); 
    } 

Je veux continuer à l'utiliser, mais laisser un événement mousePressed émule l'utilisateur en tapant réellement dans leur entrée aussi bien. Ce n'est pas une solution efficace, mais cela a du sens dans mon application. Donc la question est: comment puis-je simuler un utilisateur en tapant System.in du côté du code?

Répondre

1

Ceci est possible - la substitution la plus simple pour System.in serait un PipedInputStream. Cela doit être relié à un PipedOutputStream qui écrit à partir d'un autre thread (dans ce cas, le thread Swing).

public class GameInput { 

    private Scanner scanner; 

    /**CLI constructor*/ 
    public GameInput() { 
     scanner = new Scanner(System.in); 
    } 

    /**GUI constructor*/ 
    public GameInput(PipedOutputStream out) throws IOException { 
     InputStream in = new PipedInputStream(out); 
     scanner = new Scanner(in); 
    } 

    public String getInput() { 
     return scanner.nextLine(); 
    } 

    public static void main(String[] args) throws IOException { 
     GameInput gameInput; 

     PipedOutputStream output = new PipedOutputStream(); 
     final PrintWriter writer = new PrintWriter(output); 
     gameInput = new GameInput(output); 

     final JTextField textField = new JTextField(30); 
     final JButton button = new JButton("OK"); 
     button.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       String data = textField.getText(); 
       writer.println(data); 
       writer.flush(); 
      } 
     }); 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().setLayout(new FlowLayout()); 
     frame.getContentPane().add(textField); 
     frame.getContentPane().add(button); 
     frame.pack(); 
     frame.setVisible(true); 

     String data = gameInput.getInput(); 
     System.out.println("Input=" + data); 
     System.exit(0); 
    } 

} 

Cependant, il pourrait être préférable de repenser votre logique de jeu à découper les cours d'eau tout à fait en mode graphique.

+0

Merci! Ceci est exactement ce que je cherchais.Vous avez raison de dire qu'il devrait y avoir un meilleur moyen de gérer les entrées des utilisateurs, mais j'essayais d'obtenir quelque chose qui a peu de place pour les bogues implémentés rapidement. J'ai pris plus de temps/d'efforts que je ne le pensais ... ah, eh bien. Leçon apprise. – perimosocordiae

0

J'ai fait une application une fois qui pourrait fonctionner via la ligne de commande ou en utilisant une interface graphique.
La façon dont je l'ai fait était de définir une interface (nommée IODevice) qui a défini les méthodes suivantes:

  • public String getInput();
  • public void showOutput (sortie de chaîne);

  • J'ai ensuite eu deux classes qui mis en œuvre cette interface - On a utilisé le terminal de l'ordinateur hôte (comme vous le faites maintenant) et on utilisait une JTextArea (sortie)/JOptionPane (entrée).

    Peut-être que vous pourriez faire quelque chose de similaire - Pour changer le périphérique d'entrée utilisé, il suffit de changer l'instance de l'IODevice.


    Espérons que cela est d'une certaine utilité.

    0

    Pour être honnête, après avoir relu votre question je ne sais pas exactement ce que vous voulez.

    Quoi qu'il en soit, vous devez peut-être vérifier la méthode java.lang.System.setIn (InputStream in). Cela vous permettra de changer quel lecteur est utilisé pour lire l'entrée du terminal (c.-à-d. Le remplacer par le terminal actuel)

    0

    En supposant que vous ayez plusieurs opérations comme l'exemple donné, vous pouvez envisager l'approche d'interface décrit par Richie_W mais fait une routine par opération plutôt que des méthodes "in/out" génériques.

    Par exemple:

    public interface IGameInteraction 
    { 
        public String askForMove(String prompt); 
        public boolean askAreYouSure(String prompt); 
    } 
    

    Votre mise en œuvre de ligne de commande est claire; maintenant, votre implémentation de l'interface graphique pourrait utiliser une boîte de dialogue appropriée pour chaque opération logique plutôt que d'être simplement une zone de texte qui n'est en fait que la version de ligne de commande.

    De plus, il est plus facile d'écrire des tests unitaires car, dans vos tests, vous pouvez écraser ces routines de n'importe quelle manière.

    Questions connexes