Print to the console while user is typing - java

In Java, when you print to the console while a user is typing. It will destroy what is being typed. Let's say I have a server set up, and you can run commands from the server. Then this is what it might look like.
I'm trClient connected to server
ying to typMessage received from client
e a command
Is there a way to get around this? To have the text be printed on the line above the user is typing on. If you've ever ran a Minecraft server, you might know what I'm talking about. It would look something like this.
Since Minecraft is made using Java, I know that this is possible, but I haven't been able to figure out a way to do it.

Maybe you could do it like this.
You have one while loop with a value of true.
Everything that the user enters is entered in the ArrayList and every time the user enters something that list is printed.
If you want it to print only the entered message, you can empty it each time you print the list.
There you could use LinkedList where when you drag all the variables from the list, it remains empty.

If you want to use a library that gives terminal support, you can use com.googlecode.lanterna for your own terminal where you can set where you want to show the inputs given by the user. You can add the dependency to your program:
<!-- https://mvnrepository.com/artifact/com.googlecode.lanterna/lanterna -->
<dependency>
<groupId>com.googlecode.lanterna</groupId>
<artifactId>lanterna</artifactId>
<version>3.1.1</version>
</dependency>
You can use the Terminal of this library and do such manual positioning of input and printed test like the way you want the interface.
Have a our on this page and browse more to gather knowledge on lanterna.
I've added a very basic code for reading input and showing that on the gui:
public static void main(String[] args) {
try {
int row = 5, col = 5;
Terminal terminal = new DefaultTerminalFactory().createTerminal();
Screen screen = new TerminalScreen(terminal);
TextGraphics tg = screen.newTextGraphics();
screen.startScreen();
KeyStroke key;
List<Character> string = new ArrayList<>();
while (true) {
System.out.println("reading input");
key = terminal.readInput();
if (key != null && key.getCharacter() != null) {
System.out.println("Key not null: " + key.getCharacter());
// you can add more keypress checks, they have a lot of enums for this
if (key.getKeyType() == KeyType.Enter) {
String str = string.stream().map(String::valueOf).collect(Collectors.joining());
System.out.println(col + " " + row + " " + str);
tg.putString(col, row, str);
string.clear();
} else if (key.getKeyType() == KeyType.Escape) {
break;
} else {
string.add(key.getCharacter());
}
} else {
System.out.println("Null input");
break;
}
screen.refresh();
}
screen.stopScreen();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}

Related

Problem with Switch statement in for loop for turn based RPG battle in java

Essentially, I've put a switch statement in a for loop. It has not been working as intended. I think it has something to with the break statement.
What I want the loop to do is go to the first element in the array list, execute code based on the 'action' String, then go to the next until the list ends. However, it seems that whenever I run the program it only executes the code in the first index. Here is some code for the BattleManager class:
Scanner input = new Scanner(System.in);
String cmd;
String[] dtct;
Arraylist<BattleAction> turns = new ArrayList<BattleAction>();
public void handle() {
cmd = input.nextLine();
dtct = (cmd.split());
switch(dtct[0]) {
case "attack":
turns.add(new BattleAction("playerattack"));
getenemyaction();
turnsequence();
break;
case "defend":
getenemyaction();
turnsequence()
}
}
public void getenemyaction() {
turns.add(new BattleAction("enemyattack"));
}
public void turnsequence() {
Collections.sort(turns);
print("Size: " + turns.size())
for (int i = 0; i != turns.size(); i ++) {
switch(turns.get(i).action) {
case "playerattack":
playerattack();
break;
case "enemyattack":
enemyattack();
break;
}
}
}
public void playerattack() {
print("Player attack");
}
public void enemyattack() {
print("Enemy attack");
}
When I run the program here is the output I am getting with the attack command:
attack
Size: 2
Player Attack
However when I use the defend command the output is:
defend
Size: 1
Enemy Attack
The desired output would be for turnsequence() to go through turns and do check action for the desired code to be executed, like this:
attack
Size: 2
Player Attack
Enemy Attack
I have done my best to cut out as much unnecessary information at possible to prevent confusion. Thank you so much for reading my post! I really appreciate your help!

For loop runs through an ArrayList of objects and checks their names to display them in GUI but Error Message still shows up

I've decided to programm a search system for finding students and teachers in a school via GUI. It is an OOP and need some tweaking here and there, but there is one issue which doesn't seem logical to me. When I'm searching for a teacher, I have to type there name or surname into a JTextField and press the Search button which runs a method that loops through an ArrayList of teacher-objects and checks if their names match with the one in the Textfield. Then it checks if these teachers have multiple subjects and grades and it goes through nested if-statements. After the teacher is found, their information is displayed on a GUI with several Texfields. Theoretically if the name I typed into the TextField doesn't match one from the teacher objects, a Error Message should pop-up saying the teacher I'm looking for isn't in the system. But even though I type in the correct name and get all the information displayed, it sends me to the Error Message everytime. I tried to fix it with a break statement but that didn't work either. Can someone please help me with this.
Here is the code I'm talking about:
public void lehrerSuche()
{
String lehrername = tfSuchfeldLehrer.getText();
for(int i = 0; i < td.getFachliste(0).getListenLaengeLehrerListe();i++)
{
if(td.getFachliste(0).getLehrerliste(i).getName().equals(lehrername) || td.getFachliste(0).getLehrerliste(i).getNachname().equals(lehrername))
{
if(td.getFachliste(0).getLehrerliste(i).isMehrerefaecher() && td.getFachliste(0).getLehrerliste(i).isMehrereklassen())
{
tfNameLehrer.setText(td.getFachliste(0).getLehrerliste(i).getName() + " " + td.getFachliste(0).getLehrerliste(i).getNachname());
tfKürzelLehrer.setText(td.getFachliste(0).getLehrerliste(i).getKuerzel() + ".");
tfKlasse_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getKlasse().getBezeichnung());
tfKlasse_2Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getKlass2().getBezeichnung());
tfFach_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getFach().getFachbezeichnung());
tfFach_2Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getFach2().getFachbezeichnung());
}
if(td.getFachliste(0).getLehrerliste(i).isMehrerefaecher() == false && td.getFachliste(0).getLehrerliste(i).isMehrereklassen())
{
tfNameLehrer.setText(td.getFachliste(0).getLehrerliste(i).getName() + " " + td.getFachliste(0).getLehrerliste(i).getNachname());
tfKürzelLehrer.setText(td.getFachliste(0).getLehrerliste(i).getKuerzel() + ".");
tfKlasse_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getKlasse().getBezeichnung());
tfKlasse_2Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getKlass2().getBezeichnung());
tfFach_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getFach().getFachbezeichnung());
}
if(td.getFachliste(0).getLehrerliste(i).isMehrerefaecher() && td.getFachliste(0).getLehrerliste(i).isMehrereklassen()==false)
{
tfNameLehrer.setText(td.getFachliste(0).getLehrerliste(i).getName() + " " + td.getFachliste(0).getLehrerliste(i).getNachname());
tfKürzelLehrer.setText(td.getFachliste(0).getLehrerliste(i).getKuerzel() + ".");
tfKlasse_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getKlasse().getBezeichnung());
tfFach_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getFach().getFachbezeichnung());
tfFach_2Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getFach2().getFachbezeichnung());
}
if(td.getFachliste(0).getLehrerliste(i).isMehrerefaecher() == false && td.getFachliste(0).getLehrerliste(i).isMehrereklassen()==false)
{
tfNameLehrer.setText(td.getFachliste(0).getLehrerliste(i).getName() + " " + td.getFachliste(0).getLehrerliste(i).getNachname());
tfKürzelLehrer.setText(td.getFachliste(0).getLehrerliste(i).getKuerzel() + ".");
tfKlasse_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getKlasse().getBezeichnung());
tfFach_1Lehrer.setText(td.getFachliste(0).getLehrerliste(i).getFach().getFachbezeichnung());
}
break;
}
else
{
switchPanels_3(panelErrorLehrer);
}
}
}
I've uploaded my project to GitHub. Methods and variables are written in German, so I'm really sorry if you can't understand what I have written. If u have questions please hit me up. I use Eclipse to code.
This link should direct you to my GitHub:
https://github.com/Gonzo-CR/Home-Projects.git
If the link doesn't work, look for Gonzo-CR on GitHub and check out my Home-projects repository where I uploaded all the files.
For better undestanding these are the Object oriented classes:
Person(Abstract)
Schueler
Lehrer
Fach
Schulklasse
Spezial
Sprecher
GUI classes:
Suchsystem
Testdaten(A class which generates all my objects)
The problem is likely that if td.getFachliste(0).getLehrerliste(i).getName().equals(lehrername) is not true the very first time the loop runs, switchPanels_3(panelErrorLehrer); will be triggered - regardless of whether the condition is met on a later iteration of the loop.
What you need is to check a sentinel value after the loop finishes - e.g.:
bool lehrerGefunden = false;
for(int i = 0; i < td.getFachliste(0).getListenLaengeLehrerListe();i++){
if(td.getFachliste(0).getLehrerliste(i).getName().equals(lehrername) || td.getFachliste(0).getLehrerliste(i).getNachname().equals(lehrername)){
//etc.
lehrerGefunden = true;
break;
}
}
if(!lehrerGefunden){
switchPanels_3(panelErrorLehrer);
}
That way, you check every entry in the list before deciding whether to show the error.

