Align Strings in columns in JTextArea - java

I want to print Strings in JTextArea and align them properly. Its hard to explain so I will upload the screen shot of what I am trying to achieve.
So Strings printed in each line are printed from Paper object which has parameters (id, title, author, date, rank). The data is read from a text file and is stored in a LinkedList using loadPaper() function.
Then displayPapers() function is used to display content of the Paper object to the JTextArea.
displayPapers() is listed below:
/** Print all Paper object present in the LinkedList paperList to textArea */
public void displayPapers(){
// clear textArea before displaying new content
displayTxtArea.setText("");
Paper currentPaper;
ListIterator<Paper> iter = paperList.listIterator();
while(iter.hasNext()){
currentPaper = iter.next();
String line = currentPaper.toString();
if("".equals(line)){
continue;
} // end if
String[] words = line.split(",");
displayTxtArea.append (" "
+ padString(words[0],30)
+ padString(words[1],30)
+ " "
+ padString(words[2],30)
+ " "
+ padString(words[3],30)
+ padString(words[4],30)
+ "\n");
System.out.println(words);
//displayTxtArea.append(currentPaper.toString());
} // end while
displayTxtArea.append(" Total " + noOfPapers + " entries!");
} // end showAllPaper
The padString() function adds spaces to the String so that all of them have same number of words. PadString() is listed below:
/** Add spaces to Strings so that all of the are of same number of characters
* #param str String to be padded
* #param n total number words String should be padded to
* #return str Padded string
*/
private String padString(String str, int n){
if(str.length() < n){
for(int j = str.length(); j < n; j++){
str += " ";
} // end for
} // end if
return str;
} // end padString
I have worked on this for a while but still cant get the solution. As you can notice the above picture not everything is perfectly aligned as intended.
How do I align them perfectly so that it looks nicer? Thanks.

Output will be aligned "properly" in your JTextArea only if you use a mono-spaced font. "Andale Mono 14" for example would do the trick.
Also, in order to make your life easier and avoid the padding hell, use String.format with it's syntax.
String format = "%1$5s %2$-40s %3$-20s";
String someLine;
while (whatEver...) {
...
someLine = String.format(format, aNum, aName, aDate);
jTextArea1.append(someLine + "\n");
}

Use a JTable instead (for what is apparently tabular information). See How To Use Tables for more details & working examples.

