I'm writing a program where at one point, I need to print a String on a window using JOptionPane. The code for the line looks something like this:
JOptionPane.showMessageDialog(null, "Name: " + a.getName());
The getName function refers to the object a that i created that has a method that returns a String. However, when my code reaches this point, the program appears to enter some kind of infinite loop as the window never pops up and when using debug, it appears never-ending.
The main thing is, when I use getName, I am allowing the user the set this name with a different function earlier in the main driver.
getName() is basically one line, return name;
The code for my setName() function is basically:
Scanner a = new Scanner(System.in);
System.out.print("Pick a name: ");
name = in.nextLine();
a.close();
Name is a private variable in the class. The close() isn't necessary but I tried it to see if it had any effect.
What I did notice is that, if I use the above code, the window never pops up, and I get stuck in an infinite loop. However, if I simply change the name = line to anything, such as:
name = "foo";
The code runs smoothly, the window pops up, and I do not get stuck in a loop. Even if I do not input a name when the program prompts me to, resulting in a null String, the window still doesn't pop up. Can anyone help and advise me on why this is happening? Thanks.
Using Scanner operations creates a block in the WaitDispatchSuport class used by JOptionPane which checks non-dispatch threads are free from blocking IO. Calling Scanner.close() will not un-block the thread.
One solution is to call showMessageDialog from the EDT :
Scanner a = new Scanner(System.in);
System.out.print("Pick a name: ");
final String name = a.nextLine();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(null, "Name: " + name);
}
});
This code snippet can help you
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final String s = scanner.nextLine();
SwingUtilities.invokeLater(() -> {
JDialog dialog = new JDialog();
dialog.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(dialog, s);
});
}
Related
I'm trying to get a program together that reads integers that a user inputs. I've been reading about the scanner class which seems to be the most common way to do this in java. However when I copy+paste the examples given on sites like this one I get some kind of error that I have no idea how to fix. Which is frustrating because all the stuff posted is supposed to be completed code that shouldn't have problems!
An example of some code that's supposed to work:
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] arguments){
Scanner input = new Scanner(System.in);
String username;
double age;
String gender;
String marital_status;
int telephone_number;
// Allows a person to enter his/her name
Scanner one = new Scanner(System.in);
System.out.println("Enter Name:" );
username = one.next();
System.out.println("Name accepted " + username);
// Allows a person to enter his/her age
Scanner two = new Scanner(System.in);
System.out.println("Enter Age:" );
age = two.nextDouble();
System.out.println("Age accepted " + age);
// Allows a person to enter his/her gender
Scanner three = new Scanner(System.in);
System.out.println("Enter Gender:" );
gender = three.next();
System.out.println("Gender accepted " + gender);
// Allows a person to enter his/her marital status
Scanner four = new Scanner(System.in);
System.out.println("Enter Marital status:" );
marital_status = four.next();
System.out.println("Marital status accepted " + marital_status);
// Allows a person to enter his/her telephone number
Scanner five = new Scanner(System.in);
System.out.println("Enter Telephone number:" );
telephone_number = five.nextInt();
System.out.println("Telephone number accepted " + telephone_number);
}
}
Instead of the program running, it gives me two errors.
On the the line public class ScannerDemo { it gives me this error:
Illegal modifier for the local class ScannerDemo; only abstract or final is permitted
On the next line public static void main(String[] arguments){ I get this error:
The method main can not be declared static; static methods can only be declared in a static or top level type.
I have tried this with many different forms of scanners that are supposed to be all ready to go and get errors every time. What am I doing wrong? How can I fix it?
I am using Processing 3.
Please understand the difference between Java and Processing. Processing is its own language and editor with its own syntax rules, and you can't just copy-paste random Java code and expect it to work. You have to understand how Processing works, and then add code in a way that works in Processing.
Assuming you're using the Processing editor, then your main sketch file should not contain just a class, and it definitely shouldn't contain a main() method. It should contain a setup() and draw() function instead.
If you really want to use a class, then get rid of your main() method, encapsulate your logic in a function inside your class, and then add a setup() or draw() function that uses the class.
Or better yet, stop using a class and just use Scanner in your Processing code.
If you still can't get it working, please post a MCVE in a new question post, and we'll go from there. Good luck.
I believe as #Hovercraft has mentioned you just need this code in a file called ScannerDemo.java, Were guessing you have it in different file name.
Your class name and file name must be same. This is decision to first error.
public static void main(String[] arguments){
isn`t working because first error.
I want to take input form user, i am sure my code is right but it don't work at all. Please help is there any thing that i am doing wrong?
`public void edit() throws IOException {
sll.insertAfter();
System.out.println("Enter text: ");
String sen;
sen = keyboard.next();
Object obj = sen;
sll.put(obj);
}
when i execute this an error appears at this line
sen = keyboard.next();
import java.util.*;
public class Example
{
public static void main(String[] args)
{
Edit();
}
public static void Edit()
{
Scanner scan = new Scanner(System.in);
String random;
System.out.print("Please input some text: ");
random = scan.nextLine();
System.out.println("You entered: " + random);
}
}
I don't know what your main method looks like so I can only assume it's empty That being said I can tell you why your current code doesn't work based off of the information you've given us.
Your edit method is not static, and in this situation assuming you've laid out your program simillar to this it must be static as it is in my example.
You've not setup a scanner, or maybe you did outside of your edit method but failed to make it static?
Scanner scan = new Scanner(System.in);
Why are you using Object, if you want to edit the string just use a for loop and substring.
Object
If you provide us with more information, your full code and the error you're getting we can better help you!
I'm currently making a simple 2D RPG game in Java.
I got the render & tick methods done, the game is working fine.
Now I want to implement a console where the user can type some commands and interact with the map.
The problem is when I start the game, it is just freezing. The freeze is caused by Scanner(System.in).nextLine(). Here's my parser class :
import java.util.Scanner;
public class Parser
{
private CommandWords aValidCommands;
private Scanner aReader;
public Parser()
{
this.aValidCommands = new CommandWords();
this.aReader = new Scanner( System.in );
} // Parser()
public Command getCommand()
{
String vInputLine;
String vWord1 = null;
String vWord2 = null;
System.out.print( "> " );
vInputLine = this.aReader.nextLine();
Scanner vTokenizer = new Scanner( vInputLine );
if ( vTokenizer.hasNext() ) {
vWord1 = vTokenizer.next();
if ( vTokenizer.hasNext() ) {
vWord2 = vTokenizer.next();
}
}
if ( this.aValidCommands.isCommand( vWord1 ) ) {
return new Command( vWord1, vWord2 );
}
else {
return new Command( null, null );
}
} // getCommand()
} // Parser
and my tick function (which is called 60 times/sec)
Parser aParser = new Parser();
Command command = aParser.getCommand();
The game just freezes when it reaches the line "vInputLine = this.aReader.nextLine(); ". I have no idea why.
Also the parser class is working fine, I already made a console-based RPG using this class. I just don't know why it freezes when I try to implement it in my 2D game.
Any help would be appreciated.
Scanner.nextLine() is a blocking call. This means it will make the current thread wait until it returns a value. If you want to receive input through your scanner, aswell as possibly do other things at the same time, youll need another thread.
class Test {
private static Scanner scanner;
private static Thread inputThread = new Thread() {
public void run() {
scanner = new Scanner(System.in);
while(true) {
//scanner.nextLine();
}
}
};
public static void main(String[] args) {
inputThread.start();
//handle everything else on main thread
}
}
Because your scanner is receiving input on one thread, and possibly handling thr input on the other, you should start thinking of ways of passing values from thread-0 (the new thread) to the main thread (which calls the main method).
There are many ways of doing this, the most basic probably being adding input data to a list right when it comes in, then retreive it from the list on your other thread. But keep in mind, when using multiple threads, you need to worrry about memory inconsistancy. If both objects are trying to access the same object (in this case, the list containing the data), things might not calculate as expected. This is where synchronization come in: http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
It happens so because it actually does not finishes the line.
For example:
Code:
Scanner scan = new Scanner(System.in);
int a, b;
String name;
System.out.println("Enter two numbers");
a = scan.nextInt();
b = scan.nextInt();
System.out.println("Sum of " +a+ " and " +b+ " is " +(a+b));
System.out.println("Please enter your name");
name = scan.nextLine();
System.out.println(""+name);
Output :
Enter two numbers
1
2
Sum of 1 and 2 is 3
Please enter your name -> And it freezes here.
It happens as nextLine is still in waiting as this code (System.out.println(""+name);) just prints and does not finishes the line.
I have a class that creates multiple Integer objects and puts them into a LinkedList as shown below:
public class Shares<E> implements Queue<E> {
protected LinkedList<E> L;
public Shares() {
L = new LinkedList<E>();
}
public boolean add(E price) {
System.out.println("How many of these shares would you like?");
Scanner scanInt;
scanInt = new Scanner(System.in);
Integer noShares = scanInt.nextInt();
for (int i = 0; i < noShares; i++) {
L.addLast(price);
}
scanInt.close();
return true;
}
}
I have an application that scans for the input "add" from the console and if found, invokes the method add as shown below:
public class Application {
private static Scanner scan;
public static <E> void main(String[] args) {
Queue<Integer> S = new Shares<Integer>();
scan = new Scanner(System.in);
System.out.println("Please type add");
String sentence = scan.nextLine();
while (sentence.equals("quit") == false) {
if (sentence.equals("add")) {
System.out
.println("What price would you like to buy your shares at?");
S.add((Integer) scan.nextInt());
} else
System.exit(0);
sentence = scan.nextLine();
}
}
}
The application should allow the user to enter "add" as many times as they wish but the error "no line found" appears after the add method has been invoked.
I'm guessing this is because the Scanner in the method, has not been closed and then reopened when needed. Is this what is wrong with the program and if so, how would I go about fixing it?
Please note, this program is not finished, as I will be adding a selling method that sells these shares. That is why I am using a while loop.
Having multiple wrappers for any stream is a great way to really confuse yourself. I suggest you only ever wrap a stream once unless you really know what you are doing.
The simplest way to do this is to use a singleton in this case as it wraps another singleton (the best is to pass around the Scanner as an argument)
public class Application {
// use this Scanner in all you other code, don't create another one.
static final Scanner scan = new Scanner(System.in);
public static <E> void main(String[] args) {
Im guessing this is because the scanner in the method has not been closed
Once you close a stream it closes the underlying stream and you can't use it again. Only close System.in if you want to prevent it being used again.
how would I go about fixing it?
The best solution is to have all your Scanner use in one place, one method or one class. You have your main() do all the interaction with the user and pass the values to your data structure. Having objects which initialise themselves is a bad practice to get into and if you start doing this, it will plague you for the rest of your development days ;) (Seriously you will see this done again and again and its often a nightmare)
BTW Never exit a program without explanation. Calling System.exit(0); without even an error message is also a nightmare. I once worked on a project which has 260 calls to System.exit() often without an error message, you can imagine how much fun it is to diagnose a server just stopping for no apparent reason.
A first mistake is that this line of code
scanInt.close();
closes the System.in, not just the scanInt object. This means that after the first call to add, the scan object will only consume the input it already has and then you'll receive a NoSuchElementException: Remove this line.
Now, if you replace the last line you have with this
sentence = scan.nextLine();
System.out.println("sentence: \"" + sentence + "\"");
you will see that the last input you get before exiting is an empty String. So in the next loop you enter the else statement and your program stops execution. You can fix this problem by adding the following:
scan.nextLine(); // consume the first always empty String...
System.out.println("Please type add");
sentence = scan.nextLine(); // and then get the actual value
However, I will agree with Peter that you should not use multiple wrappers. Consider passing the Scanner object as an argument in the Shares class contractor.
Having multiple scanners (on same stream) is a very bad practice, because scanners consume the stream they share.
I've verified it while debugging the Scanner class source code, and there I’ve found:
a reference to the source input stream
a internal private buffer used to hold input.
So when a scanner instance consume its stream, basically it just read a bunch of bytes (1024) and the stream's position is moved ahead.
For example when the nextLine() method is invoket, behind the scenes the source.read() copy the result into the private buffer.
Obviously the state of other Scanner becomes corrupted (invalid).
Try to debug the Java source code yourself and/or look at the method Scanner.readInput().
I have a class called PlayGame, and in the main method I have this chunk of code:
public class PlayGame {
public static void main(String args[]) {
while (true) {
System.out.println("Where would you like your adventure to begin? (Enter a number)\n");
System.out.println("1. Play the Game\n2. Quit the Game");
Scanner userInput = new Scanner(System.in);
String userAction;
try {
userAction = userInput.nextLine().trim();
if (userAction.equals("1")) {
pressPlay();
} else if (userAction.equals("2")) {
System.exit(0);
} else {
System.out.println("Sorry, your selection wasn't valid.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
This is all fine, and when the user types 1, pressPlay() is called and it proceeds to the next method which does some stuff, mainly printing things to the screen. However, when I leave the pressPlay() method and return back to this main method, I start getting errors for reading the Input:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1516)
at PlayGame.main(PlayGame.java:17)
Can you clue me in into how I can get around this? Much appreciated!
EDIT - I just want it to return to the while loop in the main method and ask for 1 or 2 again, and take a valid 1 or 2. My code goes all the way through to userAction = userInput.nextLine().trim(); without waiting for anymore user input the second time round, after leaving the pressPlay() method.
EDIT - The pressPlay() method produces a grid that the player is able to move around in by typing particular commands. It has a while (true) { loop inside of it, as well as Scanner userInput = new Scanner(System.in); which takes the players input. If the player types quit, it calls a break out of the while loop and returns back to the main method, where the problem then arises.
I've managed to fix the issue.
In both my main method and my pressPlay() method, I was creating separate scanners taking input from System.in, and this was causing problems as it would no longer take input from the main method. Instead I took the Scanner out of the main method and put it after public class PlayGame {, and used this same scanner in both of my methods, rather than separate ones.
Thank you Jayamohan and Hossam for your input (: