How to add text to a textfield without overriding the current text? - java

I have a program where it asks the user for how many numbers to be sorted then randomly generates the amount of numbers the user asks and sorts it. This is my first attempt at using swing on java so im not sure how to go about one of my features. When the user press's sort there are 2 text fields. One is the array of the unsorted numbers and the other field will be where the sorted numbers go. However when I enter the amount of numbers then press sort I should expect the numbers with a comma. Maybe im using the wrong command for the text field but I cant figure it out. I think only the last number is coming up and is the only one that appears.
//get data
String data = txtInput.getText();
//parse for numerical value
int numGenerate = Integer.parseInt(data);
int Numbers[]=new int[numGenerate];
for (int x=0;x<=Numbers.length-1;x++)
{
Numbers[x]=(int)(Math.random()*1000)+1;
txtUnsorted.setText(String.valueOf(Numbers[x])+",");
}

Try this one.
txtUnsorted.setText(txtUnsorted.getText() + String.valueOf(Numbers[x])+ "," );

First of all don't name variable with a capital letter. Only classes should name with a capital letter.
Second thing, you don't have to parse int to String to print it.
In method setText you put only a number and a comma. You should also put existing value of this field:
txtUNsorted.setText(txtUnsorted.getText() + ", " + numbers[x]);

setText() method replaces the current text.
So get first txtUnsorted.getText() then assign to variable. Use setText() afterwards.
var unsorted = txtUnsorted.getText();
txtUnsorted.setText(unsorted + String.valueOf(Numbers[x])+",");

As czachodym said don't begin a variable with an Uppercase letter. Go through this Java Document to see the rules and conventions for naming your variables.
And also I don't think you need this statement like this because Arrays are zero-based,
x <= Numbers.length - 1
Just change above to the following because following is the correct way to iterate through an array,
x < Numbers.length
So your entire code should be like this,
// get data
String data = txtInput.getText();
// parse for numerical value
int numGenerate = Integer.parseInt(data);
int Numbers[] = new int[numGenerate];
for (int x = 0; x < Numbers.length; x++)
{
Numbers[x] = (int)(Math.random() * 1000) + 1;
txtUnsorted.setText(Numbers[x] + "," + txtUnsorted.getText()); // or
txtUnsorted.setText(txtUnsorted.getText() + Numbers[x] + ",");
}

Related

Hashmap in for loop not reading all the input

This is for AOC day 2. The input is something along the lines of
"6-7 z: dqzzzjbzz
13-16 j: jjjvjmjjkjjjjjjj
5-6 m: mmbmmlvmbmmgmmf
2-4 k: pkkl
16-17 k: kkkkkkkkkkkkkkkqf
10-16 s: mqpscpsszscsssrs
..."
It's formatted like 'min-max letter: password' and seperated by line. I'm supposed to find how many passwords meet the minimum and maximum requirements. I put all that prompt into a string variable and used Pattern.quote("\n") to seperate the lines into a string array. This worked fine. Then, I replaced all the letters except for the numbers and '-' by making a pattern Pattern.compile("[^0-9]|-"); and running that for every index in the array and using .trim() to cut off the whitespace at the end and start of each string. This is all working fine, I'm getting the desired output like 6 7 and 13 16.
However, now I want to try and split this string into two. This is my code:
HashMap<Integer,Integer> numbers = new HashMap<Integer,Integer>();
for(int i = 0; i < inputArray.length; i++){
String [] xArray = x[i].split(Pattern.quote(" "));
int z = Integer.valueOf(xArray[0]);
int y = Integer.valueOf(xArray[1]);
System.out.println(z);
System.out.println(y);
numbers.put(z, y);
}
System.out.println(numbers);
So, first making a hasmap which will store <min, max> values. Then, the for loop (which runs 1000 times) splits every index of the 6 7 and 13 16 string into two, determined by the " ". The System.out.println(z); and System.out.println(y); are working as intended.
6
7
13
16
...
This output goes on to give me 2000 integers seperated by a line each time. That's exactly what I want. However, the System.out.println(numbers); is outputting:
{1=3, 2=10, 3=4, 4=7, 5=6, 6=9, 7=12, 8=11, 9=10, 10=18, 11=16, 12=13, 13=18, 14=16, 15=18, 16=18, 17=18, 18=19, 19=20}
I have no idea where to even start with debugging this. I made a test file with an array that is formatted like "even, odd" integers all the way up to 100. Using this exact same code (I did change the variable names), I'm getting a better output. It's not exactly desired since it starts at 350=351 and then goes to like 11=15 and continues in a non-chronological order but at least it contains all the 100 keys and values.
Also, completely unrelated question but is my formatting of the for loop fine? The extra space at the beginning and the end of the code?
Edit: I want my expected output to be something like {6=7, 13=16, 5=6, 2=4, 16=17...}. Basically, the hashmap would have the minimum and maximum as the key and value and it'd be in chronological order.
The problem with your code is that you're trying to put in a nail with a saw. A hashmap is not the right tool to achieve what you want, since
Keys are unique. If you try to input the same key multiple times, the first input will be overwritten
The order of items in a HashMap is undefined.
A hashmap expresses a key-value-relationship, which does not exist in this context
A better datastructure to save your Passwords would probably just be a ArrayList<IntegerPair> where you would have to define IntegerPair yourself, since java doesn't have the notion of a type combining two other types.
I think you are complicating the task unnecessarily. I would proceed as follows:
split the input using the line separator
for each line remove : and split using the spaces to get an array with length 3
build from the array in step two
3.1. the min/max char count from array[0]
3.2 charachter classes for the letter and its negation
3.3 remove from the password all letters that do not correspond to the given one and check if the length of the password is in range.
Something like:
public static void main(String[] args){
String input = "6-7 z: dqzzzjbzz\n" +
"13-16 j: jjjvjmjjkjjjjjjj\n" +
"5-6 m: mmbmmlvmbmmgmmf\n" +
"2-4 k: pkkl\n" +
"16-17 k: kkkkkkkkkkkkkkkqf\n" +
"10-16 s: mqpscpsszscsssrs\n";
int count = 0;
for(String line : input.split("\n")){
String[] temp = line.replace(":", "").split(" "); //[6-7, z, dqzzzjbzz]
String minMax = "{" + (temp[0].replace('-', ',')) + "}"; //{6,7}
String letter = "[" + temp[1] + "]"; //[z]
String letterNegate = "[^" + temp[1] + "]"; //[^z]
if(temp[2].replaceAll(letterNegate, "").matches(letter + minMax)){
count++;
}
}
System.out.println(count + "passwords are valid");
}

