Java String Formatting not working as expected - java

please help me with the String formatting.
I have a String [], and I am adding each String into a result String which will be displayed in JOptionPane. When I add each String into the result, I used String.format("%-20s", String[i]) to make sure each string added to the final result have a minimum length of 20 and left justified. Every 5 words are started on a new line. However, the result shown in JOptionPane are not what I expected. The words are not aligned. Each word does not seem to have a minimum length of 20
private String keywordsList = "soup(s?)(base(s*))? hot(pot(s*))? "
+ "meat(s*) poultr((y)|(ies)){1} "
+ "beef(s?) cow(s?) ox(es)? bull(s?) "
+ "pork(s?) pig(s?) oink "
+ "mutton(s?) lamb(s?) sheep(s?) "
+ "chick(en(s)*)? hen(s)* rooster(s)* "
+ "seafood(s?) sea ocean shellfish fish((e)|(es))? "
+ "vegetable(s?) vege(s?) green plant(s?) veg(gies)? "
+ "signature(s?) recommendation(s?) recommend "
+ "h(i+) hell(o)+ y(o+) h(e)+(y) "
+ "morning afternoon evening "
+ "love(ly)? great good thank(s)? amazing excellent brilliant outstanding wonderful awesome okay "
+ "bad lousy useless stupid brainless fool(ish)? "
+ "got|get provide(s)* menu(s)* suppl(y|ies){1} offer(s*) "
+ "(good)?by(e+) leave end stop";
public String getKeywordList(){
String [] keywordsListArray = this.keywordsList.split("\\s");
String result = String.format("%-20s", keywordsListArray[0].replaceAll("[^a-z]", ""));
for (int i = 1; i < keywordsListArray.length; i++){
keywordsListArray[i] = keywordsListArray[i].replaceAll("[^a-z]", "");
if (i % 5 == 0){
result += String.format("%n%-20s", keywordsListArray[i]);
}
else
result += String.format("%-20s", keywordsListArray[i]);
}
return result;
}

Check first that result of getKeywordList() function is what you expect.
For example
...
// print out for debug
System.out.println(result);
return result;
}
So you will get:
soupsbases hotpots meats poultryies beefs
cows oxes bulls porks pigs
oink muttons lambs sheeps chickens
hens roosters seafoods sea ocean
shellfish fishees vegetables veges green
plants veggies signatures recommendations recommend
hi hello yo hey morning
afternoon evening lovely great good
thanks amazing excellent brilliant outstanding
wonderful awesome okay bad lousy
useless stupid brainless foolish gotget
provides menus supplyies offers goodbye
leave end stop
If the result is what you expected, than your problem is with JOptionPane and might be you will need to replace spaces with and \n with <br/>
return result.replaceAll(" ", " ").replaceAll("\n", "<br/>");
btw: you will have to use monospaced font if you want to have a correct aligned columns ... so wrap result in <pre>...</pre> tags.

You are trying to do primitive character-text-based alignment, but such a technique assumes the text is being rendered using a monospaced font. However the default font for JOptionPane is likely a proportionally-spaced font. But trying to set its font to something like Courier is likely the wrong idea, since that would ruin Swing's intended look and feel. It's better to break out of text-based thinking, and think like a UI developer instead. What you really want is to arrange your keyword strings in the cells of a JTable component, and pass that as the message argument to the JOptionPane. The message doesn't have to be a String or String []. It can be a first-class nested component object.

Related

Java: Issue when replacing Strings on loop

I'm building a small app which auto translates boolean queries in Java.
This is the code to find if the query string contains a certain word and if so, it replaces it with the translated value.
int howmanytimes = originalValues.size();
for (int y = 0; y < howmanytimes; y++) {
String originalWord = originalValues.get(y);
System.out.println("original Word = " + originalWord);
if (toReplace.contains(" " + originalWord.toLowerCase() + " ")
|| toCheck.contains('"' + originalWord.toLowerCase() + '"')) {
toReplace = toReplace.replace(originalWord, translatedValues.get(y).toLowerCase());
System.out.println("replaced " + originalWord + " with " + translatedValues.get(y).toLowerCase());
}
System.out.println("to Replace inside loop " + toReplace);
}
The problem is when a query has, for example, '(mykeyword OR "blue mykeyword")' and the translated values are different, for example, mykeyword translates to elpalavra and "blue mykeyword" translates to "elpalavra azul". What happens in this case is that the result string will be '(elpalavra OR "blue elpalavra")' when it should be '(elpalavra OR "elpalavra azul")' . I understand that in the first loop it replaces all keywords and in the second it no longer contains the original value it should for translation.
How can I fix this?
Thank you
you can sort originalValues by size desc. And after that loop through them.
This way you first replace "blue mykeyword" and only after you replace "mykeyword"
The "toCheck" variable is not explained what is for, and in any case the way it is used looks weird (to me at least).
Keeping that aside, one way to answer your request could be this (based only on the requirements you specified):
sort your originalValues, so that the ones with more words are first. The ones that have same number of words, should be ordered from more length to less.