How can I add new data to an Arraylist & How can I remove user input duplicates?

What i am shooting for is to be able to take the input from my text field in my GUI and put it into an ArrayList. Then I need to check the array and see if I already have the Integer in the array. If so I need to remove both Integers so the Integer is no longer inside the array. I also need to be able to add the Integer if it is not a duplicate to the ArrayList.
The purpose of this is to be able to have users sign in with a number. The vision I have is for them to put their unique number in when they sign in or sign out (Like a time clock). If their number is not in the array, they are signing in. If their number is in the arraylist then they are signing out.
This is what i have for code so far, i am getting a problem with signing out. It keeps sending the second value in the array back as the only one able to sign out. I have tried fixing it and can't seem to figure out what is wrong. Let me know if it would be more helpful if i posted my whole program or if this code snippet is enough to figure it out.
Thanks,
private void btnSignInActionPerformed(java.awt.event.ActionEvent evt) {
// Get data from form and put it into an Array List
Integer txtUserSignInName = Integer.valueOf(txtUserSignIn.getText());
ArrayList<Integer> userSignInNumber = new ArrayList();
userSignInNumber.add(12345678); //sample data
userSignInNumber.add(55489563); //sample data
userSignInNumber.add(26489564); //sample data
userSignInNumber.add(78654865); //sample data
userSignInNumber.add(txtUserSignInName);
// Setting up HashSet so no duplicate data
Set<Integer> hashSet = new HashSet<>();
hashSet.addAll(userSignInNumber);
userSignInNumber.clear();
userSignInNumber.addAll(hashSet);
// Other settings needed
SimpleDateFormat df = new SimpleDateFormat("hh:mm:ss a");
String time = df.format(new Date());
if ((txtUserSignIn.getText() != null && txtUserSignIn.getText().isEmpty())) {
String userSignInErrorMessage = "Sorry, Please Try Again";
JOptionPane.showMessageDialog(new JFrame(), userSignInErrorMessage, "Incorrect Sign In",JOptionPane.ERROR_MESSAGE);
//setting focus
txtUserSignIn.setText("");
txtUserSignIn.requestFocus();
} else {
for(int i = 1; i < userSignInNumber.size(); i++) {
// If number is already in array, remove it
if(txtUserSignInName.equals(userSignInNumber.get(i))) {
userSignInNumber.remove((Integer)txtUserSignInName);
System.out.println(txtUserSignInName + " has signed out");
txtLoggedInUsers.append(txtUserSignInName + " has signed out at " + time + "\n");
break;
} else { // If number is not in the array, add it to the array
System.out.println(txtUserSignInName + " has signed in");
txtLoggedInUsers.append(txtUserSignInName + " has signed in at " + time + "\n");
break;
}
}
System.out.println(userSignInNumber);
}
}
Lists are not really suitable for what you are trying to do. You would be better off using one of the Set interface implementations. Sets provide fast contains()/add()/remove() methods that you can use, without generally having to iterate over all elements manually in a loop. And if you do need to quickly iterate over all elements for some reason, then a LinkedHashSet would work just fine. For example:
Set<Integer> signedIn = new LinkedHashSet<>();
...
if (signedIn.add(loginNumber)) {
// The set was modified, therefore this is a new login
} else {
// The number was already present, log-off the user.
signedIn.remove(loginNumber);
}
...
if (signedIn.contains(loginNumber)) {
// Allow the user to...
} else {
// Error, user not signed in
}
There are a number of problems with your implementation.
The loop starts at 1 when array indices start at 0, so you are skipping the first entry.
Then you always break out of the loop straight away after checking the 2nd item and so don't check any others.
A better approach would be to use a Set, not just to remove duplicates, but as a primary way to store who is signed in. Then you can check if a number is in the set easily with the contains method so you don't need to loop through manually (which means you don't have to deal with the problems associated with removing items from a list while you are looping through it).

