【问题标题】:how to load and execute java commands from a text file如何从文本文件加载和执行 java 命令
【发布时间】:2012-11-16 16:06:37
【问题描述】:

我是 Java 编码新手,需要一些建议。

我正在编写一个小程序,该程序根据用户控制台输入的指定在图形面板中绘制形状。 (使用扫描仪类)

例如,用户可以键入 move 100 100 将图形“笔”移动到 x,y 点, 或者可以输入line 100 200 在两个坐标之间画一条线, 或者可以输入'circle 50'来绘制一个半径为50px的圆

我的下一个目标是包含命令“load example.txt”以加载一个文本文件(example.txt),其中包含一些命令,然后将在图形面板上执行。

有人告诉我最好的方法是使用

processCommandLine(String commandLine);

我已经浏览互联网很长时间了,现在正在寻找一些有用的信息,但到目前为止,我只能找到如何从文本文件中读取,很多是这样的:

 Scanner reader = new Scanner(new FileInputStream("example.txt");

我知道我需要使用 Scanner 类来读取文件内容,然后(我认为使用 processCommandLine 方法)在图形面板上执行它们

到目前为止我的代码:(我已经调用了所有必要的类和方法,保存在一个单独的文件中)

import java.util.Scanner;

public class Assign1 {

   public final static void main(String[] args) {
      System.out.println("Let's draw something on the screen!");

      GraphicsScreen graphics = new GraphicsScreen();

      Scanner input = new Scanner(System.in); // used to read the keyboard

      String next; // stores the next line input
      String[] one;

      do {
         System.out.print("Enter a command (\"stop\") to finish : ");
         System.out.print("Type 'help' for a list of commands ");
         next = input.nextLine();
         one = next.split(" ");

         String command = one[0];

         if (next.contains("help")) {
            System.out
                  .println("Type 'move' followed by an X and Y co-ordinate to move the graphical pointer.");
            System.out
                  .println("Type 'circle' followed by a radius value to output a circle.");
            System.out
                  .println("Type 'line' followed by an X and Y co-ordinate to draw a line.");
            System.out.println("Type 'clear' to reset the graphical canvas.");
         }

         else if (next.contains("move")) {
            int x = 0;
            int y = 0;

            x = Integer.parseInt(one[1]);
            y = Integer.parseInt(one[2]);

            graphics.moveTo(x, y);
         }

         else if (command.equalsIgnoreCase("circle")) {
            int radius = 0;
            radius = Integer.parseInt(one[1]);
            graphics.circle(radius);

         }

         else if (command.equalsIgnoreCase("line")) {
            int x = 0;
            int y = 0;

            x = Integer.parseInt(one[1]);
            y = Integer.parseInt(one[2]);

            graphics.lineTo(x, y);

         }

         else if (next.contains("clear")) {
            graphics.clear();
         }

         else {
            System.out.println("error message");
         }

      } while (next.equalsIgnoreCase("stop") == false);

      System.out
            .println("You have decided to stop entering commands. Program terminated!");

      graphics.close();
   }
}

我需要包含的文本文件,例如:

移动 100 100 50圈 第 100 200 行

当我调用“load example.txt”操作时,该文本文件将被应用程序读取,并通过在图形画布上绘制指定的形状来执行其中的命令。

任何帮助或指导将不胜感激,我从事 Java 编程不到一年,并且一直在努力改进,因此欢迎任何建设性的批评。

【问题讨论】:

  • 有什么东西不能用吗?你有具体的问题吗?很难准确理解您的要求。
  • 我正在尝试创建命令“load”,该命令将从文本文件中加载命令,例如,如果用户键入“load example.txt”,则文本文件中的命令将被读取并在安慰。这些命令是 graphics.draw 命令,可将用户输入的指定形状呈现到图形画布上。

标签: java command-line java.util.scanner java-io file-io


【解决方案1】:

所以,这是一个不错的项目,因为它向您介绍了代码重用的概念和基本的 MVC(模型-视图-控制器)编程。基本上,如果您认为图形上下文是您的视图,并且您正在使用一组命令控制对该视图的访问,那么您的模型显然就是命令本身。您现在要做的是使从其他来源提供模型成为可能,同时保持程序中的所有其他内容完好无损。

因此,您的首要任务是创建这个可重用的“控制器”代码,它知道如何获取模型(命令),并使用它来影响视图(您的图形上下文)。你已经有了所有必要的逻辑,你只需要把它移到你想要的函数中:

public static void processCommandLine(String[] commandArgs, GraphicsScreen graphics) {
   if (commandArgs == null || commandArgs.length = 0 || commandArgs[0] == null) {
      System.out.println("Null command!");
   }

   String command = commandArgs[0];

   if (command.trim().equalsIgnoreCase("move")) {
      int x = 0;
      int y = 0;

      x = Integer.parseInt(commandArgs[1]);
      y = Integer.parseInt(commandArgs[2]);

      graphics.moveTo(x, y);
   }

   else if (command.trim().equalsIgnoreCase("circle")) {
      int radius = Integer.parseInt(one[1]);
      graphics.circle(radius);

   }

   else if (command.trim().equalsIgnoreCase("line")) {
      int x = 0;
      int y = 0;

      x = Integer.parseInt(commandArgs[1]);
      y = Integer.parseInt(comamndArgs[2]);

      graphics.lineTo(x, y);
   }

   else if (command.trim().equalsIgnoreCase("clear")) {
      graphics.clear();
   }
   else {
      System.out.println("Invalid Command!");
   }
}

有了这个,您可以将命令和图形屏幕传递给单个函数,它会“渲染”命令。现在,您想提供不同的方式来访问该函数。您的第一种访问方法是通过控制台向用户查询命令,然后执行它。但是您还希望能够从一个文件加载多个命令并一次运行它们。所以定义一个从文件中读取一堆命令的方法:

public static List<String> getCommands(String fileName) {
   if(fileName == null) return new ArrayList<String>(0);

   File file = new File(fileName);
   if(! (file.exists() && file.canRead()) {
      System.err.println("Cannot access file! Non-existent or read access restricted");
      return new ArrayList<String>(0);
   }

   List<String> commandLines = new ArrayList<String>(32);
   Scanner scanner = new Scanner(file);
   while(scanner.hasNextLine()) {
      commandLines.add(scanner.nextLine());
   }

   scanner.close();

   return commandLines;
}

现在,您只需要根据命令的来源是控制台还是文件来更改将命令传递给渲染函数的方式:

public final static void main(String[] args) {
   System.out.println("Let's draw something on the screen!");

   GraphicsScreen graphics = new GraphicsScreen();

   Scanner input = new Scanner(System.in); // used to read the keyboard

   String next; // stores the next line input
   String[] one;

   do {
      System.out.print("Enter a command (\"stop\") to finish : ");
      System.out.print("Type 'help' for a list of commands ");
      next = input.nextLine();
      one = next.split(" ");

      String command = one[0];

      if (command.trim().equalsIgnoreCase("help")) {
         System.out
               .println("Type 'move' followed by an X and Y co-ordinate to move the graphical pointer.");
         System.out
               .println("Type 'circle' followed by a radius value to output a circle.");
         System.out
               .println("Type 'line' followed by an X and Y co-ordinate to draw a line.");
         System.out.println("Type 'clear' to reset the graphical canvas.");
      }

      else if (command.trim().equalsIgnoreCase("load")) {
         List<String> commandLines = getCommands(one[1]);
         for (String commandLine : commandLines) {
            String[] commandArgs = commandLine.split(" ");
            processCommandLine(commandArgs, graphics);
         }
      }

      else if (command.trim().equalsIgnoreCase("stop")) {
         break;
      }

      else {
         processCommandLine(one, graphics);
      }
   } while (true);

   System.out
         .println("You have decided to stop entering commands. Program terminated!");
   graphics.close();
}

通过这些(微小的)更改,您现在可以从多个不同的来源获取命令,并将这些命令呈现到您的视图中。

【讨论】:

    猜你喜欢
    • 2015-04-01
    • 2022-12-17
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2012-09-19
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多