Using Scanner to take input from two objects of the same class - java.util.scanner

I have a problem with functionality of my simple program I am making at the moment. I am trying to create two objects, each of them is asking user to provide a name and then choose from few options, by using Scanner. First object, monster of class createMonster, is asking user to provide information through Scanner. However, while creating second object monster2 of class createMonster, program does not asking for user input.
Do I need to do some changes in my class CreateScanner or is it a bigger problem?
public class MainClass {
public static void main(String[] args) {
RandomMonsterGenerator monster = new RandomMonsterGenerator();
monster.createMonster();
RandomMonsterGenerator monster2 = new RandomMonsterGenerator();
monster2.createMonster();
}
}
RandomMonsterGenerator code:
public class RandomMonsterGenerator {
// Objects
Attributes attr = new Attributes();
CreateScanner createScanner = new CreateScanner();
// Variables
String monsterName;
String attributesValues;
int choice;
// Main method for generating monster
public void createMonster() {
attr.generateAttributes();
generateName();
chooseClass();
System.out.println("Generating random stats:");
attributesValues = attr.toString();
System.out.println(attributesValues);
createScanner.closeScanner();
}
// Generating monster name
private void generateName() {
System.out.println("Name your monster: ");
monsterName = createScanner.stringInput();
System.out.println("Name of the monster: " + monsterName);
}
// Choosing a class
private void chooseClass() {
System.out.println("Class descriptions: ");
System.out.println("Warrior has +2 to Strength and +2 to Condititon.");
System.out.println("Thief has +2 to Dexterity and +2 to Charisma.");
System.out.println("Mage has +2 to Intelligence and +2 to Wisdom.");
System.out.println("**************************************************");
System.out.println("Choose your class from following options: ");
System.out.println("Warrior, press '1'");
System.out.println("Thief, press '2'");
System.out.println("Mage, press '3'");
choice = createScanner.intInput();
switch(choice) {
case 1:
Warrior warrior = new Warrior(attr);
System.out.println(monsterName + " is a warrior.");
break;
case 2:
Thief thief = new Thief(attr);
System.out.println(monsterName + " is a thief.");
break;
case 3:
Mage mage = new Mage(attr);
System.out.println(monsterName + " is a mage.");
break;
default:
System.out.println("No option choosen.");
break;
}
}
}
CreateScanner code:
import java.util.Scanner;
public class CreateScanner {
Scanner sc = new Scanner(System.in);
public String stringInput() {
String input = "";
if (sc.hasNextLine()) {
input = sc.nextLine();
}
return input;
}
public int intInput() {
int input2 = 0;
if (sc.hasNextLine()) {
input2 = sc.nextInt();
}
return input2;
}
public void closeScanner() {
sc.close();
}
}

Two things.
First, don't close the scanner until you're done with it. This closes the System.in
as well and as soon as you do that you won't be getting anymore input. This is why it just skips over the second RandomMonsterGenerator input.
Second, only create one Scanner and pass it to your RandomMonsterGenerator as an argument. This keeps things simple.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
RandomMonsterGenerator monster = new RandomMonsterGenerator(scanner);
RandomMonsterGenerator monster2 = new RandomMonsterGenerator(scanner);
}

Related

cannot find symbol for method in a class of array objects

