I am trying to make it so that instead of hitting the enter key in my java program to make the enter action occur, I can instead hit the enter key while a custom method is running. At this point, I have looked into Hashmaps but am pretty confused if this going to do what I want. Any help would be greatly appreciated. It seems like this should be an easy thing to do, but for some reason I am just not getting a solution to it.
So, I am thinking my code will be something like this. Essentially, I am making a game of Hot Potato and I need to have the players take turn entering a character (e, d, and c for team 1 and o, k, and n for team 2). This will be involving a GUI interface as well. A have a while loop that will end once a timer reaches zero. What I would like is for the players to be able to put in a letter into a JTextField in the GUI and then simply press spacebar (as they will be sharing a keyboard). Once they enter the right letter (I made it randomized), they can hit spacebar and they will have "tossed the potato" to the other player.
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
KeyEvent.VK_ENTER;
}
}
I am working all of this out of the actionPerformed(ActionEvent ev) method. The fuller code looks like this. The if statement is commented out because I would like the game to start when the main button is pressed, but right now I get a ton of compilation errors when I uncomment the JButton and have it working with the String text that is the dialogue from the text you enter into a JTextField.
public void actionPerformed(ActionEvent ev) {
Object eventSource = ev.getSource();
String text = entryText.getText(); // text entered into JText
//JButton eventButton = (JButton) eventSource;
System.out.println(text);
//if (eventButton.equals(main))
{
int totalTime = 1000*(HotPotato.randNum());
long startTime = System.currentTimeMillis();
System.out.println(totalTime/1000);
Boolean p1Start = false;
String input = "";
while (System.currentTimeMillis() - startTime <= totalTime)
{
p1Start = !p1Start;
char a = HotPotato.randLetterBoth(p1Start);
String aString = String.valueOf(a);
while (!input.equals(aString))
{
System.out.print(aString); // temporary, shows test letter
input = theKeyboard.next();
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
KeyEvent.VK_ENTER;
}
}
}
}
if (p1Start)
{
System.out.print("Team 2 Wins!");
}
else
{
System.out.print("Team 1 Wins!");
}
setLabels();
myPicture.makeHotPotatoOn(myHotPotato.state());
myPicture.repaint();
}
}
Related
So I have a GUI with a JTextField which is meant to first take user inputs for a "main menu", and once a menu command is entered perform a series of actions. For example, in the following block, I take an action and use a switch/case to get what menu selection the user entered, but now i want to take additional inputs inside this action. In the current code, the actionlistener will get stuck in an infinite loop because it doesn't wait for NEW input when I use ".getText()". Is there a way to make this work (keeping in mind I need to parse each input for format)? Or is my understanding of ActionListener thoroughly flawed?
Here is a small snippet to give some context:
#Override
public void actionPerformed(ActionEvent ae){
while(command < 1 || command > 8){
commandStr = textField.getText();
try{
command = Integer.parseInt(commandStr);
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Invalid Command!");
command = 0;
}
}
switch(command){
case(1): //Add new book
while(!BS.validateFormat(bookType, BS.IF_BT)){
textArea.setText("Enter the book type by number");
textArea.append("1: Book 2: Textbook 3: Workbook");
try{
bookType = Integer.parseInt(textField.getText());
} catch(Exception e){}
}
I am new to Java and am having trouble on getting some code working. I have a GUI with the letters A-Z. After a button click, I want to ask for a Keyevent to do a couple of things:
Only allow you to select a letter. Upper or lower case. If not wait for a response that is correct.
Then check the alphabet list to see if it has been pressed before. If it has then ask for another letter
If a new character is entered then strike it out on the alphabet and run the method that follows
Disable any further keys being pressed.
I have tried the following code:
private static void spinGame(){
switch (wheelResult)
{
case "1'
...
break;
case "2":
...
break;
default:
System.out.println("...");
newPhrase.gameB();
scene2.setOnKeyPressed((KeyEvent event) -> {
if (event.getText().isEmpty())
return;
char pressed = event.getText().toUpperCase().charAt(0);
userGuess=event.getText().charAt(0);
if ((pressed < 'A' || pressed > 'Z'))
return;
Text t = alphabet.get(pressed);
if (t.isStrikethrough())
return;
// mark the letter 'used'
else{t.setFill(Color.BLUE);
t.setStrikethrough(true);
System.out.println(userGuess);
}
int letterCount;
if ((userGuess == 'a') || (userGuess == 'e') || (userGuess == 'i') || (userGuess == 'o') || (userGuess == 'u')){
playerScores[currentPlayer] -= 250;
System.out.println("£250 docked from score for vowel use");
}
It goes wrong from here. I dont want keys to be pressed again and I don't the following method should run:
letterCount = newPhrase.makeGuess(userGuess);
...my method....;
})
I have no idea how to fix it. I tested and recorded the User guess is being selected but it does not proceed the method after and the key in input doesn't stop. I also feel that my coding for the alphanumeric stuff is wrong.
Your solution already caters for your requirements as you check for a valid letter and whether or not it is strike-through in your alphabet. So until they provide an unused letter, nothing will happen aside from the conditions being checked each time
To stop the key input I'd recommend using a ToggleButton or something similar so the user has to indicate when they want to guess. This means you can use other text based controls with a decreased probability of striking off letters in your alphabet accidentally. When they guess an unused letter you can reset the button, otherwise keep checking their input for a valid letter
Your method relating to the scoring system is only called when a vowel has been entered by the user. You can separate the score and input logic by creating a method and only providing valid unused letters to it, handling the game's scoring/phrase lookup logic there:
private void checkPhrase(char chosenLetter){
//Handle the Hangman-like logic here
boolean isVowel = vowels.indexOf(chosenLetter) >= 0;
if (isVowel) {
System.out.println("User provided a vowel");
}
}
This will make it easier to read and maintain your code as once you've determined that the letter hasn't been used you will only need to call it once. Whereas before you might have had duplication as it looks like it was only been executed for vowels
Below are the changes I made to your code when testing in case they are of use:
public class AlphabetGuess extends Application {
private String vowels = "AEIOU";
#Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Text> alphabet = FXCollections.observableArrayList();
for(char letter = 'A'; letter <= 'Z'; letter++){
alphabet.add(new Text(String.valueOf(letter)));
}
HBox alphabetContainer = new HBox(5);
alphabetContainer.setAlignment(Pos.CENTER);
alphabetContainer.getChildren().addAll(alphabet);
ToggleButton button = new ToggleButton("Listen for guess");
button.setSelected(false);
VBox root = new VBox(20, alphabetContainer, button);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 500, 100);
scene.setOnKeyPressed(event -> {
//If the button isn't selected, don't process the input
if (event.getText().isEmpty() || !button.isSelected()) {
return;
}
char userGuess = event.getText().toUpperCase().charAt(0);
if ((userGuess < 'A' || userGuess > 'Z')) {
return;
}
//This will cause letters A-Z to become 0-25 allowing the list to be indexed
Text text = alphabet.get(userGuess - 'A');
if (text.isStrikethrough()) {
System.out.println(userGuess + " has already been guessed");
return;
} else {
text.setFill(Color.BLUE);
text.setStrikethrough(true);
checkPhrase(userGuess);
}
//Un-select button which will cause this event to reject incoming keys
button.setSelected(false);
});
primaryStage.setScene(scene);
primaryStage.show();
}
private void checkPhrase(char chosenLetter){
//Handle the Hangman-like logic here
boolean isVowel = vowels.indexOf(chosenLetter) >= 0;
if (isVowel) {
System.out.println("User provided a vowel");
}
//ToDo: Implement
}
}
So I understand how to make it so when a user presses a button, the count goes up, but how would I make it so it displays the amount of times the button has been pressed in a different way. For example, if the user pressed the button 3 times, it would say 123, instead of 3.
This is my current method with does it a conventional way,
public void actionPerformed(ActionEvent event) {
count++;
label.setText("Pushes: " + count);
}
So I'm thinking maybe I can make it so it loops through each posted value and displays that?
Initialise countStr globally, than on the button click append the count with StringBuilder like:
StringBuilder countStr= new StringBuilder();
public void actionPerformed(ActionEvent event) {
count++
countStr.append(count);
label.setText("Pushes: " +countStr);
}
i have an issue with my code where i can only increment the last input data value, this code it linked to another class where i have song list etc. however im tryin to create a playlist where when i press play it increments the playcount of all the songs in the playlist. however my problem is once i add the songs to a playlist, when i press play it only increments the last track in entered into the text field. for example i type "01" then add then i type "02" and add, but it only increments track 2 (hence the last track i added) instead of incrementing both 1 and 2. im very new to java so forgive me if this seems trivial, and thanks in advance.
public void actionPerformed(ActionEvent e) {
if (e.getSource() == add) {
String key = trackNo.getText();
String name = LibraryData.getName(key);
if (name == null) {
playcount.setText("No such track number");
} else {
playcount.append("\n" + name + " - " + LibraryData.getArtist(key));
}
}
if (e.getSource() == reset) {
playcount.setText("");
}
if (e.getSource() == play) {
String key = trackNo.getText();
LibraryData.incrementPlayCount(key);
}
}
}
I found some good Q/A here on my problem but couldn't find the right one.
I have a barcode reader that reads barcode and sends scanned code as keyboard input. It is alright I can catch input easily
browser.addKeyListener(new KeyAdapter() {
#Override public void keyPressed(KeyEvent e) {
if(e.keyCode >=48 && e.keyCode <=57) {
System.out.println("number caught");
}
}
});
But I will have more inputs in my application so I need to know if it is send by barcode reader or by keyboard.
I think it can be achieved by adding some timer in code that verifies how long is some "sequence" reading.
I just can not figure it out, (I mean logic behind it), I am missing piece of logic.
User is typing some info, (alpha numerical)
user desides to use barcode reader to read barcode
I tried timer e.g
if(System.currentTimeMillis() - lastPressProcessed ??? 500) { after keyListener is triggered but I think I am missing something.
sidenote:
USB barcode reads code fast so keystrokes are emulated really fast est whole barcode is written in about 1 second + carry /r/n (also enter is pressed).
sidenote2: barcodes are going to be different in length so I can not read just some length in short time and decide wether it is user input or barcode input (max numbers read 13 + enter).
sidenote3: I have no input field for barcode I am trying to achieve running it on "background".
I am seeking logic/pseudocode suggestions on topic.
related topics that are really close to mine are here, and here
Thank you.
edit
After deep tought I found out the solution I'll keep this Q here just for another users that might find this usable.
solution
--moved to answer + edited
This code coveres everything I wanted to achieve, it reads just numbers (actualy numbers that are under F keys, not numbers that are on numpad, I had problem with it because scanner is keyboard dependant so I made function signsToNumbers() that converts signs !##$%^&*() to numbers 1234567890. I may change this function because every key on keyboard has its own unique identifier + modifier, it seems that scanner sends also SHIFT modifier to the application but that is not as problem as it seems I'll just match e.keyCode.
The code below works as:
waits for number input otherwise does nothing
if 1st number is inserted it is looping in if condition until either 200ms is reached or '\r\n` is received
sends data to server via URL
code
#Override public void keyPressed(KeyEvent e) {
if (timer == true && System.currentTimeMillis() - lastTimer < 200) {
if(e.keyCode >=48 && e.keyCode <=57) { //number pressed
lastTimer = System.currentTimeMillis();
myString = myString + Character.toString(e.character);
}
if(e.keyCode == SWT.CR) {
myString = signsToNumbers(myString);
newUrl = browser.getUrl()+ "/newcode/" + myString;
browser.setUrl(newUrl);
text.setText(newUrl);
System.out.println(myString);
System.out.println("barcode read");
myString = "";
timer = false;
lastTimer = 0;
}
}else{
if(e.keyCode >=48 && e.keyCode <=57) {
lastTimer = System.currentTimeMillis();
timer = true;
myString = Character.toString(e.character);
}
myString = "";
lastTimer = 0;
}
}
});
Here you can download my solution:
http://jhead.hu/resource/java/general/BarcodeReader.java
The following code sample shows you, how to use it. When a new barcode is identified, an ActionEvent is generated and you can get the barcode via the getActionCommand() method. If the panel is not active you can send the characters further to the focus manager.
The only problem is that my barcode scanner sends the characters too fast so the character bits are sometimes mixed. I've got no better solution yet.
public class PanelWithBarcodeReading extends javax.swing.JPanel implements ActionListener {
private BarcodeReader barcodeReader = new BarcodeReader();
public PanelWithBarcodeReading() {
initComponents();
barcodeReader.addActionListener(this);
barcodeReader.setParent(this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(barcodeReader);
}
#Override
public void actionPerformed(ActionEvent e) {
if (SwingUtilities.getWindowAncestor(this).isActive()) {
System.out.println("BARCODE='" + e.getActionCommand() + "'");
} else {
barcodeReader.dispatchLastBarcodeAsKeyEvents();
}
}
...
}