You may use HTML with swing component or use JEditorPane.
JLabel jt=new JLabel();
jt.setText("<html>
<table border='1'>
<tr><th>No</th><th>Name</th></tr>
<tr><td>1</td><td>Mr.A</td></tr></table></html>");

You can also change the font of the JTextArea if it is allowed in your problem
textArea.setFont(new Font("monospaced", Font.PLAIN, 12));

Related

Splitting a specific bunch of text - JAVA

If I have this element:
<Comments type="ITEM_OUT_COMMENTS" xml:lang="en">Item text
203871: ATAG ZON POMPUPR 15-60 DO NOT DELETE SupplierAuxiliaryPartID : 395##!817##!N
Material PO text
Computers, Mainframe
COMPUTERS,MAINFRAME,SOURCED
</Comments>
Is it also possible to get only this piece of text back: 395##!817##!N
This piece of text is always to be found behind: SupplierAuxiliaryPartID :
But it can happen that there are no spaces like this SupplierAuxiliaryPartID:395##!817##!N:
<Comments type="ITEM_OUT_COMMENTS" xml:lang="en">Item text
203871: ATAG ZON POMPUPR 15-60 DO NOT DELETE SupplierAuxiliaryPartID:395##!817##!N
Material PO text
Computers, Mainframe
COMPUTERS,MAINFRAME,SOURCED
</Comments>
I tried several splits but every time I cannot get the right piece of text.
final String LABEL = "SupplierAuxiliaryPartID"
String getSupplierAuxiliaryPartId(String comments)
{
// Split comments by line
for (String line : comments.split('\n'))
{
// find where the label is
int index = line.indexOf(label);
if (index == -1)
{
// no label on this line
continue;
}
// find first colon after the label
index = line.indexOf(":", index + LABEL.length);
if (index == -1)
{
// label without colon, but maybe the next line has a valid one
continue;
}
// return the remaining of the line after the colon striping out extra whitespaces
return line.substring(index + 1).trim();
}
// label with column not present in comment
return null;
}

Bolding specific text

I'm trying to bold some text in a setter, but when it's displayed, it's not working. I'll just jump into some code so it makes sense...
private static class Spell {
private final String name;
private final String school;
private final String display_class;
//etc.
.
Text t = new Text("TEST: ");
t.setStyle("-fx-font-weight: bold;");
this.name = name + "\n\n";
this.school = school + "\n";
this.display_class = t + display_class + " " + spell_level + "\n";
//etc.
Displaying the list:
if (!newValue.isHeader()) {
tooltip.setText(newValue.getName() + newValue.getSchool() + newValue.getDisplay_Class() //etc.
The text is displayed within a ScrollPane as a Text object: Text tooltip = new Text();
The list displays values like Level: 0 Range: 25ft etc. With this setup, is it at all possible to make just the "Level:" and "Range:" parts bold? Currently, what is displayed when it prints t is Text[text="TEST: ",x=0.0,y=0.0, alignment=LEFT, origin=BASELINE, boundsType=LOGICAL...etc. etc, yet when adding t to a pane and displaying it that way, it shows up correctly bolded. I don't know what to do at this point.
Text t = new Text("TEST: ");
...
this.display_class = t + display_class + " " + spell_level + "\n";
In the line above, you are concatenating the output of toString() of your Text object instance (t) with other strings, that where your extra junk comes from, and it is not probably what you wanted to do.
Unfortunately Text won't support multistyle text strings.

Java Regex : How to search a text or a phrase in a large text

I have a large text file and I need to search a word or a phrase in the file line by line and output the line with the text found in it.
For example, the sample text is
And the earth was without form,
Where [art] thou?
if the user search for thou word, the only line to be display is
Where [art] thou?
and if the user search for the earth, the first line should be displayed.
I tried using the contains function but it will display also the without when searching only for thou.
This is my sample code :
String[] verseList = TextIO.readFile("pentateuch.txt");
Scanner kbd = new Scanner(System.in);
int counter = 0;
for (int i = 0; i < verseList.length; i++) {
String[] data = verseList[i].split("\t");
String[] info3 = data[3].split(" ");
System.out.print("Search for: ");
String txtSearch = kbd.nextLine();
LinkedList<String> searchedList = new LinkedList<String>();
for (String bible : verseList){
if (bible.contains(txtSearch)){
searchedList.add(bible);
counter++;
}
}
if (searchedList.size() > 0){
for (String s : searchedList){
String[] searchedData = s.split("\t");
System.out.printf("%s - %s - %s - %s \n",searchedData[0], searchedData[1], searchedData[2], searchedData[3]);
}
}
System.out.print("Total: " + counter);
So I am thinking of using regex but I don't know how.
Can anyone help? Thank you.
Since sometimes variables have non-word characters at boundary positions, you cannot rely on \b word boundary.
In such cases, it is safer to use look-arounds (?<!\w) and (?!\w), i.e. in Java, something like:
"(?<!\\w)" + searchedData[n] + "(?!\\w)"
To match a String that contains a word, use this code:
String txtSearch; // eg "thou"
if (str.matches(".*?\\b" + txtSearch + "\\b.*"))
// it matches
This code builds a regex that only matches if both ends of txtSearch fall and the start/end of a word in the string by using \b, which means "word boundary".

Having trouble with string concatenation

I was trying to concatenate a string to itself + something else, like this:
String example = " "
for (int i = 0; i < 5; i++) {
if (condition OK) {
example = example + "\nAnother text";
}
}
JOptionPane.showMessageDialog(null, example);
In my mind, it should've print " (new line)Another text" but it seems to work only with the last entry in my "Another text". Like, if the condition inside the "for" loop is OK 3 times, it prints " (new line)Another text(3)" instead of " (new line) Another Text(1) (new line) Another text(2)...
Any idea of what may be happening?
EDIT: after realizing that my code was fine, I followed afzalex recommendation and found out the error was in my condition. Thanks bro
I used below program I got expected output.
String example = " ";
for (int i = 0; i < 5; i++) {
if (i == 1 || i == 3) {
example = example + "\nAnother text";
}
}
System.out.println(example);
Output:
Another text
Another text
So, probably it could be something wrong with JOptionPane.showMessageDialog(null, example); If it is being interpreted as HTML in the end, then better use </br> instead of \n, that can give you new line.

Trim() in Java not working the way I expect? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Query about the trim() method in Java
I am parsing a site's usernames and other information, and each one has a bunch of spaces after it (but spaces in between the words).
For example: "Bob the Builder " or "Sam the welder ". The numbers of spaces vary from name to name. I figured I'd just use .trim(), since I've used this before.
However, it's giving me trouble. My code looks like this:
for (int i = 0; i < splitSource3.size(); i++) {
splitSource3.set(i, splitSource3.get(i).trim());
}
The result is just the same; no spaces are removed at the end.
Thank you in advance for your excellent answers!
UPDATE:
The full code is a bit more complicated, since there are HTML tags that are parsed out first. It goes exactly like this:
for (String s : splitSource2) {
if (s.length() > "<td class=\"dddefault\">".length() && s.substring(0, "<td class=\"dddefault\">".length()).equals("<td class=\"dddefault\">")) {
splitSource3.add(s.substring("<td class=\"dddefault\">".length()));
}
}
System.out.println("\n");
for (int i = 0; i < splitSource3.size(); i++) {
splitSource3.set(i, splitSource3.get(i).substring(0, splitSource3.get(i).length() - 5));
splitSource3.set(i, splitSource3.get(i).trim());
System.out.println(i + ": " + splitSource3.get(i));
}
}
UPDATE:
Calm down. I never said the fault lay with Java, and I never said it was a bug or broken or anything. I simply said I was having trouble with it and posted my code for you to collaborate on and help solve my issue. Note the phrase "my issue" and not "java's issue". I have actually had the code printing out
System.out.println(i + ": " + splitSource3.get(i) + "*");
in a for each loop afterward.
This is how I knew I had a problem.
By the way, the problem has still not been fixed.
UPDATE:
Sample output (minus single quotes):
'0: Olin D. Kirkland                                          '
'1: Sophomore                                          '
'2: Someplace, Virginia  12345<br />VA SomeCity<br />'
'3: Undergraduate                                          '
EDIT the OP rephrased his question at Query about the trim() method in Java, where the issue was found to be Unicode whitespace characters which are not matched by String.trim().
It just occurred to me that I used to have this sort of issue when I worked on a screen-scraping project. The key is that sometimes the downloaded HTML sources contain non-printable characters which are non-whitespace characters too. These are very difficult to copy-paste to a browser. I assume that this could happened to you.
If my assumption is correct then you've got two choices:
Use a binary reader and figure out what those characters are - and delete them with String.replace(); E.g.:
private static void cutCharacters(String fromHtml) {
String result = fromHtml;
char[] problematicCharacters = {'\000', '\001', '\003'}; //this could be a private static final constant too
for (char ch : problematicCharacters) {
result = result.replace(ch, ""); //I know, it's dirty to modify an input parameter. But it will do as an example
}
return result;
}
If you find some sort of reoccurring pattern in the HTML to be parsed then you can use regexes and substrings to cut the unwanted parts. E.g.:
private String getImportantParts(String fromHtml) {
Pattern p = Pattern.compile("(\\w*\\s*)"); //this could be a private static final constant as well.
Matcher m = p.matcher(fromHtml);
StringBuilder buff = new StringBuilder();
while (m.find()) {
buff.append(m.group(1));
}
return buff.toString().trim();
}
Works without a problem for me.
Here your code a bit refactored and (maybe) better readable:
final String openingTag = "<td class=\"dddefault\">";
final String closingTag = "</td>";
List<String> splitSource2 = new ArrayList<String>();
splitSource2.add(openingTag + "Bob the Builder " + closingTag);
splitSource2.add(openingTag + "Sam the welder " + closingTag);
for (String string : splitSource2) {
System.out.println("|" + string + "|");
}
List<String> splitSource3 = new ArrayList<String>();
for (String s : splitSource2) {
if (s.length() > openingTag.length() && s.startsWith(openingTag)) {
String nameWithoutOpeningTag = s.substring(openingTag.length());
splitSource3.add(nameWithoutOpeningTag);
}
}
System.out.println("\n");
for (int i = 0; i < splitSource3.size(); i++) {
String name = splitSource3.get(i);
int closingTagBegin = splitSource3.get(i).length() - closingTag.length();
String nameWithoutClosingTag = name.substring(0, closingTagBegin);
String nameTrimmed = nameWithoutClosingTag.trim();
splitSource3.set(i, nameTrimmed);
System.out.println("|" + splitSource3.get(i) + "|");
}
I know that's not a real answer, but i cannot post comments and this code as a comment wouldn't fit, so I made it an answer, so that Olin Kirkland can check his code.

Categories

Resources