I have a class Card to represent a deck of cards as an array of objects Card[], with methods to shuffle and print the deck. I have a test class TestCard to generate the deck (in TestCard) then shuffle and print the deck (as methods in Card.) I get the message
TestCard.java:17: error: cannot find symbol
mydeck.writeDeck();
^
symbol: method writeDeck()
location: variable mydeck of type Card[]
Here is the Card.java code.
public class Card {
public static final int NUMCARDS=52;
String suit;
int value;
String name;
public Card() {
suit = " ";
value = 0;
name = " ";
}
public Card(String suit, int value, String name) {
this.suit=suit;
this.value=value;
this.name=name;
}
public void setData(String su,int va, String na) {
suit = su; value = va; name = na;
}
public void writeDeck(Card[] cards) {
int count=0;
for (Card mycard : cards ) {
System.out.print(mycard.name+mycard.suit);
count++;
if (count==13) {
System.out.println();
count= 0;
}
}
System.out.println();
}
private void swap(Card[] arr,int i, int j) {
Card temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public void shuffle(Card[] carr) {
int index;
for (int i=NUMCARDS-1; i>0; i--) {
index = (int) (Math.random() * (i+1));
swap(carr, i, index);
}
}
}
and here is TestCode.java code
public class TestCard {
public static final int NUMCARDS=52;
public static void main(String args[]) {
Card[] mydeck = new Card[NUMCARDS];
for (int i=0; i<NUMCARDS; i++) {
int j=i%13+1;
String v;
v = Integer.toString(j);
String s;
if (i<13) s="C";
else if (i<26) s="D";
else if (i<39) s="H";
else s="S";
mydeck[i] = new Card(s,j,v);
}
System.out.print(mydeck[5].suit+mydeck[5].value);
mydeck.writeDeck();
mydeck.shuffle();
mydeck.writeDeck();
}
}
I have spent 8 hours trying various fixes, using tutorials from various we sites, but have not succeeded.
mydeck.writeDeck(); is trying to call the writeDeck() method of the instance mydeck. But if you look at the code:
Card[] mydeck = new Card[NUMCARDS];
my deck is not a Card object, it's an array of Card objects. According to your code, you must pass in a Card[] as a parameter.
Turn .writeDeck(Card[] cards) into a static method:
public static void writeDeck(Card[] cards)
and then invoke the method like so:
Card.writeDeck(mydeck)
Marvin's answer worked like a charm. According to the Oracle documentation, for a method to work on an array of objects, the method must be defined for the object. But you can't just simply say arrayvar.method(). You have to say Objectclass.method(arrayvar). Good news is you can pass two array variables if you are working with both.

Sending an object to host from a client

I cant seem to find the problem on the code but it the server is not displaying anything. It displays the catch. Client seems find and it sets the players name and score and sends it but I cant seem to find the issue on this one why server is not displaying the name and score.
Here is my Client:
public class Client
{
private static final int BUFSIZE = 64;
public static void main(String[] args) throws IOException
{
try
{
int scores;
Scanner in = new Scanner(System.in);
Socket clntSock = new Socket("127.0.0.1", 6000);
System.out.println("What is the filename?");
String input = in.nextLine();
Scanner fileInput = new Scanner(new File(input));
ObjectOutputStream out = new
ObjectOutputStream(clntSock.getOutputStream());
Player playerObject = new Player();
playerObject.setName(fileInput.nextLine());
System.out.println(""+playerObject.getName());
for (int i = 0; i < 5; i++)
{
scores = Integer.parseInt(fileInput.nextLine());
playerObject.setScore(scores);
System.out.println(""+playerObject.getScores().get(i));
}
out.writeObject(playerObject);
in.close();
fileInput.close();
out.close();
clntSock.close();
}
catch ( UnknownHostException ex )
{
System.out.println( "Unknown host" );
}
}
}
and my Host:
public class Host
{
private static final int BUFSIZE = 64;
public static void main(String[] args) throws IOException
{
// Step 1: Create a ServerSocket.
ServerSocket servSock = new ServerSocket(6000);
PrintStream fileOut = new PrintStream("Datafromclient.txt");
try
{
// Step 2: Wait for a connection..
Socket clntSock = servSock.accept();
// Step 3: Get input and output streams.
System.out.println("Step 3: Get object input stream.,");
ObjectInputStream objectIn = new
ObjectInputStream(clntSock.getInputStream());
Player playerObjct = (Player)objectIn.readObject();
System.out.println("The name of Player: "+playerObjct.getName());
for(int i=0; i <5; i++)
{
System.out.println("Scores:"+playerObjct.getScores().get(i));
}
objectIn.close();
clntSock.close();
// Step 5: Close connection
objectIn.close();
clntSock.close();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
System.err.println(e);
}
}
}
My player class:
public class Player
private String name;
private int playerId;
private int bestScore;
private static int numberOfPlayers = 0;
private ArrayList<Integer> scores = new ArrayList<Integer>();
/* -------------- CONSTRUCTOR --------------------------------------
*/
public Player()
{
numberOfPlayers++;
playerId = numberOfPlayers;
}
public Player(String name)
{
this.name = name;
}
//Create set method for setName
public void setName(String name)
{
this.name = name;
}
//Create set method for setScores
public void setScore(int score)
{
scores.add(score);
}
//Create get method for getPlayerId
public int getPlayerId()
{
return this.playerId;
}
//Create get method for getName
public String getName()
{
return this.name;
}
//Create get method for getScores
public ArrayList<Integer> getScores()
{
return scores;
}
//Create get method for getBestScore
public int getBestScore()
{
calculateBestScore();
return bestScore;
}
//Method to expose the value of numberOfPlayers
public static int getNumberOfPlayers()
{
return numberOfPlayers;
}
//Create get method for calcualteAverage
public double calculateAverage()
{
Integer sum = 0;
if(!scores.isEmpty())
{
for(Integer score : scores)
{
sum += score;
}
return sum.doubleValue() / scores.size();
}
return sum;
}
public void calculateBestScore()
{
bestScore = Collections.max(scores);
}
}
I was missing
import java.io.Serializable;
public class Player implements Serializable
now its working.

