1

I'm designing a print queue program that randomly generates print jobs and, depending on each individual print job's time, "prints" them out for a few seconds, suspending the main thread while another thread continually checks whether the user has pressed the enter key, generating a new print job to be added to the end of the queue in the main thread, or the "Q" button, signalling to end the program. Here is the relevant bit of code:

Scanner input = new Scanner(System.in);
AdPrint addPrint = new AdPrint();
addPrint.start();
for (int i = 0; i < printQueue.size(); i++)
{
    System.out.println("Printing " + i + " of " + printQueue.size()
            + "\n" + printQueue.get(i).getJobTime()
            + " seconds remaining."
            + "\nPlease press \"Enter\" to submit a new print"
            + " job or \"Q\" to quit.");

    addPrint.setI(i);
    addPrint.setInput(input);
    addPrint.setJobGen(jobGen);
    addPrint.setPrintQueue(printQueue);

    Thread.currentThread().sleep(printQueue.get(i).getJobTime() * 1000);

    printQueue.add(addPrint.getPrintQueue().get(i));
    addPrint.interrupt();


}

AdPrint (which I intentionally misspelled because of another problem I had in eclipse; I changed this class in DropBox on another computer and because there was a new copy, eclipse didn't recognize it as AddPrint for some reason so I had to rename the class to make it work, but that's not the problem here) is the separate thread that handles user input during the waiting period. Before I get into that, I just want to note that I originally had addPrint.start(); in the for loop with no interrupt method, but I realized what would happen is that java would then create infinitely many parallel threads in some sort of runaway feedback loop. I just thought that the values of addPrint (the instance) would just change but that was not the case. Now for AdPrint:

import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;

public class AdPrint extends Thread
{
    private Scanner input;
    private Random jobGen;
    protected LinkedList<PrintJob> printQueue;
    int i;
    private boolean run = true;
    private String choice = new String();

    public void run()
    {
        while (run)
        {

            if (input.nextLine() != null)
            {
                this.choice = input.nextLine();
                if (choice.equalsIgnoreCase("q"))
                {
                    for (int i = 0; i < printQueue.size(); i++)
                    {
                        System.out.println(printQueue.get(i).toString());
                    }
                }
                else if (choice.equalsIgnoreCase("\\n"))
                {
                    int printTime = jobGen.nextInt(10);
                    PrintJob job = new PrintJob();
                    job.setJobNum(i);
                    job.setJobTime(printTime);
                    printQueue.add(job);
                }
            }
            else if (input.nextLine() == null) {
                this.choice = input.nextLine();

            }

        }
    }

Now as it stands, I get the following NullPointerException at if (input.nextLine() != null):

Exception in thread "Thread-0" java.lang.NullPointerException
    at AdPrint.run(AdPrint.java:19)

I am new to threads and would like some help here after spending some time tinkering with this. Why am I getting this exception? How do I make this thread, addPrint, check to see if the user has requested another print job? EDIT:

I forgot to mention that I have getter/setter methods for AdPrint:

public void setInput(Scanner input)
{
    this.input = input;
}
CelineDion
  • 906
  • 5
  • 21

1 Answers1

2

In your main() you call start() before you call setInput:

Scanner input = new Scanner(System.in);
AdPrint addPrint = new AdPrint();
addPrint.start();

This means that the Scanner will still be uninitialized and therefore still be null. You must call setInput before you call start(). To test this you can add a print statement right before you call input.nextLine() to see that input is indeed null

GBlodgett
  • 12,704
  • 4
  • 31
  • 45