I need to get an input from keyboard using a JtextPanel, saving it on a string when I press enter, then use that string to do some action based on line given in input ( example "help" or "quit"). I got this in my KeyListener for JTextPanel:
...
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
inputString = textField.getText();
textArea.append(inputString + "\n");
textField.setText("");
}
}
....
, but I cant call this method directly. I would need something like
String input = processInput();
if((input).equals("help"))
............
else if ((input).equals("go"))
............
and processInput should be a method that waits for the (key== KeyEvent.VK_ENTER), like happens when you use the scanf in C or the bufferedReader in java, it waits for you giving a string from keyboard till you press enter.
EDIT
My app manages commands like that
while(!finished) {
finished = processInput()
}
processInput manages the command given in input. That's why I cant call processInput() from the keyListener
I hope i was clear, my english is so bad!
thanks
How about this approach, pretty simple.
KeyListener:
...
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
inputString = textField.getText();
textArea.append(inputString + "\n");
textField.setText("");
processInput(inputString); //crunch it
}
}
....
And elsewhere
public void processInput(String input) {
if((input).equals("help"))
............
else if ((input).equals("go"))
............
}
I believe you are stuck on the architectural design of an event-driven interface.
The idea here is that you don't go "waiting" for input or whatever. You set up the interface, attach the KeyListener (you do have an addKeyListener() somewhere, right...), and then you're done. You give up control flow, let your main method end, done.
When the user does something noteworthy, you then deal with it, so say you had a method processText(String text), you would, in your keylistener there, say processText(inputString);.
Thus, when the user enters something and hits enter, it starts executing in the keyListener, which passes control flow into the processText() method, which would do whatever it should do because of that text.
Related
I'm trying to validate/filter my jtextbox wwith this Regex:
^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$
I want to filter two names with one space.
Tried using keytyped and keyreleased, but it just does not work (won't let me write anything on the textbox) and e.consume() does not work.
boolean StrCheck(String Exp,String str) {
return Pattern.matches(Exp,str);
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getSource() == jTextField) {
String regexp = "^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$";
if (jTextField.getText().length() == 25) {
e.consume();
} if (StrCheck(regexp,jTextField.getText())){
}else {
e.consume();
}
I've been searching, but the only possible answer I got, was to create a Documentlistene BUT can't find any example or how actually do it and make it work.
Neither KeylListener, neither DocumentListener will work. In most of this kind of cases you would need to use a DocumentFilter. Before you do though, take a look on how to use formatted textfields. It might be enough for you. If it does not, this answer is what you are looking for.
In Java, I have checked the list of Virtual Key Codes, and there is not a VK for '<'. I have tried "VK_LESS" with my program (which sounds like it could be '<'), but that did not work either.
I am wondering if I have to check to see if the Shift key is pressed down, and then check to see if the Comma key is also pressed down, but I am not sure how to do that in a KeyHandler class, using a switch statement for the keyPressed method.
The KeyHandler keyPressed method will receive a KeyEvent. You can call isShiftDown() on that KeyEvent to see if the shift key is currently pressed.
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_COMMA && e.isShiftDown()) {
// do your thing!
}
}
You could also try doing:
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '<') {
...
}
}
Note the use of keyTyped rather than keyPressed. keyTyped triggers only when a key press outputs a character, rather than on every key press. This method would be more likely to work for other types of keyboard. But I haven't tried it, so I don't know if it would work at all.
I believe you'd want to use VK_LESS and VK_GREATER for "<" and ">", respectively.
You can use KeyEvents.getKeyChar() method
public void keyPressed(KeyEvent e) {
if (evt.getKeyChar().equals("<")) {
/*your code*/
}
}
So i'm trying to make a text game in java for a project and i have a problem in the main loop.I have the available commands in a hashmap named commands in the class CommandWords and i want to check if the user input exists in the hashmap and if it does to execute the associated object.But i can't exactly find a way.Here is my code.I understand it's probably an if but i don't know how to check.
public void play()
{
System.out.println("Welcome to the world of JZork " +player.name);
printWelcome();
boolean finished = false;
while (! finished) {
Command command = parser.getCommand();
if(command == null) {
System.out.println("I don't understand...");
}
}
}
It is possible to do it the way you said, but you would need to learn to use Java reflection. This isn't THAT hard, but you aren't going to like it.
if (command.equals("quit")) {
quit();
}
else if (command.equals("whatever")) {
whatever();
}
This isn't that elegant, but it's easy to implement.
I'm a beginner in Java programming & I am making an application requiring an object to move around a grid filled with squares.
The object should only move one square at a time and if the user wants to move into another square, they must press the key again. My move method is the following:
public void move() {
x += dx;
y += dy;
}
I am using the KeyListener interface to implement the keyPressed, keyTyped and keyReleased methods and I have conditions like the one in the fragment below inside KeyPressed
//KeyPressed
int c = e.getKeyCode();
if (c == KeyEvent.VK_UP) {
player.setDy(-5);
}
This allows the object to move freely. However, it will clearly continue to move as long as the UP arrow is pressed.
Is there any way to have to object move up by say -5 once and then stop even if the key is still pressed?
I am unsure whether I need to change my move method or the KeyListener methods to do this.
I hope that I have been clear enough as to what I'm asking and I'd highly appreciate any pointers.
first of all : you should use Synchronization if you call class-methods from within listeners like keyPressed or keyReleased - thats because your listener-method can be called from multiple threads so your class-method (player.setDy()) can (and will) be called in parallel - you will need to make sure that each call to setDy happens before the next one.
Also : keyTyped is much better in many cases : https://stackoverflow.com/a/7071810/351861
An example could look like this:
public void keyTyped(KeyEvent arg0) {
if(arg0.getKeyCode() == KeyEvent.VK_UP)
{
synchronized(player)
{
player.setDy(-5);
}
}
}
this will call setDy sequentially and reliably. Now all you need to do is to make sure that setDy works as intended, hence sets the position only once
easiest would be to add a boolean to indicate, that a moving key is pressed
class member : boolean movingKeyPressed = false
in key pressed :
if (movingKeyPressed) {
return;
} else {
// do stuff
movingKeyPressed = true;
}
in key released method :
movingKeyPressed = false;
I am sitting with a little problem here, and i has been searching for hours for any soultion now, but cant seem to find any, and i hope you can help me.
I have these methods:
public String getInput(){
//Wait here somehow
return "Whatever to return";
}
public void keyTrigger(KeyEvent event){
if(event.getCode().equals(KeyCode.ENTER)){
String[] getInput = gameLog.getText().split("\n");
input = getInput[getInput.length - 1]; //Input is a variable in the class
//Tell the getInput() to continue from where i waited
}
}
So if anyone can tell me how the make the first method wait for a response from the other method, i woul be very happy, because none i have tried so far has worked
EDIT...
Sorry guys, i have missed out on some details.
1st: I am developing a GUI in JavaFX, and the gameLog variable is a textarea, and thats why im splitting the String on linebreaks.
2nd: when i call getInput() i want it to wait for the user to press enter, then get the input variable
Your immediate request would be satisfied by a CompletableFuture:
public String getInput(){
final CompletableFuture<String> fut = new CompletableFuture<>();
commonFuture = fut;
return fut.join();
}
In the above, you need to provide a variable commonFuture which is accessible both from the above code and from your KeyEvent listener, and will serve as the point of contact between these two pieces of code. In the listener you would say
commonFuture.complete(getInput[getInput.length - 1]);
and at that point the join call in getInput() would complete, returning this value.
However, I urge you to seriously think through your current design, which demands such synchronous blocking. You may be able to rework so that getInput is replaced by a callback method which gets invoked when the input value is available.
I don't really understand your issue here, from common logic I guess your getInput() should read from command line and return the value as String. You don't need to write any special code for it, for reading from command line you should use BufferedReader, see the example below.
public String getInput(){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
try{
line = reader.readLine();
}catch(IOException e){
e.printStackTrace();
}
return line;
}
Also this part of your code, input = getInput[getInput.length - 1]; I don't see a point of getInput.length - 1 because getInput() will return a whole string so you don't need to trim it unless you explicitly want to do it. So you can just write input = getInput();, with assumption that variable input is of type String.
Instead of trying to block until the variable changes, you should use a StringProperty and register listeners with it.
Here's some skeleton code:
private final StringProperty input = new SimpleStringProperty();
public StringProperty inputProperty() {
return input ;
}
public final String getInput() {
return inputProperty().get();
}
public final void setInput(String input) {
inputProperty().set(input);
}
// event handler (I'm assuming):
public void keyTrigger(KeyEvent event){
if(event.getCode().equals(KeyCode.ENTER)){
String[] getInput = gameLog.getText().split("\n");
inputProperty().set(getInput[getInput.length - 1]);
}
}
Now you can have code execute when the input is changed:
inputProperty().addListener((obs, oldInput, newInput) -> {
// newInput contains the new value set to the input property....
});
The Properties and Bindings tutorial has more details on using JavaFX properties.