I'm developing a tool which is supposed to save the content from a JTable to a CSV file, I have this "add row" button to add a new row, but I need the last row to be filled on every cell and then be allowed to add a new row.
Here is the code I have, but this doesn't create the new row nor throw any errors on console.
private void btnAddRowActionPerformed(java.awt.event.ActionEvent evt) {
for(int i=0;i<=jTable1.getColumnCount();i++){
if(jTable1.isRowSelected(jTable1.getRowCount())){
do{
model.insertRow(jTable1.getRowCount(), new Object[]{});
} while(jTable1.getValueAt(jTable1.getRowCount(), i).equals(""));
}
}
}
Okay, so what you seem to be saying is, the user should not be allowed to add a new row until the last row is fully completed...
You existing loop doesn't make sense, basically, for each column, you are checking to see if the last row is selected, and inserting a new row for each column which is blank ("")...?
Remember, generally Java is zero indexed, this means, the last row is actually jTable1.getRowCount() - 1, so, it's unlikely that your if isRowSelected would be true, which is actually a good thing, cause otherwise you would have had a real mess...
Assuming I understand your question correctly (as it's a little vague), you could try something more like this...
boolean rowCompleted = true;
int lastRow = jTable1.getRowCount() - 1;
if (jTable1.isRowSelected(lastRow)) {
for (int col = 0; col < jTable1.getColumnCount(); col++) {
Object value = jTable.getValueAt(lastRow, col);
if (value == null || value.toString().trim().isEmpty()) {
rowCompleted = false;
break;
}
}
}
if (rowCompleted) {
// Insert new row...
} else {
// Show error message
}
Maybe use a TableModelListener.
Every time a cell is updated on the last row of the table you check to make sure all columns have data. If all columns have data you enable the "Add Row" button, otherwise you disenable the button.
I was checking this post and I used the code posted by MadProgrammer, but I made a few modifications and I got this working properly according to your need. If you want you can ask me for the project and I can happily provide it to you
private void btnAddRowActionPerformed(java.awt.event.ActionEvent evt) {
boolean rowCompleted;
int lastRow = jTable1.getRowCount()-1;
if(jTable1.isRowSelected(lastRow)){
for(int col=0;col<jTable1.getColumnCount();col++){
Object value = jTable1.getValueAt(lastRow, col);
if(value == null || value.toString().trim().isEmpty()){
rowCompleted=false;
}
else{
rowCompleted=true;
}
if(rowCompleted==true){
model.insertRow(jTable1.getRowCount(), new Object[]{});
}
else{
JOptionPane.showMessageDialog(null, "Something went worng. Try this:\n - Please select a row before adding new row.\n - Please verify there are no empty cells","Processing table's data",1);
}
break;
}
}
else{
JOptionPane.showMessageDialog(null, "Something went wrong. Verify this:\n - There is not any row selected.\n - You can only create new rows after last row","Processing table's data",1);
}
}
I hope this could help you, but first say thanks to MadProgrammer :D
Related
I am using poi(v4.0.0) to import the excel document. But when I tried to get the next cell carModelCell, it always return null, this is my Java 8 code looks like:
public void verifyCar(Cell cell, int relativeRowIndex, Head head) {
if (cell.getRowIndex() > 0 && head.getFieldName().equals("car")) {
if (StringUtils.isBlank(cell.getStringCellValue())|| cell.getStringCellValue().equals("无车")) {
return;
}
Cell carModelCell = cell.getRow().getCell(cell.getColumnIndex() + 1);
if (carModelCell == null || StringUtils.isBlank(carModelCell.getStringCellValue())) {
SparkUserParseResult result = new SparkUserParseResult();
result.setSuccess(false);
UploadSparkUserDataListener.parseSuccess.set(result);
return;
}
}
}
I am tried to get row from Cell, and get the next cell value with the same row and do some check, but the next cell carModelCell always return null. I have already sure the next cell of current row have a value. why would this happen? what should I do to fix this problem? This code block was in CellStyleWriteHandler which extend AbstractCellStyleStrategy in easy excel (version 2.2.11):
public class CellStyleWriteHandler extends AbstractCellStyleStrategy {
#Override
protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
impl(cell, head, relativeRowIndex);
}
}
I tried to get the last index num was 14, the current column index number was 13. the total column of my imported excel was 24, seems the easy excel did not pass the full column, is it possible to fix this problem? How to get the next cell of current row?
i also user poi to parse excel, i think problem in this line:
Cell carModelCell = cell.getRow().getCell(cell.getColumnIndex() + 1);
code above is error, becase cell can get from row,like:
Cell cell = sheetColumnRow.getRow()
one raw can cantain many Cell,but you can not get complete row from Cell, Parse row Cell value can not reverse; wish help you;
The aim is to return a clean table that only includes rows that have numeric data within them, from a nominated column.
The code below works for me. But I can’t help but feel there is a better way to do this. Any thoughts on a more elegant solution?
I have the code:
Table removeEmptyRows(Table data, String column_name)
{
IntList rows_to_remove = new IntList();
Table dataCopy = cloneTable(data);
for (int r = 0; r<dataCopy.getRowCount(); r++)
{
String value_string = dataCopy.getString(r, column_name);
///filter out the NaNs
if ( ! isNullOrBlank(value_string))
{
if ( ! isNumeric(value_string) )
{
rows_to_remove.append(r);
}
} else {
rows_to_remove.append(r);
}
}
rows_to_remove.sortReverse();
for (int r : rows_to_remove)
{
dataCopy.removeRow(r);
}
return dataCopy;
}
boolean isNumeric(String inputData) {
return inputData.matches("[-+]?\\d+(\\.\\d+)?");
}
private static boolean isNullOrBlank(String s)
{
return (s==null || s.trim().equals(""));
}
This question might be a better fit at the Code Review Stack Exchange (note that if you post there, please link between crossposts and make sure you post a true MCVE and make it clear that this is a Processing, not Java question), but I'll try to offer some input.
You can simplify your code by adding good rows instead of removing bad rows. Create the returnTable by copying just the columns from the inputTable, then loop over inputTable and only add the valid rows.
Also, take a look at this if statement:
if ( ! isNullOrBlank(value_string) ) {
if ( ! isNumeric(value_string) ) {
rows_to_remove.append(r);
}
}
else {
rows_to_remove.append(r);
}
This will keep a row in one case: if the value is not null or blank and if it is numeric. You can rewrite this logic using a single if statement:
if (!isNullOrBlank(rowValue) && isNumeric(rowValue)){
Putting it all together, it looks like this:
Table removeEmptyRows(Table inputTable, String columnName){
Table returnTable = cloneTable(inputTable);
returnTable.clearRows();
for (int row = 0; row < inputTable.getRowCount(); row++){
String rowValue = inputTable.getString(row, columnName);
if (!isNullOrBlank(rowValue) && isNumeric(rowValue)){
returnTable.addRow(inputTable.getRow(row));
}
}
return returnTable;
}
But note that this code isn't necessarily better than your code. It's not any faster. And if you understood your code, then that's the most important thing. If it works, don't worry too much about making it "more elegant". Just move on to the next thing.
I am working on the TableModelListener for a JTable. Now the jtable can get the value fine. but when it comes down to setting the value of the last column of the selected row. It gets wonky, not sure what the error is it just hangs up. Not seeing any errors on netbeans so not sure what to think. Because of this I am not even sure if the if statements work at all in terms of setting values. Should I be using or doing something else for this to happen ?
Update: It does appear to be an infinite loop. edited the code to a suggestion to check for Update table events but still having the same problem.
Here is the code below:
public class MyListener implements TableModelListener {
#Override
public void tableChanged(TableModelEvent tme) {
if (tme.getType() == TableModelEvent.UPDATE)
{
int rowcount = jDetailSubmitTable.getSelectedRow();
// Initial return when table is starting to be filled.
if(rowcount == -1 )
{
return;
}
int com = tme.getColumn();
// Number being Validated.
if(jDetailSubmitTable.getModel().getValueAt(rowcount, com).toString().trim().isEmpty())
{
JOptionPane.showMessageDialog(null, "Invaid Number selected.");
jDetailSubmitTable.getModel().setValueAt("0", rowcount, com);
return;
}
try
{
Double.parseDouble(jDetailSubmitTable.getModel().getValueAt(rowcount, com).toString().trim());
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "Invaid Number selected.");
jDetailSubmitTable.getModel().setValueAt("0", rowcount, com);
return;
}
// Adjusted amount is calculated below.
double nur = Double.parseDouble(jDetailSubmitTable.getModel().getValueAt(rowcount, 9).toString().trim());
double our = Double.parseDouble(jDetailSubmitTable.getModel().getValueAt(rowcount, 8).toString().trim());
double diff = nur - our;
double nunits = Double.parseDouble(jDetailSubmitTable.getModel().getValueAt(rowcount, 11).toString().trim());
double ans = diff * nunits;
jDetailSubmitTable.getModel().setValueAt(ans, rowcount, 12);
}
}
}
The following line will get the selected row index, that index being a view index since you ask this from the JTable instance:
int rowcount = jDetailSubmitTable.getSelectedRow();
Later on you use this view index to index the model:
jDetailSubmitTable.getModel().getValueAt(rowcount, com)
You should first convert this view index to a model index using JTable.convertRowIndexToModel:
int selrowid = jDetailSubmitTable.getSelectedRow();
selrowid = jDetailSubmitTable.convertRowIndexToModel(selrowid);
[...]jDetailSubmitTable.getModel().getValueAt(selrowid, com)[...]
I gave a longer explanation about view vs model and the need to convert indexes in this answer on SO.
Update: #camickr made the correct observation that you should be using the data that comes with the TableModelEvent, i.e. TableModelEvent.getFirstRow(), TableModelEvent.getLastRow() and TableModel.getColumn(). These methods return model indexes.
For a Java Schoolproject I would like to have a table from witch you can select a Item that then shows up on a new window. In that window you can change things like ComboBoxes and others. My only problem is, that I dont know how to select the Item of the ComboBox I need. All the ComboBoxItems are Objects and I dont know how to handle this.
My ComboBoxItem looks like this:
Apprentice [person=Person, DB ID: 9, Kappa Kappa, Kappastrasse 21,
CityID: 4521, kappa.kappa#kappa.ch, idpersonen=9,
vertragsstart=2020-01-02, ausbildungsct=2, id=6]
Now, my Question is, how do I select the ComboBoxitem where the id=6, all the things I found needed the whole Object to select a special Item. How would you guys go at this problem?
Good luck and thanks for the Help.
Bono
All I had to do was a really simple while with a for and a if.
int trys = 0;
while (0 == apprenticeComboBoxZeugnis.getItemCount() && trys < 10000) {
System.out.println(apprenticeComboBoxZeugnis.getItemCount());
for (int i = 0; i < apprenticeComboBoxZeugnis.getItemCount(); i++) {
apprenticeComboBoxZeugnis.setSelectedIndex(i - 1);
int spacko = getApprenticeCombo();
if (spacko == lehrlingsid) {
TableFilterListenerZeugnis tableFilterListenerZeugnis = new TableFilterListenerZeugnis(
this);
tableFilterListenerZeugnis.updateNoten();
break;
}
}
trys++;
}
This first trys until the number of Objects is not = 0 and after that looks at every object, cuts out the id with getApprenticeCombo() and compares it with my id I allready have. If they match it breaks out and is done with it.
I have a JTable of which one column is pre-filled with 30min time slots (6.30-24.00).
Now I have another table which has a list of movie titles which contains a column with the duration of the movie (in minutes - e.g. 140 minutes).
Now I have a button that does this. I made a piece of code, which funnily enough, sometimes works and sometimes doesn't (after I add 3-4 titles). It adds to the time slots according to the math equation.It gives me :
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "DRAMA"
This is the code:
btnAddProg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
int dur = Integer.parseInt(progTableModel.getValueAt(listTable.getSelectedRow(), listTable.getSelectedColumn()+1).toString()) / 30;
int durT = Integer.parseInt(progTableModel.getValueAt(listTable.getSelectedRow(), listTable.getSelectedColumn()+1).toString());
if(durT % 30 != 0)
{
dur += 1;
}
for(int i = 0; i < dur; i++)
{
String value = progTableModel.getValueAt(listTable.getSelectedRow(), listTable.getSelectedColumn()).toString();
String value2 = progTableModel.getValueAt(listTable.getSelectedRow(), listTable.getSelectedColumn()+2).toString();
channel1DataTitle.set(chOneTable.getSelectedRow()+i, value);
channel1DataGenre.set(chOneTable.getSelectedRow()+i, value2);
}
chOneTable.repaint();
} catch (IndexOutOfBoundsException f) {
JOptionPane.showMessageDialog(frame,
"Please select a row in the Channel table!",
"Channel row not selected",
JOptionPane.PLAIN_MESSAGE);
}
}
});
Can anyone tell me what's wrong?
It works when you click on the proper column and fails when you click on another, doesn't it? You have fixed logic (parsing the duration number) applied to a variable column (depending on the exact column the user clicked). Access the column with a fixed number, don't check for the selected column index.
You are trying to parse a String which does not translate into a number. It looks like the problem is you are working off of whatever the user has selected. You either need to restrict the data you are processing to be from certain columns in your table, or validate the data before trying to process it.