Getting true selected value of JTable - java

I'm currently getting the value of my jTable as everybody does:
String d = jTable1.getModel().getValueAt( jTable1.getSelectedRow() , row ).toString();
The thing is that now I'm sorting my jTable with a rowsorter:
sorter = new TableRowSorter<TableModel>(modelo);
jTable1.setRowSorter(sorter);
private void filterTable(){
//If current expression doesn't parse, don't update.
try {
rf = RowFilter.regexFilter("(?iu)"+jFilter.getText(),0,1,2,3,4);//no filtrar la columna con imágenes porque hace cualquiera
} catch (java.util.regex.PatternSyntaxException e) {
return;
}
sorter.setRowFilter(rf);
}
THE PROBLEM:
Once the table is filtered, the function getSelectedRow returns the correct row, but the getModel function returns the original model, not the one after filtering...
THE QUESTION:
How to get the correct value from the table when it is filtered?

You probably need to convert your "row" value to a model index value, using convertRowIndexToModel.
String d = Table1.getModel().getValueAt(convertRowIndexToModel(jTable1.getSelectedRow()) , column ).toString();

For future wanderers:
The problem was on the way of getting the value from the jTable:
This is wrong when you have a rowsorter:
String d = jTable1.getModel().getValueAt( jTable1.getSelectedRow() , row ).toString();
This is what you should be doing:
String d = jTable1.getValueAt( jTable1.getSelectedRow() , row ).toString();

Related

JTable when searched - not getting right ID

So I'm trying to after searching a name click on the table and then edit it in other table, the problem is that I'm not getting the right ID but instead only getting the ID that is the first.
JTable
Search in action
ID wrong
Edit Code
int linha = this.jTable1.getSelectedRow();
int idUtilizador = Integer.parseInt((String)(this.jTable1.getModel() ).getValueAt(linha, 0));
Utilizador uti = UtilizadorJpaController.read(idUtilizador);
CriarCliente updateCliente = new CriarCliente(uti);
updateCliente.setVisible(true);
Search Code
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
TableRowSorter<DefaultTableModel> tr = new TableRowSorter<DefaultTableModel>(model);
jTable1.setRowSorter(tr);
tr.setRowFilter(RowFilter.regexFilter(jTextField1.getText().trim(),1))
When you sort or filter a table, the data in the TableModel doesn't change. Only the view of the data changes.
If you want to get the data from the model, then you need to convert the "view row" to the "model row":
int linha = this.jTable1.getSelectedRow();
int modelRow = jTable1.convertRowIndexToModel(linha);
int idUtilizador = Integer.parseInt((String)(this.jTable1.getModel() ).getValueAt(modelRow, 0));
//int idUtilizador = Integer.parseInt((String)(this.jTable1.getModel() ).getValueAt(linha, 0));
Also, why are you using Integer.parseInt(...)? If the data in the model is an integer value, then it should be stored as an Integer value, not a String value.

Java - Parse delimited file and find column datatypes