Deleting String template until '\n' In a large String - Java

I'm having problem with String's in Java. I have a large String with a lot of \n and \\n. I want to delete entire rows that start with a certain template "Chorus:" and the rest of the row until \n.
I try to go over the String and searching the template "Chorus:". When i reach that, I concatenate the rest of the line until i reach to \n. Then i use myString.reaplaceAll(subString," ") and i get the same String as i started with.
My Code:
String string = " Police voice:\n"
+ "Attention all units attention all units\n"
+ "We have an All Points Bulletin out on a man with green hair\n"
+ "I repeat we have an APB on a man with green hair\n"
+ "He's armed with a knife I repeat he's armed with a knife\n"
+ "Proceed with caution watch your back fella's\n"
+ "He could be coming at your girlfriend next\n\n"
+ "Verse 1:\n"
+ "There's a joker on the loose from the psychiatric ward\n"
+ "His face is up on the bulletin board with a reward\n"
+ "He'll stab you with a sword don't be fooled by his charm\n"
+ "He's probably armed with intent to do bodily harm\n"
+ "Ring the alarm, look for a man with green hair\n"
+ "Check at your girl's house, he was last seen there\n"
+ "He's has a mean stare but usually crack's jokes\n"
+ "Good luck on your mission and guard your backs folks\n\n"
+ "Chorus:\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!\n\n"
+ "Verse 2:\n"
+ "We got the walkie-talkies to keep us all informed\n"
+ "Suited up head to toe in detective uniforms\n"
+ "Our unit storms in, we split the ghetto in sectors\n"
+ "Locking down every block and put up metal detectors\n"
+ "Protectors and be sure that you stand close\n"
+ "Watch each others backs and guard your command post\n"
+ "And most of all be advised that he's wise\n"
+ "He could be disguised as one of your very own guys\n\n"
+ "Chorus:\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!\n"
+ "Verse 3:\n"
+ "I'm on a solo mission to find him personally\n"
+ "To settle the score and beat then him mercifully\n"
+ "For what he first did to me\n"
+ "It's sure to be the last\n"
+ "Following footprints with a magnifying glass\n"
+ "To drag his lying ass back to his padded cell\n"
+ "I'm mad as hell, on the trail of the tattle tail\n"
+ "I heard a yell the voice sounded familiar\n"
+ "Give me your girlfriend or I'm gonna kill ya\n\n"
+ "Chorus:\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!\n\n"
+ "Verse 4:\n"
+ "I followed the voice that led down a flight of steps\n"
+ "Sneezing at dust, and swinging at the spider-webs\n"
+ "Inside the depths of his basement\n"
+ "I taste lint in my mouth, then the lights in the placeā€¦ went!\n"
+ "I saw my life flash in front of my eyes\n"
+ "I felt a butcher knife slash at one of my thighs\n"
+ "None of my guys knew where I'm at I was doomed\n"
+ "Then I remembered the flashlight in my costume\n\n"
+ "Chorus: Eminem\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!\n\n"
+ "Verse 5:\n"
+ "Dealing with backstabber's there was one thing I learned\n"
+ "They're only powerful when you got your back turned\n"
+ "I yearned for the day that we finally met againf\n"
+ "So I can give him a taste of his own medicine\n"
+ "He shed his skin, then he promised to come clean\n"
+ "I took his butcher knife and jabbed it into his spleen\n"
+ "Cut him at the seam then dragged the fella home\n"
+ "Beating him over the head with the telephone\n\n"
+ "Police voice:\n"
+ "Attention all cars, attention all cars\n"
+ "Unit 313 has apprehended the suspect\n"
+ "He's going back to the crazy home, I repeat\n"
+ "He's going back to the crazy home, how about that?\n\n"
+ "Chorus:\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!\n"
+ "I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Hit a bitch snake from the back, I make you think you're a best friend then\n"
+ "Why I oughtta\n"
+ "Stay away from him he ain't no good!";
String subString = ""; // Searching for Chorus: (7 characters) sub sub string in string
for (int i = 0;i < string.length();i++)
{
if (string.charAt(i) == 'C')
{
subString = string.substring(i,i + 7);
subString += " "; // "Chorus: "
//System.out.println(subString);
if (subString.equals("Chorus:")) // Delete the row
{
i += 7;
while (string.charAt(++i)!= '\n')
{
//System.out.println(string.charAt(i));
subString += string.charAt(i);
}
string = new String(string.replaceAll(subString, ""));
}
}
}
printString(string);
}
/**
*
* #param string to be printed on the console.
*/
public static void printString(String string)
What am i doing wrong? Any help will be very appreciated.
EDIT:
For clarification:
converting "abcChorus:def\n"+"gh\n"+"Chorus;ijk\n"+"lmnop" to "gh\n"+"lmnop"
You should get into the base libraries of a language and see what they can do, instead of pushing chars yourself...
String[] lines = string.split("\n"); // split into array at newlines
String result = Stream.of(lines)
.filter(s -> !s.startsWith("Chorus:")) // filter however you like
.collect(Collectors.joining("\n")); // re-join as string with newlines
System.out.println(result);
You can try this:
String new = old.trim()
It removes the leading and trailing spaces from string.
You can store the trimmed string somewhere.After that once you make the modification concatenate it as the way you want it.
You could make a use of regex and recursion too. Just call the removeStuff method on your String.
You can also change and tweak the regex inside the compile method argument.
static Pattern pattern = Pattern.compile("Chorus([^\n]*)");
static Matcher matcher = pattern.matcher(string);
public static String removeStuff(String myString, Matcher matcher) {
if (matcher.find() == false) {
return myString;
}
return removeStuff(string.replace(matcher.group(), ""), matcher);
}
My complicated solution.
I searched for "Chorus: " String in the String and concatenated the rest of the line (until \n) and replace those sub strings in the whole String. Then replacing all the "Chorus:" sub strings from the whole String.
Like that i tackle both "Chorus:" lines and "Chorus: blablablalba" lines.
Solution:
String subString = ""; // Searching for "Chorus: " (7 characters) sub string in string
for (int i = 0;i < string.length();i++)
{
if (string.charAt(i) == 'C')
{
subString = string.substring(i,i + 8);
//subString += " "; // "Chorus:"
//System.out.println(subString);
if (subString.equals("Chorus: ")) // Delete the row
{
i += 8;
while (string.charAt(i)!= '\n')
{
//System.out.println(string.charAt(i));
subString += string.charAt(i);
i++;
}
//System.out.println(subString);
string = new String(string.replaceAll(subString, ""));
}
}
}
string = new String(string.replaceAll("Chorus:", ""));