How to write code that if something happens nothing else happens afterward?

Lets say if the last level of a game is beaten then you dont show a dialog box asking if the player wants to go on to the next level, but rather to the mainmenu. SO basically if something happens the things that are supposed to happen afterward dont.
private void submitButtonActionPerformed(java.awt.event.ActionEvent evt) {
final ImageIcon pokeballIcon = new ImageIcon("C:\\Users\\bacojul15\\Pictures\\pokeball5.gif");
final ImageIcon pokemoneggIcon = new ImageIcon("C:\\Users\\bacojul15\\Pictures\\nidoking.gif");
final ImageIcon pokemonredIcon = new ImageIcon("C:\\Users\\bacojul15\\Pictures\\red.gif");
String userAnswer = answertextArea.getText().trim();
if (userAnswer.equalsIgnoreCase(answers.get(questionNumber))) {
answerLabel.setText("Correct");
levelScore ++;
triviagui.totalScore ++;
} else {
answerLabel.setText("Incorrect");
}
answertextArea.setText("");
questionNumber++;
if(questionNumber == questions.size()){
JOptionPane.showMessageDialog(null, "Your score for this level was : " + levelScore + " out of 10. \n Your total score is " + triviagui.totalScore, "Scores",JOptionPane.INFORMATION_MESSAGE, pokeballIcon );
if(difficulty == 3){
JOptionPane.showMessageDialog(null, "Good job you beat the game! \n Your total score was " + triviagui.totalScore + " out of 30.", "Thanks for playing!", JOptionPane.INFORMATION_MESSAGE, pokemonredIcon);
triviagui.questionFrame.setVisible(false);
triviagui.mainFrame.setVisible(true);
}
int leveloptionPane = JOptionPane.showConfirmDialog(null,"Would you like to go on to the next level?" , "Next Level?", JOptionPane.YES_NO_OPTION, levelScore, pokemoneggIcon);
if(leveloptionPane == JOptionPane.YES_OPTION){
difficulty++;
triviagui.questionFrame.setVisible(false);
triviagui.questionFrame=new QuestionFrame(difficulty);
triviagui.questionFrame.setVisible(true);
}
if(leveloptionPane == JOptionPane.NO_OPTION){
triviagui.questionFrame.setVisible(false);
triviagui.mainFrame.setVisible(true);
}
return;
}
updateQuestionScore();
}
You simply want to do:
if(something happens) {
return;
}
If you want to jump out from method use
return;
example of something like that:
public void myMethod(){
if(mynumber==5){
doThis();
}else{
return;
}
/*
*do something else <- this wont be executed if number doesnt equal 5
*cause we are already out of method.
*/
}
If you dont want to jump out from whole method bud only form part of it for instance loop.
break;
example of that:
public void myMethod(String[] stringArr){
for(String s:stringArr){
if(s.equals("hello")){
break; //get me out of this loop now !
}else{
s+="alriight";
}
}
}
doSomethingElse();//this will be executed even if you go thru break; you are still inside method dont forget.You are just out of loop
}
There are better uses for that maybe examples aint best bud you will understand how to use it form this:).
When you use break or return.In eclipse for instance you will be shown Where you actually exit. it will highlight "}"
There are several ways to do this:
You can return from a method.
You can break to exit a loop or continue to start the next iteration of the loop.
You can use an 'else' to only execute other code if the first section did not execute.
You can set a boolean flag variable and then check for that elsewhere in your code.
Depending on what you are trying to do each of these is sometimes the best way, sometimes not the best way.