Java - getting and using the integers from an array (0-how ever many the user inputted)

My program requires an input of as many integers as the user wishes on a SINGLE line. My program must then, take the first integer the user entered decide if it is in the range or not. If NOT output error, If YES then do specified conversion. THEN move to the SECOND integer entered by the user (if there is one).
The way I have tackled this so far is this...
System.out.print("Enter a digit(s). ");
//Gets input numbers and stores them as a whole string
//e.g if enters 1 2 3 input will = "1 2 3"
String input = kbd.nextLine();
//Splits the input at every space and stores them in an array
//e.g If input = "1 2 3", numbers {"1", "2", "3"}
String[] numbersString = input.split(" ");
//Creates an array the same length as our String array
//How we will store each number as an integer instead of a string
int[] numbers = new int[numbersString.length];
//a loop that goes through the array as a string
for ( int i = 0; i < numbersString.length; i++ )
{
// Turns every value in the numbersString array into an integer
// and puts it into the numbers array.
numbers[i] = Integer.parseInt(numbersString[i]);
}
My problem is that I don't know how to GET the first integer entered and then on to the second and so on... (I DONT UNDERSTAND HOW to access the array of integers ive obtained from the user and manipulate them from 1 - how ever many entered.
You access the array in a similar way to how you built it. For example, to print out the array, you can do this:
for ( int i = 0; i < numbers.length; i++ )
{
System.out.println(numbers[i]);
}
Note how the for loop is nearly identical to the last for loop in the code you posted. The only difference is numbers.length since you want to iterate over the numbers array.
You should also take the time to learn about the enhanced for loop which makes iterating over an array much easier.
What about something like this:
for(int number : numbers) //iterates through each number in the array of numbers
{
if(number > 4 && number < 10) //or whatever range you wanted
{
number *= 2; //or whatever conversion you wanted
System.out.println(number);
}
}
This uses an enhanced for loop as mentioned in comment above. The variable number (singular) is each int in your array of numbers.

String replace isn't working in for loop - Java

