How can I prevent duplication of data in JTable?
The for loop determines whether the data contains similar ID.
Yes, it determines and show a JOptionPane which works.
But my problem is that it scans for a duplicate after I setValue on table 2.
I want my program to prevent duplication of data before it setValue on table 2.
public void dProductList(){
table.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 1) {
JTable tbl = (JTable)e.getSource();
int rrow = tbl.getSelectedRow();
if(rrow>=0) {
int dcol = 0;
int rcol = 0;
((DefaultTableModel)table2.getModel()).addRow(new Object[] {0,0,0,0});
while(rcol<table2.getColumnCount()-1) {
table2.setValueAt(table.getValueAt(rrow,rcol),drow,dcol);
totalAmount = totalAmount + (int) table2.getValueAt(drow,3);
rcol++;
dcol++;
if(rcol==table2.getColumnCount()-1) {
drow++;
}
label.setText(String.valueOf(totalAmount));
}
for(int i=0; i<table2.getRowCount()-1;i++){
if(table2.getValueAt(i,0).equals(table2.getValueAt(table2.getRowCount()-1,0))){
JOptionPane.showMessageDialog(null,"item already listed");
}
}
}
}
}
});
}
Use for loop checking just before table2.setValueAt and add only if no duplicate.
You could also keep your data to a Set (eg a HashSet) and check there before adding to your JTable.
Related
I am writing a program where users answer questions by clicking on JTable cells. If the question is answered correctly/incorrectly, the MouseListener changes the value of answeredResult. The program will keep running until there are no available questions (the available array list contains a list of Items, which is a class I created that contains strings event, year, and description, called by getEvent(), getYear(), and getDescription() methods respectively). However, for each question, I want to wait until a mouseClickedEvent is detected before executing the proceeding code (see below).
I know that adding another while loop for waiting is really bad. I've also seen
some answers suggesting to put whatever I want to do in the mouseClicked method, but I don't know how in my case, since I want to repeat it multiple times.
I think another problem is that the program is stuck in the while(available.size()!=0) loop. So it cant detect the mouse click.
Any suggestions on how to make this work?
ArrayList<Item> available = new ArrayList<Item>();
for(int i = 0; i < 5; i++){
available.add(new Item("Event " + i, "Year " + i, "Description " + i));
}
JTable table = new JTable(model);
table.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());
if (row >= 0 && col == 2 && canPlay) {
clickedYear = (String)data[row][col];
if(clickedYear.equals(answerYear)){
answeredResult = 1;
}else{
answeredResult = -1;
}
}
}
});
while(available.size()!=0){
promptPanel.removeAll();
answeredResult = 0; //0-unanswered 1-correct 2-incorrect
int random = (int)(Math.random()*(available.size()-1));
JLabel label = new JLabel(available.get(random).getEvent()+"\n");
promptPanel.add(label);
canPlay = true;
//wait for mouse clicked before proceeding to the next code
if(answeredResult == 1){
JLabel correct = new JLabel("Correct!");
promptPanel.add(correct);
}else if(answeredResult == -1){
JLabel wrong = new JLabel("Wrong.");
promptPanel.add(wrong);
}
revalidate();
repaint();
available.remove(random);
}
This question already has an answer here:
JTable Java Error Stack OverFlow when setvalue to a specific column
(1 answer)
Closed 6 years ago.
I am getting stackoverflow error when I try to change one of columns data when 2 columns of the columns has been edited.
I have 3 columns which are items, quantity, price.
I want to calculate the price when items and quantity has an input. Below is my code:-
itemsTable.getModel().addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
for (int i = 0; i < itemsTable.getRowCount(); i++) {
if (itemsTable.getValueAt(i, 0) != null) {
String item = itemsTable.getValueAt(i, 0).toString();
double price = Double.parseDouble(selectedItem.substring(item.indexOf("RM") + 2, item.length())); //get price from the cell
double qty = Double.parseDouble(itemsTable.getValueAt(i, 1).toString()); //get quantity from cell
itemsTable.setValueAt(price * qty, i, 2); //calculate price * qty and set price
}
}
}
});
I set a combobox that loaded with database data to items column and a JSpinner for quantity
What am I doing wrong? I am new to JTable.
EDIT
Answer:(credits to Titus)
#Override
public void tableChanged(TableModelEvent e) {
if (e.getType() == TableModelEvent.UPDATE && e.getColumn() != 2) {
for (int i = 0; i < itemsTable.getRowCount(); i++) {
if (itemsTable.getValueAt(i, 0) != null) {
...
}
}
}
}
Also wouldn't hurt to limit the loop to going from row e.getFirstRow() thru e.getLastRow(), and maybe updating price in an invokeLater process as well. But titus hit it head on: gotta stop the infinite cascade of change invokes handler which makes change that invokes handler which makes change...
I need to know how to check if there is data in a JTable something like
if(jTextField1.getText().isEmpty()):
then (if jTable1.isEmpty())
...
how I do that?
JTables are not simple components like the jtextfield, like other swing components they have an underlying Data Model, check this example from the javadoc:
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
JTable table = new JTable(dataModel);
Like in every UI object that follows the MVC pattern, you don't use the graphical component to understand the values it has, you use the data model. In you case, save a reference to the Data Model of the JTable you created and call getRowCount to know how much data you have previously loaded.
Also, check the official docs here.
I validate if the jtable is empty with
this code.
private int calculate() {
Vector<Integer> myvector = new Vector();
TableModel mode = new DefaultTableModel();
mode = jTable2.getModel();
int n = mode.getRowCount();
for (int i = 0; i < n; i++) {
if (mode.getValueAt(i, 3) != null) {
myvector.add((Integer) mode.getValueAt(i, 3));
}
}
return myvector.size();
}
//then I validate with a button
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
int numofvalidrows;
numofvalidrows = calculate();
if (numofvalidrows == 0) //if the size of the vector is 0 then the jtable is empty
{
System.out.println("You need to add people to the jtable, because the table is empty");
} else {
// I get the values of the jtable with
for (int i = 0; i < n; i++) {
if (model.getValueAt(i, 3) != null) { //whith this "if" I print only data, not print null of the empty cells in jtable
System.out.print(model.getValueAt(i, 3))
}
}
}
}
i want to add a cloumn to a jtable when a radio button is being clicked. but when i click it twice two columns are being added to the table. here's my code
dtm = (DefaultTableModel) viewTable.getModel();
dtm.setRowCount(0);
TableColumnModel model=viewTable.getColumnModel();
boolean found=false;
for (int i = 0; i < viewTable.getColumnCount(); i++) {
if (model.getColumn(i).getIdentifier().equals("customer Id")) {
found=true;
break;
}
if (found==false) {
dtm.addColumn("customer Id");
}
don't know how to fix it..
This code would help you. Call the below method on actionPerformed of the check box and if it is true. Validating it based on the column header.
private static void addColumn( final JTable table, final String newColumnHeader )
{
final JTableHeader header = table.getTableHeader();
final int columnCount = header.getColumnModel().getColumnCount();
boolean addColumn = true;
for( int index = 0; index < columnCount; index ++ )
{
final Object headerValue = header.getColumnModel().getColumn(index).getHeaderValue();
if( newColumnHeader.equals( headerValue ) )
{
JOptionPane.showMessageDialog(null, "Column already exists" );
addColumn = false;
break;
}
}
if( addColumn )
{
final TableColumn newCol = new TableColumn();
newCol.setHeaderValue(newColumnHeader);
table.getColumnModel().addColumn(newCol);
}
}
It is good to disable the checkbox if it is already clicked ;) if you do not want a huge code.
This is a clumsy solution but it will work.
You can create a new boolean variable in your class and this variable represents if a column was set or not.
Like:
class MyClass{
boolean isColumnAdded
public MyClass(){
isColumnAdded = false;
}
private void radioButtonActionPerformed(java.awt.event.ActionEvent evt){
if(!isColumnAdded){
//add column
isColumnAdded = true;
}
}
}
To start with, JRadioButton has a selected property. You should be checking this state to determine if the column needs to be removed or added...
Assume that each column name is unique, you could use something like...
TableColumnModel model = viewTable.getColumnModel();
int index = -1;
try {
index = model.getColumnIndex("customer Id");
} catch (IllegalArgumentException e) {
// I know, sucks...
}
if (index < 0) {
// Add new column, if JRadioButton.isSelected
} else {
// Remove old column...
// JRadioButton.isSelected is false...
}
To find and add/remove the column.
Have a look at How to Use Buttons, Check Boxes, and Radio Buttons for some more details
What is the best way to verify if a specific combination of two symbols is already selected in a several couples of jcomboboxes? This question is refered to a situation in which I have e. g. 10 options and for each of those I can assign a combination of two symbols where first one is from [ALT, CTRL, SHIFT] vector and second one is from [letters and numbers] vector. Both vectors are visualized in JComboBoxes (for each option are two combo boxes).
Put couples of jcomboboxes into different buckets. Those couples that have ALT selected in first combobox go to the 1st one, those who have CTRL selected - to the 2nd one, SHIFT - to the 3rd one. Then see whether the same option in the second combobox is selected within the buckets.
Thank you everyone for answers. Finally I manage this problem this way:
// Method For KeyGroup 1
public boolean isAlreadyKeyEvent(int index) {
int vector[] = {combo_1_group1.getSelectedIndex(), combo_2_group1.getSelectedIndex(), combo_n_group1.getSelectedIndex()};
int x = 0;
for (int i : vector) {
if (i == index) {
x++;
}
}
if (x > 1) {
return true;
} else {
return false;
}
}
// Method For KeyGroup 2
public boolean isAlreadyInputEvent(int index) {
int vector[] = {combo_1_group2.getSelectedIndex(), combo_2_group2.getSelectedIndex(), combo_n_group2.getSelectedIndex()};
int x = 0;
for (int i : vector) {
if (i == index) {
x++;
}
}
if (x > 1) {
return true;
} else {
return false;
}
}
combo_1_group2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean one = isAlreadyKeyEvent(combo_1_group2.getSelectedIndex());
boolean two = isAlreadyInputEvent(combo_1_group1.getSelectedIndex());
if (one) {
if (two) {
JOptionPane.showMessageDialog(null, "Such shortcut already exists! \n" +
"Choose something else.");
combo_1_group2.setSelectedIndex(Settings.combo_1_group2);
} else {
Settings.combo_1_group2 = combo_1_group2.getSelectedIndex();
}
} else {
Settings.combo_1_group2 = combo_1_group2.getSelectedIndex();
}
}
});
So basically I've wrote two quite similar methods and also I've created a new class with static fields for values store. All works great :)