I'm writting a console interface for a small program I'm doing. I display something like this on the console:
Please select:
1)Add user
2)Delete user
3)Edit user
The method it self should listen for a button push, and if that button push is one of the digits 1,2 or 3 it should call some other method and clear all the text from the console. Something like this:
display the above info
if(button is not pushed)
do nothing
else if ( button == 1)
call method addUser and clear everything on the console, so that addUser
can display it's info
I know the question does not contain any code, but I have no idea how to do this. I know there should be some kind of button listener, but have no idea what to use and how. Any help is welcomed :)
You'll have to add an event listener to the button(s), and when that specific button is clicked, you call the required methods.
If you're not familiar with event listeners, I strongly suggest you check out https://docs.oracle.com/javase/tutorial/uiswing/events/intro.html and related pages on the official documentation portal.
Hope this helps.
This code can guide you to your solution. Use BufferedReader to read from console and check codes for buttons which was pressed, and depending on them, call the appropiate methods.
public static void main (String[] args) throws IOException {
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Hit 1, 2 or 3");
int buttonCode = bufferRead.read();
System.out.println("Code of button hit is: "+buttonCode);
//Button Codes for 1, 2 and 3 keys are 49, 50 and 51 respectively
if (buttonCode==49) {
//DO insert user
} else if(buttonCode==50) {
//Do delete
} else if (buttonCode==51) {
//Do Edit
} else {
System.out.println("Wrong button pressed");
}
}
Related
So I am trying to run a code, open a GUI window, choose between two buttons, which set a value and then with this value continue the rest of the code.
I have seen similar questions or Tutorials, but I do not find the suitable solution for my problem.
As I have already seen, JFrame, ActionListener and ActionEvent have to be used in order to make a GUI with a button.
An Object which extends JFrame and implements ActionListener is writen in the main method.
The Problem is, that the code writen in the main method opens the GUI window and continues to run. I just want that the code waits till the user clicks a button and then continue.
A sub-solution is, to write the code that I want in the actionPerformed method but:
The GUI window remains open, after the selection of a button
It makes no sense to me to write the rest of the code in the actionPerformed method.
Or to write a while loop until a button is clicked. A more sensible solution has to exist that I am not aware of or I do not understand the way this should work.
Here is a part of the code.
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == testStringA) {
setVariableTo = "testString_a";
try {
runMethodWithNewVariable(setVariableTo);
} catch (IOException e1) {
e1.printStackTrace();
}
System.exit(0);
} else {
setVariableTo = "project";
try {
runMethodWithNewVariable(setVariableTo);
} catch (IOException e1) {
e1.printStackTrace();
}
System.exit(0);
}
}
Instead of a JFrame, why don't you use a JOptionPane (showOptionDialog) with two buttons, "string A" and "project" instead of "Yes" and "No", for example?
JOptionPanes like "show Option Dialog" are intrinsically blocking. If you put one in your main() method, execution will "wait" for the user to select something in the dialog and the dialog will return an indicator to what was selected before execution in main() continues.
At the begining of your program, show a modal JDialog to the user! You can do this using JOptionPane.show() methods, like this:
String[] buttonTexts = {"first","second"}; //create the button texts here
//display a modal dialog with your buttons (stops program until user selects a button)
int userDecision = JOptionPane.showOptionDialog(null,"title","Select a button!",JOptionPane.DEFAULT_OPTION,JOptionPane.PLAIN_MESSAGE,null,buttonTexts,buttonTexts[0]);
//check what button the user selected: stored in the userDecision
// if its the first (left to right) its 0, if its the second then the value is 1 and so on
if(userDecision == 0){
//first button was clicked, do something
} else if(userDecision == 1) {
//second button was clicked, do something
} else {
//user canceled the dialog
}
//display your main JFrame now, according to user input!
You basically have two threads running - the main thread and the GUI thread. You don't explicitly create the GUI thread but it is there.
You can use a number of techniques to synchronise these two threads. The most basic is the good old synchronized, wait and notify. Something a Semaphore can also be used. In the main thread you would create the GUI and wait until a condition is met. In the GUI thread (i.e. actionPerformed) you would notify.
I would like to know the best way to approach what I am trying to achieve, I can't figure out the logical path I should take.
I have a JTextField and a JTextButton, when input is added to the JTextField and either enter or the button is pressed, it will display on the JTextArea. Now, what I want is to choose when and what the JTextArea and Button do.
For example I want default Enter & Button to display next append text in my code. Then when a case is presented I want the JTextField to only accept either int or string and then once completed, I want it to go back to default.
I don't know if what I am trying to do is logical or best practice...
The idea behind this is, I have a story text based gui game. I want it to display text to the JTextArea and when Enter or button is pressed to display the next line of text and when in the story it requires user input, the JTextArea will look for that input.
So far I have an EventListener and ActionListener which submits what I type from JTextField to JTextArea, but that is about it.
Thanks for your assistance! I have solved my issue, not sure if this is the "Best Solution". I combined your solution with a bit of tweaking.
In this instance, buttonState is an int which can be changed throughout my code by calling a constructor "setButtonState". I could have made buttonState a static to make things easier, but thought I could keep things clean.
enterButton.addActionListener(new ActionListener()
{ //This is used so when the enter screen button is pressed, it will submit text from text field to text area.
public void actionPerformed(ActionEvent e) {
String text = inputTextField.getText();
InputTextFieldEvent event = new InputTextFieldEvent(this, text);
if (buttonState == 0) //Displays all text in JTextField to JTextArea, mostly for testing purposes.
{
if (textInputListener != null) {
textInputListener.setInputListenerOccurred(event);
}
}
if (buttonState == 1) //Only accepts string for answer
{
if (inputTextField.getText().matches("[a-zA-Z]+"))
{
textInputListener.setInputListenerOccurred(event);
}
else
{
getAppendMainTextArea("You have entered an invalid input, only letters are allowed.");
}
}
if (buttonState == 2) //Only accepts int for answer
{
if (inputTextField.getText().matches("[0-9]+"))
{
textInputListener.setInputListenerOccurred(event);
}
else
{
getAppendMainTextArea("You have entered an invalid input, only numbers are allowed.");
}
}
}
});
Okay, so our assignment is to create a Guessing Game where the user inputs a number and the text foreground is supposed to change to either red if it is too high, blue if it is too low, or green if it is exact.
Our teacher has posted code that does that, and it is quite simple and I can understand it. Problem is, when I try to reformat it for what I need I get the JFrame, I get the text field where I can input it, but when I click submit it just like freezes. I suppose it has to do with how the action listener is written, but I am not sure.
Any help would be appreciate.
Here's my code, edited so just that specific part is shown"
button.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
userInput = keyboard.next();
if(Integer.parseInt(userInput) > randomNumber)
{
tf.setForeground(Color.red);;
}
else if(Integer.parseInt(userInput) < randomNumber)
{
tf.setForeground(Color.blue);
}
else if(Integer.parseInt(userInput) == randomNumber)
{
tf.setForeground(Color.green);
}
}
}
);
}
while(true)
That's the problem. Don't block the EDT (Event Dispatch Thread). The GUI will 'freeze' when that happens. See Concurrency in Swing for details and the fix.
First, I know that the way I'm trying to read the input is really bad, but I've tried to use Keylistener, and it doesn't work no matter what I try. I don't know what I'm doing wrong, so this is what I'm trying at the moment. I'm trying to call a thread in Controller.java from PreControls.java. If you could help me implement a working keylistener, it would me much appreciated, but I think fixing this thread problem will work too. I have tried debugging it, and the thread doesn't seem to start.
Code in PreControls.java:
Controller C = new Controller();
C.start();
System.out.print("Thread Should be started ");
Code in Controller.java:
package Game;
public class Controller extends Thread {
public void MyShipController(){
System.out.print("Thread Is started ");
String CharIn = "";
while(SpaceInvaders.GameOn = true){
CharIn = PreControls.ReadKeyPressed.getText();
if(CharIn.equalsIgnoreCase("a")){
SpaceInvaders.MyPos[0]--;
System.out.print("Move Left ");
}else if(CharIn.equalsIgnoreCase("d")){
SpaceInvaders.MyPos[0]++;
System.out.print("Move Right");
}else if(CharIn.equalsIgnoreCase(" ")){
//Fire Bullet
}
PreControls.ReadKeyPressed.setText("");
SpaceInvaders.MyShip.setLocation(SpaceInvaders.MyPos[0], SpaceInvaders.MyPos[1]);
jp1.repaint();
}
}
}
Sorry for not providing an SSCCEE. I'd need to send my whole project, and that defeats the point of doing a project.
ReadKeyPressed is the JTextArea that I'm having the letters inputted into.
jp1 is the JFrame
I'm working in the Eclipse IDE.
EDIT: forgot to add: After I start the applet, the Console reads "Thread Should be started" only, so it is a problem with the how I made the thread, or how I'm trying to create it.
Edit 2: My End goal is to detect when a (or left arrow) is pressed and move MyShip (a JLabel) to the left by 1 position and more it to the right by 1 position if d (or right arrow) is pressed.
Alright, I've accepted Williams answer as it made my thread run. And as suggested, I'm going to look into key bindings to detect when the keys are pressed. Thanks for all the help.
This = is an assinment operator.
while(SpaceInvaders.GameOn = true)
I think you wanted this ==
while(SpaceInvaders.GameOn == true)
Or better yet, and much cleaner, just
while(SpaceInvaders.GameOn)
Also, you should use key bindings instead of KeyListener, which my give you focus problems. See this answer for an example of using key bindings. Also see the tutorial
The code you've written in method MyShipController should be placed inside the run method of your thread. The run method is what the thread actually executes within.
As you've written it now, calling start on your Controller class will start your thread, and that thread will end immediately as its run method is empty.
public class Controller extends Thread {
#Override
public void run()
//public void MyShipController(){
System.out.print("Thread Is started ");
String CharIn = "";
while(SpaceInvaders.GameOn = true){
CharIn = PreControls.ReadKeyPressed.getText();
if(CharIn.equalsIgnoreCase("a")){
SpaceInvaders.MyPos[0]--;
System.out.print("Move Left ");
}else if(CharIn.equalsIgnoreCase("d")){
SpaceInvaders.MyPos[0]++;
System.out.print("Move Right");
}else if(CharIn.equalsIgnoreCase(" ")){
//Fire Bullet
}
PreControls.ReadKeyPressed.setText("");
SpaceInvaders.MyShip.setLocation(SpaceInvaders.MyPos[0], SpaceInvaders.MyPos[1]);
jp1.repaint();
}
}
}
However, I suggest your controller class extend Runnable rather than Thread.
so I have this part of my code (I cannot post everything because it's just too long and so far this is the only problem with it). Our professor assigned us to make our own Assembler just like MARIE and we are having a trouble with these lines of code:
else if(get.charAt(0)=='B')//input
{
inputfield.setEditable(true);
//INSERT LISTENER HERE!
AC.setText(inputfield.getText());
System.out.println(""+col);
//insert action here - HALP
}
The entire thing gets a value from a table sort of like an Instruction in Hex and if the Intruction starts with B like B000 then it will toggle the input textbox which is named inputfield. It works fine but we need to add a key listener in the part where it says //INSERT LISTENER HERE! for when the user will press enter the AC.setText(inputfield.getText()); will be executed. How should we do it? I mean we tried actionListener but it sort of stops the loop unless another button is clicked. We need another way that when the user presses enter it automatically resumes the execution.
Thank you.
Add action listener to textfield. ActionEvent will occur when you press Enter while editing in textfield.
JTextField field = new JTextField();
field.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// action to perform when one hits "Enter"
}
});