Is it possible to parse a delimited file and find column datatypes? e.g
Delimited file:
Email,FirstName,DOB,Age,CreateDate
test#test1.com,Test User1,20/01/2001,24,23/02/2015 14:06:45
test#test2.com,Test User2,14/02/2001,24,23/02/2015 14:06:45
test#test3.com,Test User3,15/01/2001,24,23/02/2015 14:06:45
test#test4.com,Test User4,23/05/2001,24,23/02/2015 14:06:45
Output:
Email datatype: email
FirstName datatype: Text
DOB datatype: date
Age datatype: int
CreateDate datatype: Timestamp
The purpose of this is to read a delimited file and construct a table creation query on the fly and insert data into that table.
I tried using apache validator, I believe we need to parse the complete file in order to determine each column data type.
EDIT: The code that I've tried:
CSVReader csvReader = new CSVReader(new FileReader(fileName),',');
String[] row = null;
int[] colLength=(int[]) null;
int colCount = 0;
String[] colDataType = null;
String[] colHeaders = null;
String[] header = csvReader.readNext();
if (header != null) {
colCount = header.length;
}
colLength = new int[colCount];
colDataType = new String[colCount];
colHeaders = new String[colCount];
for (int i=0;i<colCount;i++){
colHeaders[i]=header[i];
}
int templength=0;
String tempType = null;
IntegerValidator intValidator = new IntegerValidator();
DateValidator dateValidator = new DateValidator();
TimeValidator timeValidator = new TimeValidator();
while((row = csvReader.readNext()) != null) {
for(int i=0;i<colCount;i++) {
templength = row[i].length();
colLength[i] = templength > colLength[i] ? templength : colLength[i];
if(colHeaders[i].equalsIgnoreCase("email")){
logger.info("Col "+i+" is Email");
} else if(intValidator.isValid(row[i])){
tempType="Integer";
logger.info("Col "+i+" is Integer");
} else if(timeValidator.isValid(row[i])){
tempType="Time";
logger.info("Col "+i+" is Time");
} else if(dateValidator.isValid(row[i])){
tempType="Date";
logger.info("Col "+i+" is Date");
} else {
tempType="Text";
logger.info("Col "+i+" is Text");
}
logger.info(row[i].length()+"");
}
Not sure if this is the best way of doing this, any pointers in the right direction would be of help
If you wish to write this yourself rather than use a third party library then probably the easiest mechanism is to define a regular expression for each data type and then check if all fields satisfy it. Here's some sample code to get you started (using Java 8).
public enum DataType {
DATETIME("dd/dd/dddd dd:dd:dd"),
DATE("dd/dd/dddd",
EMAIL("\\w+#\\w+"),
TEXT(".*");
private final Predicate<String> tester;
DateType(String regexp) {
tester = Pattern.compile(regexp).asPredicate();
}
public static Optional<DataType> getTypeOfField(String[] fieldValues) {
return Arrays.stream(values())
.filter(dt -> Arrays.stream(fieldValues).allMatch(dt.tester)
.findFirst();
}
}
Note that this relies on the order of the enum values (e.g. testing for datetime before date).
Yes it is possible and you do have to parse the entire file first. Have a set of rules for each data type. Iterate over every row in the column. Start of with every column having every data type and cancel of data types if a row in that column violates a rule of that data type. After iterating the column check what data type is left for the column. Eg. Lets say we have two data types integer and text... rules for integer... well it must only contain numbers 0-9 and may begin with '-'. Text can be anything.
Our column:
345
-1ab
123
The integer data type would be removed by the second row so it would be text. If row two was just -1 then you would be left with integer and text so it would be integer because text would never be removed as our rule says text can be anything... you dont have to check for text basically if you left with no other data type the answer is text. Hope this answers your question
I have slight similar kind of logic needed for my project. Searched lot but did not get right solution. For me i need to pass string object to the method that should return datatype of the obj. finally i found post from #sprinter, it looks similar to my logic but i need to pass string instead of string array.
Modified the code for my need and posted below.
public enum DataType {
DATE("dd/dd/dddd"),
EMAIL("#gmail"),
NUMBER("[0-9]+"),
STRING("^[A-Za-z0-9? ,_-]+$");
private final String regEx;
public String getRegEx() {
return regEx;
}
DataType(String regEx) {
this.regEx = regEx;
}
public static Optional<DataType> getTypeOfField(String str) {
return Arrays.stream(DataType.values())
.filter(dt -> {
return Pattern.compile(dt.getRegEx()).matcher(str).matches();
})
.findFirst();
}
}
For example:
Optional<DataType> dataType = getTypeOfField("Bharathiraja");
System.out.println(dataType);
System.out.println(dataType .get());
Output:
Optional[STRING]
STRING
Please note, regular exp pattern is vary based on requirements, so modify the pattern as per your need don't take as it is.
Happy Coding !

Java Inserting into database adds new data and it replaces the first row

This is the code for my button, which inserts the data that has been changed in the text boxes of the GUI, once it is pressed.
I have been getting an issue where it adds a new row of data when I press insert, but it also replaces the first row in the table, so I end up having the first and last row equal in all aspects.
May you please help me? It be appreciated.
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Tblstudents stud = new Tblstudents();
int row = jTable1.getRowCount();
row++;
stud.setStudentid(row);
stud.setFirstname(jTextField2.getText());
stud.setSurname(jTextField3.getText());
String BirthD = dateD.getText();
SimpleDateFormat sdf1 = new SimpleDateFormat ("yyy-MM-dd");
try
{
Date date = null;
date = sdf1.parse(BirthD);
stud.setBirthdate(date);
} catch (ParseException ex)
{}
stud.setGrade(jTextField4.getText());
stud.setHouseid (Integer.parseInt(jTextField6.getText()));
StudentHousePUEntityManager.getTransaction().begin();
StudentHousePUEntityManager.persist(stud);
StudentHousePUEntityManager.getTransaction().commit();
tblstudentsList.clear();
tblstudentsList.addAll(tblstudentsQuery.getResultList());
}

Java Changing the color of a certain row in JTable [duplicate]

This question already has answers here:
Change the background color of a row in a JTable
(5 answers)
Closed 8 years ago.
ANSWER:
Im not allowed to post answers... thumbs up stackoverflow!!!
But here it is:
Holy freakin'....
I made it, actualy it was easier than i have thought....
Here's my solution:
tbl_needaction = new javax.swing.JTable()
{
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
Date d = new Date();
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
java.util.Date acdate = null;
Component c = super.prepareRenderer(renderer, row, column);
// Color row based on a cell value
if (!isRowSelected(row))
{
c.setBackground(getBackground());
int modelRow = convertRowIndexToModel(row);
String sd = "";
sd = (String)getModel().getValueAt(modelRow, 5);
try {
acdate = df.parse(sd);
} catch (ParseException ex) {
Logger.getLogger(EditApplicationJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
if (d.compareTo(acdate)>=0){
c.setBackground(Color.RED);
}
}
return c;
}
};
I had to edit this via NotePad++ because NetBeans dosn't allow me to edit the automaticly generated initComponents().
QUESTION:
I know, there are lots and lots examples and tutorials for this issue, but none of them seems to work for me....
Im getting data from a sql-database which i show in a JTable. There is a date called "ActionPoint". Now i want to mark every row red where the "ActionPoint" equals today oder is "smaller" than today.
My Code to conpare today with the "ActionPoint" for ebery row in my jTable:
for(int row = 0;row < dbApplicantsTableModel.getRowCount();row++) {
String sd = "";
sd = (String) dbApplicantsTableModel.getValueAt(row, 5);
try {
acdate = df.parse(sd);
} catch (ParseException ex) {
Logger.getLogger(EditApplicationJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
if (acdate.compareTo(d)<=0){
}
}
So i should have my "row" which now should be painted red.
Can anyone provide a Method which simply gets a row, and then sets the background of this certain row red?
EDIT:
Now my code looks like this:
for(int row = 0;row < dbApplicantsTableModel.getRowCount();row++) {
String sd = "";
sd = (String) dbApplicantsTableModel.getValueAt(row, 5);
try {
acdate = df.parse(sd);
} catch (ParseException ex) {
Logger.getLogger(EditApplicationJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
if (acdate.compareTo(d)<=0){
dbApplicantsTableModel.setRowColour(row, Color.RED);
}
But ist doesnt set any backgrounds red!
Sadly i need a reputation of 10 to post images -.-
i want to mark every row red where the "ActionPoint" equals today oder is "smaller" than today.
Check out Table Row Rendering for an easy approach to solve this problem. The approach overrides the prepareRenderer(...) method of the JTable, so you can add you logic in one place with a simple "if statement".

Sorting JTable by 2 columns that represent time

I have a table that consists of three columns: Name | Date-Time | Description
The values for Date-Time are actually stored 2 separate fields in database table and (Outdated database - can't change, so have to work around it).
I have the following code applied:
tbNotes.setAutoCreateRowSorter(true); //tbNotes is the JTable
DefaultRowSorter sorter = ((DefaultRowSorter) tbNotes.getRowSorter());
ArrayList list = new ArrayList();
list.add(new RowSorter.SortKey(2, SortOrder.DESCENDING)); //column 2 because I have an invisible ID column
sorter.setSortKeys(list);
sorter.sort();
The result produced appears correct - the rows are sorted by date with older items appearing towards the bottom. However, sometimes I see this:
It is obvious that the sort looks at the first character in a string and assumes that 1 is bigger than 0 so 12/28/2011 is larger(newer) than 01/03/2012
How would I go about having a proper sort on my JTable by date?
Thank You
P.S. Here is the code for populating the JTable
try {
DefaultTableModel noteDataModel = new DefaultTableModel() {
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
tbNotes.setModel(noteDataModel);
Object[] objects = new Object[4];
ListIterator<Todonote> todoNoteListIterator = noteList.listIterator();
while (todoNoteListIterator.hasNext()) {
todoNoteEntity = todoNoteListIterator.next();
DateFormat noteDateFormatter = new SimpleDateFormat("MM/dd/yyyy");
String noteDateTime = noteDateFormatter.format(todoNoteEntity.getUserDate())
+ " - " + todoNoteEntity.getUserTime().substring(0, 2) + ":" + todoNoteEntity.getUserTime().substring(2);
objects[0] = todoNoteEntity.getPrimaryKey();
objects[1] = todoNoteEntity.getUserContact().getName();
objects[2] = noteDateTime;
objects[3] = todoNoteEntity.getNotes();
noteDataModel.addRow(objects);
}
Edit 1
I updated the table model with
#Override
public Class getColumnClass(int column) {
for (int row = 0; row < getRowCount(); row++) {
Object o = getValueAt(row, column);
if (o != null) {
return o.getClass();
}
}
return Object.class;
}
It seems to work now, but dates are showing up as Oct 26, 2012 instead of yyyy/MM/dd - HH:mm - how would I fix that?
I'm not sure, but if you want to display a Date object as appointed format like yyyy/MM/dd - HH:mm, why not try the Renderer?

Categories

Resources