For some reason this code doesn't work.
public void actionPerformed(ActionEvent e) {
Random random = new Random();
int randomChar = random.nextInt((23 - 0) + 1);
for(int x = 23;x > 0;x-- ) {
String text;
text = original.getText();
text = text.toLowerCase();
text = text.replace(alphabet[x], alphabet[randomChar]);
newText.setText(text);
}
Just to clear a couple things up original and newText are JTextField, and alphabet is a char array with a-z.
Now when I run this it should go through and replace every character with a random one, starting at Z and ending at A however it just gives me the exact same string that I entered back, just converted to lowercase.
It's worth noting that if I replace
text = text.replace(alphabet[x], alphabet[randomChar]);
With
text = text.replace(alphabet[0], alphabet[randomChar]);
And put a bunch of A's into the input box it does change them into a random letter. EG:
aaaa input
llll output
or gggg output
it just doesn't work if I have a variable in there.
The rest of the code isn't important by the way, it's all declaring variables and setting up the GUI.
Any help is much appreciated!
In addition to moving the random character generation inside the loop (as suggested by #CIsForCoocckies), you'll also need to move the getText() and setText() calls outside the loop (because each time the loop is run, you start over with the original text so at most one kind of character would be replaced in the end, no matter how many times the loop iterates.
your randomchar is set before the loop with some char and then all chars are replaced to said char so - "yourstring" becomes "xxxxxxxxxx" where x=randomchar
In addition to the two other answers, I'd like to add a comment to the for loop:
for(int x = 23;x > 0;x--)
You won't enter the loop when x == 0 at all, which means the first char in your alphabet array won't be considered for replacement.
If you have the alphabet array already and want to replace every character with a random one, why not consider using:
for (int x = 0; x < alphabet.length; x++){
//your code here
}
This should be better than hard-coding

How to place spaces in between input textfield

I am trying to place spaces in between a number that has been entered in a textfield. I am using the following code:
for(int i = 0; i <= 2; i++)
{
char cijfer = tf1.getText().charAt(i);
char getal1 = tf1.getText().charAt(0);
char getal2 = tf1.getText().charAt(1);
char getal3 = tf1.getText().charAt(2);
}
String uitvoerGetal = getal1 + " " + getal2 + " " + getal3;
I suppose I don't understand the charAt() function yet, does anyone have a link explaining it in a way so I might be able to make this work too? Thanks in advance!
Example:
public class Test {
public static void main(String args[]) {
String s = "Strings are immutable";
char result = s.charAt(8);
System.out.println(result);
}
}
This produces the following result:
a
In more Detail From java docs
public char charAt(int index)
Returns the char value at the specified index. An index ranges from 0 to length() - 1. The first char value of the sequence is at index 0, the next at index 1, and so on, as for array indexing.
If the char value specified by the index is a surrogate, the surrogate value is returned.
Specified by:
charAt in interface CharSequence
Parameters:
index - the index of the char value.
Returns:
the char value at the specified index of this string. The first char value is at index 0.
Throws:
IndexOutOfBoundsException - if the index argument is negative or not less than the length of this string.
In straight words You can't. You can't add space in int datatype because int is meant to store the integer value only. Change int to String to store the space in between.
Okay, let's see what's wrong with your code...
Your for-loop is 1-based instead of the standard 0-based. That's not good at all.
You're attempting to assign a char to a String (3 times), the first call to charAt is correct, but for some reason you then switch to using a String?
Finally you're attempting to assign a String to an int, which is just completely nonsensical.
You have a number of problems, but well done on an honest attempt.
First up, the indexes in a string are zero-based, so charAt(0) gives you the first character, charAt(1) gives you the second character, and so on.
Secondly, repeating all your calls to charAt three times is probably unnecessary.
Thirdly, you must be careful with your types. The return value from charAt is a char, not a String, so you can't assign it to a String variable. Likewise, on the last line, don't assign a String to an int variable.
Lastly, I don't think you've thought about what happens if the text field doesn't contain enough characters.
Bearing these points in mind, please try again, and ask for further help if you need it.
Try following code
String text = tf1.getText(); // get string from jtextfield
StringBuilder finalString = new StringBuilder();
for(int index = 0; index <text.length(); index++){
finalString.append(text.charAt(index) + " "); // add spaces
}
tf1.setText(finalString.toString().trim()) // set string to jtextfield

Java loop to collect the second and third elements every three in an array

I have a file with data in the form timestamp, coordinate, coordinate, seperated by spaces, as here;
14:25:01.215 370.0 333.0
I need to loop through and add the coordinates only to an array. The data from the file is read in and put into as String[] called info, from split(" "). I have two problems, I think the end of the file has a extra " " which I need to lose appropriately and I also want confirmation/suggestions of my loop, at the moment I am getting sporadic out of bounds exceptions. My loop is as follows;
String[] info;
info = dataHolder.split(" ");
ArrayList<String> coOrds1 = new ArrayList<String>();
for (int counter = 0; counter < info.length; counter = counter+3)
{
coOrds1.add(info[counter+1]);
coOrds1.add(info[counter+2]);
}
Help and suggestions appreciated.
The text file is here but the class receives in a UDP packet from another class so I am unsure if this potentially adds " " at the end or not.
There are various classes/methods in Google's Guava library that could help with this task, in particular Splitter.omitEmptyStrings() which will discard any trailing space at the end of the file:
String input = Files.toString(file, Charsets.US_ASCII);
Iterable<String> fields =
Splitter.on(" ")
.omitEmptyStrings()
.split(input);
List<Coord> coords = Lists.newArrayList();
for (List<String> group: Iterables.partition(fields, 3)) {
String t = group.get(0);
double x = Double.parseDouble(group.get(1));
double y = Double.parseDouble(group.get(2));
coords.add(new Coord(t, x, y));
}
The problem will occur if you have an extra space at the end, because you are testing for counter < info.length and using counter + 1 and counter + 2. Try changing the loop conditions to:
for (int counter = 0; counter + 2 < info.length; counter = counter+3)
There is no need for external libraries.
You could just call dataHolder.trim(); which will remove any whitespace from the beginning and end your string. Then using dataHolder.split("\s"); //splits on "whitespace", you will receive an array consisting only of your data and with the appropriate size.
This will save you all the checks at each iteration whether counter+2 is still within the scope of the array. While still a valid solution, this could introduce further problems in the future due to its inherent nature of being "check-to-validate" - you simply might forget to process one of the cases - while trimming the string beforehand makes it structurally, constructed valid and there is no need to process special cases.

Categories