Should be returning true but returns false instead?

Code:
Bukkit.getServer().broadcastMessage("Check " + ChatColor.stripColor(i));
Bukkit.getServer().broadcastMessage("That it starts with " + ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', GUIShop.instance.getConfig().getString("Messages." + type + "Label"))));
Bukkit.getServer().broadcastMessage(ChatColor.stripColor(i).startsWith(ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', GUIShop.instance.getConfig().getString("Messages." + type + "Label")))) + "");
And image of it returning false instead of true:
Could me being stupid.. Not sure
EDIT1: Ok so thanks to eckes he pointed out that I was being stupid.. How would I check if "Buy: 50.0" started with "Buy: Price". Like if up to %price%
False is correct, "Buy: 50.0" does not start with "Buy: %price%". And you should really not mix color logic with translation logic with business logic.
Make your code readable, it often helps to find the problem yourself.
If you want to remove %price% you could use:
String check = ChatColor.stripColor(i);
String pattern = ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&',
GUIShop.instance.getConfig().getString("Messages." + type + "Label")));
pattern = pattern.replace(" %price%", "");
boolean isBuy = check.startsWith(pattern);
I cant make it much more readable without more background details.

Love letter- using arrays to print message

I've been asked to create a program that stores series of suitable nouns, adjectives and verbs in arrays. These must be set up at the start of program run. Rather than ask the user, each time it generates letter it just chooses words at random from the appropriate array. The arrays are passed to methods that represent the templates.
I'm new to java, and this is what I have managed to get done below, however shows errors saying void cannot be converted to string for each print message part. I would be glad if someone can help me approach this simple question which i'm struggling on, I don't know if I am doing it correctly.
Any help would be much appreciated.
public static void arrays()
{
String []noun = {"face", "eyes", "tender", "lips", "ears", "roses"};
Random random = new Random();
int rand1 = random.nextInt(noun.length);
String []verb = {"enchant", "dazzle", "cuddle" , "lure", "desire", "dream" };
Random random2 = new Random();
int rand2 = random2.nextInt(verb.length);
String []adjective = { "Alluring", "Angelic", "Adoring", "Appealing", "Attractive", "beautiful"};
Random random3 = new Random();
int rand3 = random3.nextInt(adjective.length);
printmessage (noun[rand1], verb[rand2], adjective[rand3]);
}
// END arrays
public static void printmessage(String noun, String verb, String adjective)
{
System.out.println("I would love to " + verb + " " + adjective + " " + noun + "\n");
System.out.println("Your are my " + noun + " " + adjective + " " + verb + "\n");
System.out.println("you always look great in that " + noun + " ,as you always do, since your so " + adjective + "\n");
System.out.println("I get butterflies when I see you in" + noun + " , you make me " + verb + " , in your " + adjective + " world" + "\n");
}
} // END class loveletter
You've got some issues here, so let's walk through them.
First, the conceptual issue. You shouldn't need to return anything from your printmessage method, as all you're doing is showing a message dialog.
Next, you don't do anything with those four result variables, and they would only last within the scope of that method. That's to say, not very long. I don't think you need them.
Next, the technical issues:
One return is all it takes for the code execution to halt. If it were valid code, you would only get back result1. Since we discussed earlier that you don't need to return anything from this method, remove the superfluous returns.
JOptionPane#showMessageDialog returns void; that is to say, it returns nothing. You can't assign a value of its return type to a variable, so the variables do you absolutely no good. Remove the assignment and declarations.
Don't forget to change the return type of your method to void instead of String.
Clean up the call in arrays() so that it only calls printmessage at the end, and doesn't do anything else after that.
I leave the logical errors (I did notice some funky string concatenation and grammatical errors in there) as an exercise to the reader.