BlueJ Scanner won't launch class

import java.util.Scanner;
public class Homework
{
static String aString;
public Homework()
{
}
public static void Check(String args[])
{
Scanner s = new Scanner(System.in);
aString=s.next();
boolean palinder;
palinder=true;
for(int i=0;i!=aString.length()/2;i++)
{
if (aString.charAt(i)!=aString.charAt(aString.length()))
{
System.out.println("The word "+aString+" isn't a palinder");
palinder=false;
}
}
if (palinder)
{
System.out.println("The word "+aString+" is a palinder");
}
}
}
I wrote this program which is supposed to determine whether a word
is a palinder or not, but the problem is that when I launch it in
blueJ the program won't load, its like I looped. I can't figure out
what did I write wrong.
Here is the solution. You need to change your current code significantly.
import java.util.Scanner;
public class Homework
{
public Scanner s;
public String wordToTest;
public void HomeWork()
{
s = new Scanner(System.in);
wordToTest = s.next();
Check(wordToTest);
}
public static void Check(String testWord)
{
String aWord = "palinder";
if (aWord.equals(testWord))
{
System.out.println("The word "+testWord+" is a palinder");
}
else
{
System.out.println("The word "+testWord+" isn't a palinder");
}
}
}
Hope it will help.

Using a user input to make an object in Java

