I am trying to create an array of Strings to use with JList, I have a array of objects from my Book class which contains the Author name, Tittle etc... But when I use string.format and send it to my JList the text doesn't come out aligned like when I use system.out.format.
Code:
final static String FORMAT = "|%1$-25s|%2$-25s|$%3$-10.2f|%4$-15s|%5$-13s|\n";
static String[] createStringList(Book[] dataBase)
{
String[] list = new String[dataBase.length];
for (int i = 0; i < dataBase.length; i++)
{
list[i] = String.format(FORMAT, dataBase[i].getTittle(), dataBase[i].getAuthor(),
dataBase[i].getBookPrice(), dataBase[i].getNumberInStock(),
dataBase[i].getISBNNumber());
}
return list;
}
static void printout(Book[] dataBase)
{
System.out.println(" Tittle" + "\t" + " Author" + "\t" + " Price" + "\t" + "Number In Stock" + "\t" + " ISBN Number");
System.out.println("_____________________________________________________________________________________________");
for (int i = 0; i < dataBase.length; i++)
{
System.out.format(FORMAT, dataBase[i].getTittle(), dataBase[i].getAuthor(),
dataBase[i].getBookPrice(), dataBase[i].getNumberInStock(),
dataBase[i].getISBNNumber());
}
}
Result Screenshot:
As you can see, the print method aligns it fine but when I try to send it to my JList it messes up even though I am using the same code. How would I go about aligning it? I have tried playing with the values in String format = "|%1$-25s|%2$-25s|$%3$-10.2f|%4$-15s|%5$-13s|\n"; but it doesn't seem to help.
The reason for your messed up alignment in the JList is because it uses (hopefully) a proportional font. You could use a monospaced one, but that will be ugly. You need to use columns in the JList (i.e. a table control).
Related
I am writing a project in which I have to write questions and marks from MySQL database in a text file (Questions and marks are in different columns in database but in same table). Here, I want to write marks in same position i.e vertically aligned after each questions.
I tried using \t but it can't get desired output
while(myRs.next()) {
String question = myRs.getString("question");
String marks = myRs.getString("questionMarks");
try {
file.write(question+"\t\t\t\t\t\t\t" + marks + "\n");//write to text file
}
catch(Exception exe) {
System.out.println(exe);
}
System.out.println("Q" + count +". " + question);
}
Desired output is:
(Single "." represents whitespaces in actual output and "Question1", "Question2" , "Question3" are not actual questions, rather, they are statements)
Q1. Question1.............................4
Q2. Question2.............................4
Q3. Question3.............................5
Actual output is:
Q1. Question1........................ 4
Q2. Question2................................4
Q3. Question3...........................5
You just need to calculate the size of the question and add remaining spaces up to your preferred linesize.
See add characters n-times for alternative ways to repeat characters.
int maxlinesize = 40;
int count=0;
while(myRs.next()) {
String question = myRs.getString("question");
String marks = myRs.getString("questionMarks");
count++;
String q="Q"+count+" "+question;
StringBuffer buffer = new StringBuffer();
buffer.append(String.join(q, java.util.Collections.nCopies(maxlinesize - q.length(), " ")))
.append(marks);
try {
file.write(buffer.toString()+ "\n");//write to text file
}
catch(Exception exe) {
System.out.println(exe);
}
}
As suggested by Avi, just store all the questions to be written in an ArrayList. Also, store marks in another ArrayList. Then, find the longest question's string length and use String.format to write in the text file. As follows:
ArrayList<String> question1 = new ArrayList<String>();
ArrayList<Integer> marks1 = new ArrayList<Integer>();
int maxLen = 0;
while(myRs.next()) {
String question = myRs.getString("question");
Integer marks = myRs.getInt("questionMarks");
question1.add(question);
marks1.add(marks);
for(int i = 0; i < question1.size(); i++) {
if(question1.get(i).length() > maxLen) {
maxLen = question1.get(i).length();
}
}
int index = 0;
try {
file.write("Q" + count + ". " + String.format("%-"+(1+maxLen)+"s%d\n", question1.get(index), marks1.get(index)));
}
catch(Exception exe) {
System.out.println(exe);
}
`
I have a JList model (listModelGrid) with items with labels like this:
LastName, FirstName Spouse // e.g. This is 1st list item with labels
Children // e.g. This is 2nd list item with labels
Street // e.g. This is 3rd list item with labels
City, State Postal // e.g. This is 4th list item with labels
I want to replace Labels with ResultSet.getString method like this:
String labels = "";
labels += resultSet.getString("LastName")+", "+resultSet.getString("FirstName")+" "+
resultSet.getString("Spouse") + "\n";
labels += resultSet.getString("Children") + "\n";
labels += resultSet.getString("Street") + "\n";
labels += resultSet.getString("City")+", "+resultSet.getString("State")+" "+
resultSet.getString("Postal");
I have tried it but stuck in loops:
private String getPrintingLabels(ResultSet rs) throws SQLException {
String str = "";
for (int i = 0; i < listModelGrid.getSize(); i++) {
String element = String.valueOf(listModelGrid.getElementAt(i));
String[] lbls = element.split(",\\s");
str += rs.getString(lbls[0])+", ";
for(int j = 1; j < lbls.length ; j++) {
// Stuck on her
}
String[] lbls2 = element.split("\\s");
str += rs.getString(lbls2[0])+" ";
for(int j = 1; j < lbls2.length ; j++) {
// Stuck on her
}
}
return str;
}
Thanks in advance!
The code in your method is written in a little complicated way.
I have used regex and simplified the code you wanted to write and here it is.
private String getPrintingLabels(ResultSet rs) throws SQLException {
Pattern p = Pattern.compile("([a-zA-Z]+)(,? )?");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < listModelGrid.getSize(); i++) {
String element = String.valueOf(listModelGrid.getElementAt(i));
Matcher m = p.matcher(element);
while(m.find()) {
sb.append(rs.getString(m.group(1)));
if (m.group(2) != null) {
sb.append(m.group(2));
}
}
sb.append(System.getProperty("line.separator")); // helps correctly insert a new line for any platform linux/windows/any
}
System.out.println(sb.toString());
return sb.toString();
}
I don't know if you are familiar with regex but by using regex your job is done quite easily. Also, using String concatenation is not a good idea specially when you have to do it quite much hence I have used StringBuild for same purpose. Also used line.separator property so no matter in what platform you run the code it will have appropriate line in your string. Just use my method instead of yours and see if the desired string the one you wanted.
Also in my code, you won't have to manually manage inserting ", " or " " as that is done automatically as it is present in the string.
Also make sure you import these two or any needed imports,
import java.util.regex.Matcher;
import java.util.regex.Pattern;
I haven't been able to find any questions similar to my situation so I hope I'm not missing something.
I have an array of strings. I want to print every 3 strings on their own line with commas and spacing.
Here is my method:
public static void Modify(String stringSearch)
{
ArrayList<String> records = new ArrayList<String>();
try {
File file = new File("Temp.txt");
input = new Scanner(file);
}
catch (IOException ioe) {
ioe.printStackTrace();
}
if (input.hasNext()) {
while (input.hasNext())
{
String firstName = input.next();
String lastName = input.next();
String phoneNumber = input.next();
if ((Objects.equals(firstName, stringSearch)) || (Objects.equals(lastName, stringSearch)) || (Objects.equals(phoneNumber, stringSearch))) {
records.add(firstName);
records.add(lastName);
records.add(phoneNumber);
}
} // end while
}
int size;
size = (records.size()) / 3;
System.out.printf("Found %d records:%n", size);
String[] Array = records.toArray(new String[0]);
for (int s = 0; s < Array.length; s++) {
System.out.printf("%s", Array[s]);
}
}
I am converting an arrayList to a string array in order to try and format it. I'm very new to java and am working on a project in a time crunch.
I need it to print exactly like this:
Found 2 records:
1) Garcia, John 505-338-2567
2) John, Joseph 212-780-3342
It is printing like this:
Found 2 records:
GarciaJohn505-338-2567JohnJoseph212-780-3342
Java is an Object-Oriented language, and you should use it.
Create a class representing your Person, with firstName, lastName, and phoneNumber as fields.
Then you create a List<Person> with 2 objects in it, and write a method for printing that list. The System.out.printf() you're already using can help output values in columns like you want.
You probably need to create you own data-structure, with a toString() method that suits your needs.
Something like:
public class PersonalCustomerData {
private String firstName;
private String lastName;
private String phoneNumber;
...
#Override
public String toString() {
return lastName + "," + " " + firstName + " " + phoneNumber;
}
}
And, as #Andreas mentioned in his answer, you also need a Collection<PersonalCustomerData>, that when you iterate over it, you print your fully formatted output:
private Collection<PersonalCustomerData> col;
// init the collection + do stuff...
public void printCustomerData() {
int lineNumber = 0;
for(PersonalCustomerData pcd : col) {
lineNumber++;
System.out.println(lineNumber + ")" + " " + pcd);
}
}
If you don't want to use object to contain your values and stick with your plan of doing. you can use this code to print it with format.
Replace this:
String[] Array = records.toArray(new String[0]);
for (int s = 0; s < Array.length; s++) {
System.out.printf("%s", Array[s]);
}
to this:
int numberOfLine = 1; // Counter of words per line
String[] Array = records.toArray(new String[0]);
for(String str : Array) {
String strSperator = "";
switch (numberOfLine) {
case 1:
strSperator = ", ";
numberOfLine++;
break;
case 2:
strSperator = " ";
numberOfLine++;
break;
case 3:
strSperator = "\n";
numberOfLine = 1;
break;
}
System.out.printf("%s%s",str,strSperator);
}
replace this line
for (int s = 0; s < Array.length; s++) {
System.out.printf("%s", Array[s]);`
to something like this. I didn't test out the code so there might be small typos or what not. I think this will do what you want.
As Andreas said, it would be better if you make a person class. It will look more organized and probably easier to understand.
int counter = 1;
System.out.print(records.get(0) + ",\t")
while (counter !=records.size())
{
if(counter %3 ==0)
System.out.println(records.get(counter));
else if(counter% 3== 1)
System.out.print(records.get(counter) + ",\t");
else
System.out.print(records.get(counter)+ "\t");
counter ++;
}
Since your first element will always be first name , 2nd element will be last name and 3rd element is the phone number, I print the first one initially then the modding and the while loop should handle everything I believe.
I have a String array defined and read some values from a table into it:
String[][] ssRet = null;
ssRet = new String[tblRoDe.getNumRows()+1][2];
ssRet[0][0] = "AGR_NAME";
ssRet[0][1] = "TEXT";
for(int j=0; j<tblRoDe.getNumRows(); j++ )
{
tblRoDe.setRow( j );
ssRet[j+1][0] = tblRoDe.getString( "AGR_NAME" );
ssRet[j+1][1] = tblRoDe.getString( "TEXT" );
logger.debug("------- Start Entry #" + (j+1) + " -------");
logger.debug(ssRet[0][0] + ": " + ssRet[j+1][0]);
logger.debug(ssRet[0][1] + ": " + ssRet[j+1][1]);
logger.debug("------- End Entry #" + (j+1) + " -------");
}
My task now is: depending on a function param I will have to read values from a different table into the same string array (append this). There are still only two columns but I have to add more lines.
How can I achieve that?
You will have problems when you stick with arrays, as they are fix in their size.
For a more dynamic solution you will need a Collection, such as List - this grow with the data.
Arrays cannot be expanded once created.
So, there are the following solutions.
Create array of needed size. You can achieve this if you know the array size before reading the data.
create new array once you have to "expand" it and copy data from the small array to the bigger one. Then continue to fill the bigger array. You can use System.arraycopy() or implement the logic yourself
Use any implementation of java.util.List instead of array.
BTW unless this is a school exercise avoid using 2 dimensional array in this case. I'd recommend you to define your custom class with 2 fields name and text and then use 1 dimensional array or list according to your choice.
If you have a different amount of Rows, and you can't excatly say how much rows it will be you should use ArrayList instead of an array with an fixed size. To an ArrayList you can add as muchs values as you want. The Problem is, that an Array, once it is created, cant be resized.
To this List you could save Objects of your own type(to handle your data) like this:
public class TableRow {
private String agr_name;
private String text;
private int entryNr;
public TableRow(String agr_name, String text, int entryNr) {
this.agr_name = agr_name;
this.text = text;
this.entryNr = entryNr;
}
public String getAgr_name() {
return agr_name;
}
public void setAgr_name(String agr_name) {
this.agr_name = agr_name;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getEntryNr() {
return entryNr;
}
public void setEntryNr(int entryNr) {
this.entryNr = entryNr;
}
}
This used to your code should look like that:
ArrayList<TableRow> allRows = new ArrayList<>();
for (int j = 0; j < tblRoDe.getNumRows(); j++) {
tblRoDe.setRow(j);
TableRow trow = new TableRow(tblRoDe.getString("AGR_NAME"), tblRoDe.getString("TEXT"), j);
allRows.add(trow);
logger.debug("------- Start Entry #" + trow.getEntryNr() + " -------");
logger.debug("AGR_Name: " + trow.getAgr_name());
logger.debug("TEXT: " + trow.getText());
logger.debug("------- End Entry #" + trow.getEntryNr() + " -------");
}
Hope that helps!
You can't manipulate the array size after creating it , so Use List as it can grow and it's considered as a dynamic solution
List<List<String>> ssRet = new ArrayList<ArrayList<String>>();
List<String> temp=ArrayList<String>(); //creating temp list
temp.add("AGR_NAME");
temp.add("TEXT");
ssRet.add(temp);
for(int j=0; j<tblRoDe.getNumRows(); j++ )
{
tblRoDe.setRow( j );
temp.clear();//clear list instead of creating new one
temp.add(tblRoDe.getString("AGR_NAME"));
temp.add(tblRoDe.getString("TEXT"));
ssRet.add(temp);
}
To get the data :-
for(int i = 0 ; i < ssRet.size() ; i++){
for(int j = 0 ; j < ssRet.get(i).size() ; j++){
System.out.println("The "+(i+1) + " array data");
System.out.println(ssRet.get(i).get(j));
}
}
I have a JTable with 4 columns (name, category, duration, file size) and JTextField in which I enter phrases to find specific records in that JTable.
I'd need a Regex formula, which'd filter the records in this way:
JTable:
name | category | duration | file size
Linkin.Park | cat1 | 00:03:30 | 5,30
If I enter phrase: kin - it will show all songs which have "kin" inside the name.
If I enter phrase: lin*ar* - it will show all songs which start with "lin", then have any amount of characters, then have "ar" and then any amount of characters.
If I enter phrase: lin?in* - it will show all songs wich start with "lin", then have 1 character, then have "in" and then any amount of characters.
Also, I need that filter to only consider the first column of the JTable (name), for example, writing: 30* will show songs wich start with 30, but not those which don't start with it but have the duration for example 3:30 or file size for example 7,30.
I'm sorry for my english xD.
I have this kind of search right now:
private void search(String text) {
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableUtwory.getModel());
tableUtwory.setRowSorter(sorter);
String regex;
if(text.startsWith("*") && text.endsWith("*")) {
String s = Pattern.quote(text.replaceAll("^\\*|\\*$", ""));
regex = "(?i).+" + s + ".+";
} else if(text.startsWith("*")) {
String s = Pattern.quote(text.replaceAll("^\\*", ""));
regex = "(?i).+" + s + "$";
} else if(text.endsWith("*")) {
String s = Pattern.quote(text.replaceAll("\\*$", ""));
regex = "(?i)^" + s + ".+";
} else {
String s = Pattern.quote(text);
regex = "(?i)^" + s + "$";
}
sorter.setRowFilter(RowFilter.regexFilter(regex));
sorter.setSortKeys(null);
}
But it doesn't return any result if I insert "*" between characters (for example lin*ar*), and I don't have the option to use "?". Also, as for now it also considers other columns, not only name column, so if I enter "30*" it returns also songs which size or duration have 30.
The second part of your question:
You have to only go through the first column of the dataValues (or whatever you called it) two dimension array, like:
for (int i=0; i<=dataValues.length; i++) {
String s = dataValues[i][0];
}
Anyway, could you provide more information about your JTable, especially the data model?
For the first part:
The easiest way is to read the JTextField into a regex, but you have to make sure, that it only contains * and/or ? as regex characters then try to match it up with the String s value above. And you have to transform the ? to .{1} and the * to .*
If not you are the one setting the datavalues for the JTable, then you can get them directly from the JTable...
public static Object[][] getTableData(JTable table) {
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
int nRow = dtm.getRowCount(), nCol = dtm.getColumnCount();
Object[][] tableData = new Object[nRow][nCol];
for (int i = 0 ; i < nRow ; i++)
for (int j = 0 ; j < nCol ; j++)
tableData[i][j] = dtm.getValueAt(i,j);
return tableData;
}
Object[][] dataValues = getTableData(YourJTable);
String regex;
if (s.indexOf("*") != -1) {
regex = s.replaceAll("*", ".*");
}
if (regex.indexOf("?") != -1) {
regex = regex.replaceAll("?", ".{1}");
}
for (int i=0; i<=dataValues.length; i++) {
String s2 = (String) dataValues[i][0];
if (s2.matches(regex)) {
System.out.println("Match: " + s2);
} else {
System.out.println("Not match: " + s2); //for debugging
}
}
}
Note that, if someone writes any special characters or combination for regex in the JTextField, then it messes up everything... so you have to care of the proper input.