Issue in Combining splitted String

I have extracted text from "web 2.0 wikipedia" article, and splitted it into "sentences". After that, I am going to create "Strings" which each string containing 5 sentences.
When extracted, the text looks like below, in EditText
Below is my code
finalText = textField.getText().toString();
String[] textArrayWithFullStop = finalText.split("\\. ");
String colelctionOfFiveSentences = "";
List<String>textCollection = new ArrayList<String>();
for(int i=0;i<textArrayWithFullStop.length;i++)
{
colelctionOfFiveSentences = colelctionOfFiveSentences + textArrayWithFullStop[i];
if( (i%5==0) )
{
textCollection.add(colelctionOfFiveSentences);
colelctionOfFiveSentences = "";
}
}
But, when I use the Toast to display the text, here what is gives
Toast.makeText(Talk.this, textCollection.get(0), Toast.LENGTH_LONG).show();
As you can see, this is only one sentence! But I expected it to have 5 sentences!
And the other thing is, the second sentence is starting from somewhere else. Here how I have extracted it into Toast
Toast.makeText(Talk.this, textCollection.get(1), Toast.LENGTH_LONG).show();
This make no sense to me! How can I properly split the text into sentences and, create Strings containing 5 sentences each?
The problem is that for the first sentence, 0 % 5 = 0, so it is being added to the array list immediately. You should use another counter instead of mod.
finalText = textField.getText().toString();
String[] textArrayWithFullStop = finalText.split("\\. ");
String colelctionOfFiveSentences = "";
int sentenceAdded = 0;
List<String>textCollection = new ArrayList<String>();
for(int i=0;i<textArrayWithFullStop.length;i++)
{
colelctionOfFiveSentences += textArrayWithFullStop[i] + ". ";
sentenceAdded++;
if(sentenceAdded == 5)
{
textCollection.add(colelctionOfFiveSentences);
colelctionOfFiveSentences = "";
sentenceAdded = 0;
}
}
add ". " to textArrayWithFullStop[i]
colelctionOfFiveSentences = colelctionOfFiveSentences + textArrayWithFullStop[i]+". ";
I believe that if you modify the mod line to this:
if(i%5==4)
you will have what you need.
You probably realize this, but there are other reasons why someone might use a ". ", that doesn't actually end a sentence, for instance
I spoke to John and he said... "I went to the store.
Then I went to the Tennis courts.",
and I don't believe he was telling the truth because
1. Why would someone go to play tennis after going to the store and
2. John has no legs!
I had to ask, am I going to let him get away with these lies?
That's two sentences that don't end with a period and would mislead your code into thinking it's 5 sentences broken up at entirely the wrong places, so this approach is really fraught with problems. However, as an exercise in splitting strings, I guess it's as good as any other.
As a side problem(splitting sentences) solution I would suggest to start with this regexp
string.split(".(\\[[0-9\\[\\]]+\\])? ")
And for main problem may be you could use copyOfRange()

Categories