9

I have a program that uses multiple classes, I want the other classes to be able to access the same scanner that I have declared in the main class, I assume it would be done using some sort of get method, however I am unable to find any resources to help me.

Here are the Scanners that I have made in my main class:

  Scanner in = new Scanner(System.in);
            System.out.println("Enter a filename");
            String filename = in.nextLine();
            File InputFile = new File (filename);
            Scanner reader = new Scanner(filename);

The reader Scanner is the one I want to be able to access across the other classes that make up the program, can anyone give me some guidance on how I can do this? Thanks a lot for any help!

Samolivercz
  • 200
  • 2
  • 10
  • This would seem to be somewhat fragile as another `class` could `close()` the `Scanner` and break everything - no? Maybe you should read the file into memory? Or is it very large? – Boris the Spider Mar 28 '15 at 22:04
  • one option would be to declare reader as a static field in your main class – Sergey Pauk Mar 28 '15 at 22:04
  • another option would be to inject reader into other objects created from main class (assuming that main class is responsible for all the wirings) – Sergey Pauk Mar 28 '15 at 22:06
  • @SergeyPauk How would I go about doing this, as I have indeed used objects to call other methods in the other classes – Samolivercz Mar 28 '15 at 22:10

3 Answers3

5

Simply use public static final Scanner in = new Scanner(System.in); in you main class. After that you can call it from anywhere by MainClassName.in.

Also, be careful with arguments you pass to Scanner. I guess you wanted to put InputFile into Scanner, rather than filename =)

File InputFile = new File (filename);
Scanner reader = new Scanner(filename);
ar4ers
  • 740
  • 5
  • 19
  • So just do this with the Scanner that I have already defined, ie the "reader"? – Samolivercz Mar 28 '15 at 22:07
  • 1
    Yes. You can declare your local field `public static Scanner reader` in `MainClass`, initialize it from you code and use it from anywhere. But be careful with closing this resources. – ar4ers Mar 28 '15 at 22:09
  • I cannot seem to call the Scanner into another class using the way you suggested, I am getting an error : "not a statement" – Samolivercz Mar 28 '15 at 22:17
  • 1
    First, you need to declare local public static field in you `MainClass` like this: `public static Scanner reader;`. Second. You need to initialize it from your code, like this: `reader = new Scanner(filename);`. And, finally, you can call it from any other class like this: `MainClass.reader.nextLine()`. Beware of null pointers and resource closing. – ar4ers Mar 28 '15 at 22:21
  • Okay I've done this however now the Scanner is not correctly Scanning the file, before I had written a simple program that counted the number of spaces in a file however now it keeps saying there are 0 spaces, which is incorret – Samolivercz Mar 28 '15 at 22:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74016/discussion-between-samolivercz-and-ar4ers). – Samolivercz Mar 28 '15 at 22:33
  • I have just stumbled across another problem, it can only do one class at a time. – Samolivercz Mar 28 '15 at 23:21
1

Answering your question about dependency injection: here's a rough idea of dependency injection (via constructor):

public void wire() {
    ...
    Scanner reader = new Scanner(filename);
    ClassA objectA = new ClassA(reader);
    ClassB objectB = new ClassB(reader);
    ...
}

class A (class B would have a similar constructor):

public class ClassA {

    private Scanner reader;

    public ClassA(Scanner reader) {
        this.reader = reader;
    }
    ...
}

So the idea is that you create and wire up your objects in wire() method.

Sergey Pauk
  • 4,697
  • 3
  • 25
  • 40
0

There are so called design patterns that help you to deal with such daily issues. They show up best practises.

You are looking for something like a Singleton, an instance of a class that is unique to your software echosystem.

For your example, you can do something like this:

public class MyScanner{
   private static MyScanner instance = new MyScanner();
   private MyScanner(){
       // init the scanner
   }

   //Get the only object available
   public static MyScanner getInstance(){
      return instance;
   }

   public void read(File f){
      // read your file
   }
}
Remo Liechti
  • 142
  • 5