This site requires JavaScript, please enable it in your browser!
Greenfoot back
joeenglish
joeenglish wrote ...

2016/1/6

Keyboard Input

joeenglish joeenglish

2016/1/6

#
Can anybody out there let me know whether, and if so how, Scanner can be used in the Greenfoot environment to receive keyboard input? I am seriously considering using Greenfoot to teach OOP and Java and would like to build a small bank of simple I/O examples first. The following simple example does not work as intended. Sometimes it hangs (I'm thinking on the line that instantiates the class). Sometimes it prompts for a number and then hangs. Any help would be appreciated.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;
import java.lang.System;
 
/**
 * Write a description of class Main here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class Main
{
    /**
     * Constructor for objects of class Main
     */
    public Main()
    {
        Scanner input = new Scanner( System.in );
        System.out.println("Enter a number");
        int n1 = input.nextInt();
        System.out.printf("Number is %d\n", n1);
    }
}
danpost danpost

2016/1/6

#
First, I want you to be clear as to how greenfoot operates. Your main method is intended to execute straight through, once. Your line 19, for one thing, requires an int already be in the 'input' (which is not even being checked for -- using the 'hasNextInt' method call). For this int value to be there, however, it would take some time for the keystrokes to be executed. Greenfoot was built so that time would be broken down into instantaneous steps. Each act cycle in a running greenfoot program represents a "frame" in time. Keyboard and mouse actions will only be detected during a running program. Therefore, you need to create a Main object in the 'act' method of your World subclass and follow its creation with stopping the program and then test it by compiling and starting the project:
1
2
3
4
5
public void act()
{
    new Main();
    Greenfoot.stop();
}
I am not saying that it will now work as you want; but, it should be closer, for now. I am doing some testing myself and will post my finding when finished.
danpost danpost

2016/1/6

#
The code I gave in my last post will not work either. Like I said, however, it will be closer to what is wanted. The Main object should be created in the constructor of the world and the actions of the Main object should be controlled via 'act' methods. I do not think that you can run a Scanner on System.in within Greenfoot. I suggest that you make use of the Greenfoot class methods 'isKeyDown' and 'getKey' for keyboard input within greenfoot. Again, this will require that greenfoot run the scenario to work. You could explain what type of simple I/O operations you had in mind and possibly we could help you with the coding.
joeenglish joeenglish

2016/1/6

#
Thank you danpost. I am a reasonably experienced Java developer but completely new to Greenfoot. So far I love its potential for use as a teaching tool but before delving into the world of Crabs and OOP I would like to provide my students with a number of solutions to simple I/o problems such as those listed..... Write a Program to compute and display the arithmetic mean of two numbers entered by the user WAP a program that prompts a user to enter a value and display the converted value in some other units (e.g. Celsius -> Fahrenheit) WAP to do some tax/interest calculation based on parameters provided by the end-user etc., etc. Thanks again. I really do appreciate your time on this.
danpost danpost

2016/1/6

#
Shall I presume that you will want the programs to be converted to application jar files when completed?
joeenglish joeenglish

2016/1/6

#
No. I am happy to run everything from within the Greenfoot environment.
danpost danpost

2016/1/6

#
joeenglish wrote...
No. I am happy to run everything from within the Greenfoot environment.
Okay. I was thinking you could have a simple world just so the project can compile and an object that can manually be created and the parameters (the user input values) entered into the input dialog box. For the Celsius to Fahrenheit example: the world:
1
2
3
4
5
6
7
public class Main extends greenfoot.World
{
    public Main()
    {
        super(0, 0, 0);
    }
}
the conversion object
1
2
3
4
5
6
7
public class CelsiusToFahrenheit
{
    public CelsiusToFahrenheit(double celsius)
    {
        System.out.println(celcius+" degrees Celsius is about equal to "+(c*9/5+32)+" degrees Fahrenheit");
    }
}
Do not run the scenario -- just right click on the 'CelsiusToFahrenheit' class and select 'new CelsiusToFahrenheit(double celsius)'
danpost danpost

2016/1/7

#
Another way follows. This one uses swing operations for input and output and only uses one world class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import javax.swing.JOptionPane;
 
public class CelsiusToFarenheit extends greenfoot.World
{
    public CelsiusToFarenheit()
    {
        super(0, 0, 0);
        String text = "Enter amount in celsius";
        String input = JOptionPane.showInputDialog(text);
        Double c = Double.parseDouble(input);
        Double f = c*9/5+32;
        text = c+" degrees Celsius is about "+f+" degrees Farenheit";
        JOptionPane.showMessageDialog(null, text);
    }
}
joeenglish joeenglish

2016/1/7

#
Thanks. This is a help but it's not what I'm looking for. My students are coming from Python where when they can use the built-in function input to return data entered by a user and save that data in a variable. For example,
1
2
3
4
c=input("Enter the Centigrade value you wish to convert")
c=float(c)
f=9/5*c+32
print("There are ", f, "degrees Fahrenheit in", c, "degrees Centigrade")
I'm hoping to make the transition from Python to Java as simple as possible. I have been investigating the 'isKeyDown' and 'getKey' class methods with no luck yet. I've even tried the following code which, when run just displays Key is null. Any ideas why? The documentation suggests that the call will block until the user enters something.
1
2
3
4
5
6
7
public void getInput()
{
    Greenfoot gf = new Greenfoot();
    String s = gf.ask("Enter a value");
    System.out.printf("Key is %s\n", s);
    return;
}
joeenglish joeenglish

2016/1/7

#
Oops. The call to 'ask' in my previous post does actually work - I just needed to have it invoked via the scenario. (I was invoking from the new class instance menu option instead.) I think I can progress now. Thanks again for your help.
danpost danpost

2016/1/7

#
Oh, yeah. I had forgotten about the 'ask' method (I am using a slightly older version of greenfoot in which that method was not yet available in). One thing, however, is that you do not need to create an instance of the Greenfoot class to use the 'ask' method. In fact, all the methods in the Greenfoot class are static methods (you call the methods on the class itself):
1
String s = Greenfoot.ask("Enter a value");
Another thing is that you never need to use a return statement at the end of a 'void' method. Now, your 'getInput' method will take the input value (as a String) and output the text with the input to the terminal. However, upon exit from the method, that string is lost -- it is not being saved to a field and it is not being returned to the method that calls the 'getInput' method. I am not familiar with Python other than what bit of code you have shown above. However, the following may be more like what you are wanting:
1
2
3
4
String input = Greenfoot.ask("Enter the Centigrade value you wish to convert");
float c = Float.parseFloat(input);
float f = c*9/5+32;
System.out.println("There are ", f, "degrees Fahrenheit in", c, "degrees Centigrade");
You need to login to post a reply.