Is there a way for me to take a string input from scanner and create a new object with that string entry? Such as:
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("What is your name: ");
String name = input.nextLine();
ListOfNames name = new ListOfNames();
}
Note that in the last line the "ListOfNames name = new ListOfNames();" I want the new object to be the string that the variable "name" holds.
I want to do this so that after the object is made I can add it to an array then be able to search the array later after inputting multiple names in for the one I need.
There is probably a way to do this with the arrays class but I am new and unfimliar with the class. Any help would be fantastic! Thanks!
You could do...
public class Test {
public static void main(String[] args) {
ArrayList<String> listOfNames = new ArrayList<String>();
Scanner input = new Scanner(System.in);
System.out.println("What is your name: ");
String name = input.nextLine();
listOfNames.add(name);
}
Just add the received input from Scanner to listOfNames array list.
Or if you are really need to use another Object...
public class Name {
String value;
public Name(String value) {
this.value = value;
}
}
public class Test {
public static void main(String[] args) {
ArrayList<Name> listOfNames = new ArrayList<Name>();
Scanner input = new Scanner(System.in);
System.out.println("What is your name: ");
String nameValue = input.nextLine();
Name n = new Name(nameValue);
listOfNames.add(n);
}

How to apply mask formatting to TextField?

I am creating some forms and I need to create masks and validation for some fields.
Is it implemented in anyway in JavaFX?
My example of the mask.
Using:
<MaskField mask="+7(DDD)DDD-DDDD"/>
<MaskField mask="AA DDD AAA" placeholder="__ ### ___"/>
etc
Restricting input from Richard's fxexperience post:
TextField field = new TextField() {
#Override public void replaceText(int start, int end, String text) {
// If the replaced text would end up being invalid, then simply
// ignore this call!
if (!text.matches("[a-z]")) {
super.replaceText(start, end, text);
}
}
#Override public void replaceSelection(String text) {
if (!text.matches("[a-z]")) {
super.replaceSelection(text);
}
}
};
If you want to create your use a mask and create your own control, take a look at Richard's MoneyField, which also includes a sample project and source. Along the same lines there are controls to restict input to Integers, Doubles or formatted web colors (e.g. #rrggbb) in the fxexperience repository. All of these follow a common theme where they subclass Control, provide some properties to be get and set which define the public interface and then also define a private backing skin which handles rendering of the UI based on the values set through the public interface.
I had the same needs. I created this field, called it SpecialTextField, and pushed into GitHub. Example also there. Hope this help.
NOTE: this only works correctly with JRE 1.8.0_25 or lower. With JRE 1.8.0_48 or 0_51, the caret position is always set to 0 after each character input.
No, this is not implemented in standard JavaFX. You need to use some library or do it yourself.
This is my implementation of static mask for text fields. It works for date, phone and other types of static masks:
/**
* Adds a static mask to the specified text field.
* #param tf the text field.
* #param mask the mask to apply.
* Example of usage: addMask(txtDate, " / / ");
*/
public static void addMask(final TextField tf, final String mask) {
tf.setText(mask);
addTextLimiter(tf, mask.length());
tf.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
String value = stripMask(tf.getText(), mask);
tf.setText(merge(value, mask));
}
});
tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(final KeyEvent e) {
int caretPosition = tf.getCaretPosition();
if (caretPosition < mask.length()-1 && mask.charAt(caretPosition) != ' ' && e.getCode() != KeyCode.BACK_SPACE && e.getCode() != KeyCode.LEFT) {
tf.positionCaret(caretPosition + 1);
}
}
});
}
static String merge(final String value, final String mask) {
final StringBuilder sb = new StringBuilder(mask);
int k = 0;
for (int i = 0; i < mask.length(); i++) {
if (mask.charAt(i) == ' ' && k < value.length()) {
sb.setCharAt(i, value.charAt(k));
k++;
}
}
return sb.toString();
}
static String stripMask(String text, final String mask) {
final Set<String> maskChars = new HashSet<>();
for (int i = 0; i < mask.length(); i++) {
char c = mask.charAt(i);
if (c != ' ') {
maskChars.add(String.valueOf(c));
}
}
for (String c : maskChars) {
text = text.replace(c, "");
}
return text;
}
public static void addTextLimiter(final TextField tf, final int maxLength) {
tf.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
if (tf.getText().length() > maxLength) {
String s = tf.getText().substring(0, maxLength);
tf.setText(s);
}
}
});
}
See also:
JavaFX 2.2 TextField maxlength
Supported by current javafx-2 platform by default - No, but go through this link , it has many insights and sample code for Form validation in javaFX
public class NumberTextField extends TextField {
private int maxLenght;
public NumberTextField(int maxLenght) {
super();
this.maxLenght = maxLenght;
}
#Override
public void replaceText(int start, int end, String text) {
if (validate(text)) {
super.replaceText(start, end, text);
}
}
#Override
public void replaceSelection(String text) {
if (validate(text)) {
super.replaceSelection(text);
}
}
private boolean validate(String text) {
if (this.getText() != null) {
}
boolean status = ("".equals(text) || text.matches("[0-9]"));
if (this.getText() == null) {
return status;
} else {
return (status && this.getText().length() < maxLenght);
}
}
}
In some cases I would validate the text property:
myTextField
.textProperty()
.addListener(
(obs, oldVal, newVal) ->
{
if(!newVal.matches("\\d+"))
textField.setText(oldV);
});
Unlucky: textField.setText(oldV); will enter the same function again, testing unnecessarily if oldVal matches.
If the TextField becomes a value that doesn't matches before this listener is added to the TextField, enter a not matching new value will cause a loop!!!
To avoid this, it will be safer to write:
String acceptableValue = "0";
myTextField
.textProperty()
.addListener(
(obs, oldVal, newVal) ->
{
if(!newVal.matches("\\d+"))
textField.setText(oldVal.matches("\\d+") ? oldV : acceptableValue);
});
I wrote a class that extends the TextField and apply the mask.
package com.model;
import java.text.NumberFormat;
import java.util.Locale;
/**
* ATENTION
* DO NOT FORGUET TO IMPORT IN FXML
* <?import com.view.TextFieldMoney?>
*
* */
import javafx.scene.control.TextField;
public class TextFieldMoney extends TextField {
private int maxlength;
private String valor = "";
public TextFieldMoney() {
this.maxlength = 11;
}
public void setMaxlength(int maxlength) {
this.maxlength = maxlength;
}
#Override
public void replaceText(int start, int end, String text) {
// Delete or backspace user input.
if (getText() == null || getText().equalsIgnoreCase("")) {
valor = "";
}
if (text.equals("")) {
super.replaceText(start, end, text);
} else{
text = text.replaceAll("[^0-9]", "");
valor += text;
super.replaceText(start, end, text);
if (!valor.equalsIgnoreCase(""))
setText(formata(valor));
}
}
#Override
public void replaceSelection(String text) {
// Delete or backspace user input.
if (text.equals("")) {
super.replaceSelection(text);
} else if (getText().length() < maxlength) {
// Add characters, but don't exceed maxlength.
// text = MascaraFinanceira.show(text);
if (text.length() > maxlength - getText().length()) {
// text = MascaraFinanceira.show(text);
text = text.substring(0, maxlength - getText().length());
}
super.replaceSelection(text);
}
}
/*
*Return the number without money mask
**/
public String getCleanValue(){
String cleanString = getText().replaceAll("[^0-9]", "");
Double cleanNumber = new Double(cleanString);
return String.valueOf(cleanNumber/100);
}
private String formata(Double valor) {
Locale locale = new Locale("pt", "BR");
NumberFormat nf = NumberFormat.getInstance(locale);
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
return nf.format(valor);
}
public String formata(String valor) {
double v = new Double(valor);
return formata(v/100);
}
}
And in the FXML where is
<TextField fx:id="valorTextField" GridPane.columnIndex="2" GridPane.rowIndex="2" />
put
<TextFieldMoney fx:id="valorTextField" GridPane.columnIndex="2" GridPane.rowIndex="2" />

Resources