Error checking if statements

I am doing some practice work by expanding on a homework project I recently wrote. This is not for a grade, but I want to add some error checking to my code.
The program requires you to enter a name, select from a dropdown, select from a listbox and to select a radio button. My goal is to populate an error messagebox if any of the required items is blank.
The code I have so far for the error checking is below, but Im not sure how to take the individual lacking item and populate that to the message box since all of the error checking is in a single "if" statement.
Error checking code:
// Listener to handle the print button.
class ButtonListener implements ActionListener
{
ButtonListener() {}
public void actionPerformed(ActionEvent e)
{
JFrame frame1 = new JFrame("Show Message Dialog");
// Checks for required entries
if (error == 0 || name == "" || flag == 0)
{
JOptionPane.showMessageDialog(frame1,
"You must complete the form: " + missing, "ERROR",
JOptionPane.ERROR_MESSAGE);
}
else
{
// Get values from fields
setText();
System.out.println("Passenger's Name: " + name + "\n");
System.out.println("Age Group: " + ageValue + "\n");
for (int i = 0; i < value.length; i++)
{
System.out.println("Destination: " + value[i] + "\n");
}
System.out.println("Departure Day: " + day + "\n");
}
}
}
Thanks!
It looks like they can actually have multiple things wrong, so why only show one? I'm normally a C# dev so I'm not going to try to get the syntax right on typing this myself, but here's the concept:
Create a collection of some sort, like a list of strings.
Make 3 if statements, one for each of those errors, and put the field
names in for each one that fails. if (name.isEmpty()) {
errorList.Add("name"); }
Check to see if the count of items in the list is greater than 0. If
it is throw your error and put the name of the bad fields from the
collection into the string that you generate.

Categories