I have the following code, that allows me to remove a row from the right Jtable with a click. It works fine for all the rows, except when there is only one row remaining. BTW, sorry for most names being in portuguese, its my native language. Here are the images showing before and after i click the final row in the table. It updates the total, but the row remains. For every other case, it works perfectly.
Screenshot:
private void jtbSelecionadosMouseClicked(java.awt.event.MouseEvent evt)
{
int x = jtbSelecionados.rowAtPoint(evt.getPoint());
if (x >= 0)
{
String nomeProduto = (String)jtbSelecionados.getModel().getValueAt(x, 0);
for (int i = 0; i < itensVenda.size();i++)
{
if (itensVenda.get(i).getNomeProduto().equals(nomeProduto))
{
if(itensVenda.get(i).getQtd() > 1)
{
valorTotal -= (itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd());
double precototal = itensVenda.get(i).getPreco();
double unit = precototal / itensVenda.get(i).getQtd();
System.out.println("Unidade: "+unit+"\nTotal: "+precototal);
itensVenda.get(i).setPreco(itensVenda.get(i).getPreco() - (itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd()));
itensVenda.get(i).setQtd(itensVenda.get(i).getQtd() - 1);
recarregarTabela();
}
else if(itensVenda.get(i).getQtd() <= 1)
{
valorTotal -= itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd();
itensVenda.remove(i);
recarregarTabela();
}
}
}
}
function that resets the table with new information:
private void recarregarTabela()
{
if (itensVenda.size() == 0)
{
dtm.getDataVector().removeAllElements();
dtm.setRowCount(0);
lblTotal.setText("Total: R$" + String.valueOf(valorTotal));
}
else
{
dtm.getDataVector().removeAllElements();
dtm.setRowCount(0);
for (Item item : itensVenda)
{
Object[] vetor = new Object[3];
vetor[0] = item.getNomeProduto();
vetor[1] = item.getQtd();
vetor[2] = String.format("%.2f", item.getPreco());
System.out.println(item.getPreco());
dtm.addRow(vetor);
}
lblTotal.setText("Total: R$" + String.valueOf(valorTotal));
}
}
You dont have to rebuild whole model everytime a single row is deleted. As you already have index of clicked or selected row you can just remove it from model using removeRow(index) method. I suspect that dtm is a DefaultTableModel so just call dtm.removeRow(index) everytime you need to remove row from table
Related
public void setForm(mhs m)
{
String[] jurusan = {"TI","SI"};
JComboBox<String> cjurusan = new JComboBox<String> (jurusan);
String st;
st = ((String)m.getJurusan()).toUpperCase();
for(int i = 0; i < cjurusan.getItemCount(); i++)
{
String jur = ((String) cjurusan.getItemAt(i)).toUpperCase();
if(jur.equals("SI"))
{
cjurusan.setSelectedIndex(1);
}
else
{
cjurusan.setSelectedIndex(0);
}
}
tnim.setText(m.getNim());
tnama.setText(m.getNama());
cjurusan.setBounds(110,70,90,20);
add(cjurusan);
}
}
I want to set jcombobox's value according the data record in jtable, till now, I just get the data value at the first time, for second time the jcombobox's value is the same with last. please help. many thanks.
This is my sample image program : screenshoot
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 ran out of ideas on how to perform search in table layout using textfield. I just want to match the text of textfield with 1st column text, if it exist, show the entire row containing that text.I have done it in list and table component but in table layout everything i do is just not working. Any help is appreciated.
TableLayout tl1 = new TableLayout(1, 2);
Container containerTableData = new Container(tl1);
for (int i = 1; i < 3; i++) {
Container tableNameDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
tableNameData = new TextArea("Table Name " + i);
tableNameDataContainer.add(tableNameData);
Container inaugurationDateDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
inaugurationDateData = new TextArea("Inauguration Date 1");
inaugurationDateDataContainer.add(inaugurationDateData);
containerTableData.add(tl1.createConstraint().widthPercentage(50), tableNameDataContainer);
containerTableData.add(tl1.createConstraint().widthPercentage(50), inaugurationDateDataContainer);
containerTableData.revalidate();
}
TextField searchTextField = new TextField();
searchTextField.addDataChangeListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
String getTextAreaData = tableNameData.getText();
String getTextField = searchTextField.getText();
if (getTextAreaData.startsWith(getTextField)) {
}
}
}
Update 1:
To add black and white strips design to the table as in fig below:
Mycode so far:
for (int i = 1; i < 3; i++) {
Container tableNameDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
tableNameData = new TextArea("Table Name " + i);
tableData(tableNameData, i, tableNameDataContainer);
tableNameDataContainer.add(tableNameData);
Container inaugurationDateDataContainer = new Container(new FlowLayout(Component.CENTER, Component.CENTER));
inaugurationDateData = new TextArea("Inauguration Date 1");
tableData(inaugurationDateData, i, inaugurationDateDataContainer);
inaugurationDateDataContainer.add(inaugurationDateData);
containerTableData.add(tl1.createConstraint().widthPercentage(50), tableNameDataContainer);
containerTableData.add(tl1.createConstraint().widthPercentage(50), inaugurationDateDataContainer);
}
method to add desired style
public void tableData(TextArea textAreaName, int i, Container c) {
textAreaName.setName(textAreaName.getText());
c.setName("c" + i);
zeroPaddingMargin(textAreaName);
zeroPaddingMargin(c);
textAreaName.setUIID(textAreaName.getText());
textAreaName.getAllStyles().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL));
textAreaName.setEditable(false);
textAreaName.setGrowByContent(true);
textAreaName.setGrowLimit(2);
textAreaName.getAllStyles().setBgTransparency(0);
c.getAllStyles().setBgTransparency(255);
textAreaName.getAllStyles().setFgColor(0x000000);
if (i % 2 == 0) {
c.getAllStyles().setBgColor(0xcccccc);
} else {
c.getAllStyles().setBgColor(0xffffff);
}
textAreaName.getAllStyles().setPadding(0, 0, 0, 0);
textAreaName.getAllStyles().setMargin(0, 0, 0, 0);
textAreaName.getAllStyles().setAlignment(Component.CENTER);
}
public void zeroPaddingMargin(Component a) {
a.setUIID("Uiid" + a.getName());
a.getAllStyles().setPadding(0, 0, 0, 0);
a.getAllStyles().setMargin(0, 0, 0, 0);
}
The black and white strip style in table rows appears as abov img at first but all the styles disappears as soon as i search in the textfield. I managed to achieve those styles somehow though i think it is not the standard way to do that. Is there any standard way to achieve that?
Didn't try it but I'm guessing this should work. It will require making containerTableData final:
searchTextField.addDataChangeListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
String getTextField = searchTextField.getText().toLowerCase();
int counter = 0;
boolean show = false;
for(Component c : containerTableData) {
if(counter % 2 == 0) {
Container cnt = (Container)c;
TextArea ta = (TextArea)cnt.getComponentAt(0);
show = ta.getText().toLowerCase().indexOf(getTextField) > -1);
}
counter++;
c.setHidden(!show);
c.setVisible(show);
}
containerTableData.animateLayout(200);
}
}
Edited the answer to hide/show the entire row. It relies on searching only in the first column and on there being two columns but that should be easily adaptable.
I am using GWT 2.5 in a project and I had to add a double click event in a table, where I have to take both row and column, so, based on previous questions I created the following:
cellTable.addCellPreviewHandler(new CellPreviewEvent.Handler<BusStopsInfo>() {
long lastClick=-1000;
#Override
public void onCellPreview(CellPreviewEvent<BusStopsInfo> event) {
long clictAt = System.currentTimeMillis();
if(event.getNativeEvent().getType().contains("click")){
if(clictAt-lastClick < 500) { // dblclick on 2 clicks detected within 500 ms
if (BrowserEvents.CLICK.equalsIgnoreCase(event.getNativeEvent().getType())) {
int columnHit = event.getColumn();
if (selectedItems != null){
selectedItems.clear();
selectionModel.clear();
}
selectedItems = new ArrayList<BusStopsInfo>();
Set<HasData<BusStopsInfo>> bsinfos = dataProvider.getDataDisplays();
Iterator<HasData<BusStopsInfo>> iter = bsinfos.iterator();
HasData<BusStopsInfo> bsinfo = iter.next();
Iterable<BusStopsInfo> iterbs = bsinfo.getVisibleItems();
int counterbs = 0;
for (BusStopsInfo bs : iterbs){
if (counterbs == event.getIndex()){
selectedItems.add(bs);
break;
}
counterbs++;
}
if (columnHit == 8){
edit_associations.click();
} else{
edit.click();
}
}
}
lastClick = System.currentTimeMillis();
}
}
});
I also use pagination (SimplePager) in my tables, so, the above code is working fine in the first page of the table, but it doesn't work in other pages than first. Does anyone have any suggestion?
I identified the error. Just in case it will help other people the error is here:
if (counterbs == event.getIndex()){
selectedItems.add(bs);
break;
}
replace with:
if (counterbs == (event.getIndex() - (pagertop.getPage()*pagertop.getPageSize()))){
selectedItems.add(bs);
break;
}
because dataProvider starts from 0 in each page.
I am looking to get the value of the selected row in an AbstractTableModel and I am noticing some things. It is correctly reporting what sell (row) I am on, when it is selected, but as soon as I click my button to remove, the selected row value goes to 0. Resulting in the 0 row always being removed. I want to get the value int selectedRow and use it to remove it from the table and my ArrayLists.
ListSelectionModel rsm = table.getSelectionModel();
ListSelectionModel csm = table.getColumnModel().getSelectionModel();
csm.addListSelectionListener(new SelectionDebugger(columnCounter,csm));
columnCounter = new JLabel("(Selected Column Indices Go Here)");
columnCounter.setBounds(133, 62, 214, 14);
csm.addListSelectionListener(new SelectionDebugger(columnCounter,csm));
contentPane1.add(columnCounter);
rowCounter = new JLabel("(Selected Column Indices Go Here)");
rowCounter.setBounds(133, 36, 214, 14);
rsm.addListSelectionListener(new SelectionDebugger(rowCounter, rsm));
contentPane1.add(rowCounter);
SelectionDebugger:
public class SelectionDebugger implements ListSelectionListener {
JLabel debugger;
ListSelectionModel model;
public SelectionDebugger(JLabel target, ListSelectionModel lsm) {
debugger = target;
model = lsm;
}
public void valueChanged(ListSelectionEvent lse) {
if (!lse.getValueIsAdjusting()) {
// skip all the intermediate events . . .
StringBuffer buf = new StringBuffer();
int[] selection = getSelectedIndices(model.getMinSelectionIndex(),
model.getMaxSelectionIndex());
if (selection.length == 0) {
buf.append("none");
//selectedRow = buf.toString();
}
else {
for (int i = 0; i < selection.length -1; i++) {
buf.append(selection[i]);
buf.append(", ");
}
buf.append(selection[selection.length - 1]);
}
debugger.setText(buf.toString());
System.out.println("CampaignConfiguration: Selected Row: " + selection[selection.length - 1]);
// Set the selected row for removal;
selectedRow = selection[selection.length - 1];
}
}
// This method returns an array of selected indices. It's guaranteed to
// return a nonnull value.
protected int[] getSelectedIndices(int start, int stop) {
if ((start == -1) || (stop == -1)) {
// no selection, so return an empty array
return new int[0];
}
int guesses[] = new int[stop - start + 1];
int index = 0;
// manually walk through these . . .
for (int i = start; i <= stop; i++) {
if (model.isSelectedIndex(i)) {
guesses[index++] = i;
}
}
// ok, pare down the guess array to the real thing
int realthing[] = new int[index];
System.arraycopy(guesses, 0, realthing, 0, index);
return realthing;
}
}
}
The TableModel has nothing to do with selection. The View(JTable) is responsible for the selection.
I want to get the value int selectedRow and use it to remove it from the table and my ArrayLists.
You should NOT have separate ArrayLists. The data should only be contained in the TableModel.
If you want to delete a row from the table (and the TableModel) then you can use the getSelectedIndex() method of the table in your ActionListener added to the "Delete" button. Something like:
int row = table.getSelectedIndex();
if (row != -1)
{
int modelRow = table.convertRowIndexToModel( row );
tableModel.removeRow( modelRow );
}
If you are not using the DefaultTableModel, then your custom TableModel will need to implement the "removeRow(...)" method.