slow Jtable due to tableChanged method

I create a table model as in the following code. I need that the values of some columns are recalculated based on the change in different columns of the table .

The code that I wrote seems to work correctly but on the other side it slow -down the load of the data in the table. In particular if the tableChanged method is empty to load 10.000 rows 15 seconds are necessary it the method is the one in the code below 1 minute it is necessary .

Any suggestion to improve the performance ?

Thank you very much .

publicclass PriceChangeSTableComponentextends JPanelimplements

TableModelListener{

JTable table;

JTable tableSup;

privateboolean ALLOW_COLUMN_SELECTION =true;

privateboolean ALLOW_ROW_SELECTION =true;

// CONSTRUCTOR //

public PriceChangeSTableComponent(AbstractTableModel model){

super(new GridLayout(1, 0));

// Create sorted model

TableSorter sorter =new TableSorter(model);

table =new JTable(sorter)

{

/*public void changeSelection(int row, int column, boolean toggle,

boolean extend) {

super.changeSelection(row, column, toggle, extend);

if (table.editCellAt(row, column))

table.getEditorComponent().requestFocusInWindow();

}*/

public Component prepareEditor(TableCellEditor editor,int row,int column){

Component c = super.prepareEditor(editor, row, column);

if (cinstanceof JTextComponent){

((JTextField) c).selectAll();

}

returnc;

}

publicboolean editCellAt(int row,int column, EventObject e){

boolean result = super.editCellAt(row, column, e);

final Component editor = table.getEditorComponent();

if (editor !=null && editorinstanceof JTextComponent){

if (e ==null){

((JTextComponent) editor).selectAll();

}else{

SwingUtilities.invokeLater(new Runnable(){

publicvoid run(){

((JTextComponent) editor).selectAll();

}

});

}

}

return result;

}

};

// Header Settings

sorter.setTableHeader(table.getTableHeader());

// Add all necessary listener

// 1. Table Listener (detect data update in the table)

model.addTableModelListener(this);

// 2. Selection Listener (detect data selection)

table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

if (ALLOW_ROW_SELECTION){// true by default

ListSelectionModel rowSM = table.getSelectionModel();

rowSM.addListSelectionListener(new ListSelectionListener(){

publicvoid valueChanged(ListSelectionEvent e){

// Ignore extra messages.

if (e.getValueIsAdjusting())

return;

ListSelectionModel lsm = (ListSelectionModel) e.getSource();

if (lsm.isSelectionEmpty()){

//System.out.println("No rows are selected.");

}else{

int selectedRow = lsm.getMinSelectionIndex();

//System.out.println("Row " + selectedRow

//+ " is now selected.");

}

}

});

}else{

table.setRowSelectionAllowed(false);

}

if (ALLOW_COLUMN_SELECTION){// false by default

if (ALLOW_ROW_SELECTION){

// We allow both row and column selection, which

// implies that we *really* want to allow individual

// cell selection.

table.setCellSelectionEnabled(true);

}

table.setColumnSelectionAllowed(true);

ListSelectionModel colSM = table.getColumnModel()

.getSelectionModel();

colSM.addListSelectionListener(new ListSelectionListener(){

publicvoid valueChanged(ListSelectionEvent e){

// Ignore extra messages.

if (e.getValueIsAdjusting())

return;

ListSelectionModel lsm = (ListSelectionModel) e.getSource();

if (lsm.isSelectionEmpty()){

//System.out.println("No columns are selected.");

}else{

int selectedCol = lsm.getMinSelectionIndex();

//System.out.println("Column " + selectedCol

//+ " is now selected.");

}

}

});

}

//

JScrollPane ScollPanel =new JScrollPane(table);

this.add(ScollPanel);

}

publicvoid changeSelection(int row,int column,boolean toggle,

boolean extend){

table.changeSelection(row, column, toggle, extend);

if (table.editCellAt(row, column))

table.getEditorComponent().requestFocusInWindow();

}

private JComponent prepareEditor(TableCellEditor editor,int row,int column){

Component c = table.prepareEditor(editor, row, column);

if (cinstanceof JTextComponent){

((JTextField) c).selectAll();

}

return (JComponent) c;

}

publicboolean editCellAt(int row,int column, EventObject e){

boolean result = table.editCellAt(row, column, e);

final Component editor = table.getEditorComponent();

if (editor !=null && editorinstanceof JTextComponent){

if (e ==null){

((JTextComponent) editor).selectAll();

}else{

SwingUtilities.invokeLater(new Runnable(){

publicvoid run(){

((JTextComponent) editor).selectAll();

}

});

}

}

return result;

}

public TableModel getModel(){

TableSorter ts = ((TableSorter) table.getModel());

TableModel model = ts.getTableModel();

return model;

}

public JTable getTable(){

return table;

}

publicvoid tableChanged(TableModelEvent e){

if (e.getType() == TableModelEvent.UPDATE){

int column = e.getColumn();

if (column == 11){

int row = e.getFirstRow();

Double newPercentage = (Double) table.getModel().getValueAt(

row, column);

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 1);

Double NewSellPrice =new Double(AvPrice.doubleValue()

* (1 - (newPercentage.doubleValue() / 100)));

Double NewRealDis =new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewSellPrice, row, column + 1);

table.getModel().setValueAt(NewRealDis, row, column + 2);

}

if (column == 12){

int row = e.getFirstRow();

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 2);

Double NewSellPrice = (Double) table.getModel().getValueAt(

row, column);

Double NewRealDis =new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

//table.getModel().setValueAt(NewRealDis, row, column + 1);

}

if (column == 14){

int row = e.getFirstRow();

Double newPercentage = (Double) table.getModel().getValueAt(

row, column - 3);

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 4);

Double NewSellPrice =new Double(AvPrice.doubleValue()

* (1 - (newPercentage.doubleValue() / 100)));

Double NewRealDis =new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

//table.getModel().setValueAt(NewSellPrice, row, column - 2);

//table.getModel().setValueAt(NewRealDis, row, column - 1);

}

}

}

}

[13633 byte] By [bronze-starDukes] at [2007-11-26 12:10:06]
# 1

The table changed method doesn't look like it would take a minute to run? What part of it is slow? Are you sure that it is your bottleneck?

Run a profiler on the code to find the exact problems.

Why is this method: editCellAt defined in two places and what is it doing? (look strange)

silverstar at 2007-7-7 13:47:50 > top of Java-index,Archived Forums,Socket Programming...
# 2

Sorry I make a mistake in the copy/paste of the code . This is the correct code :

package com.bnt.iso.pricechange.swing.util;

import java.awt.Color;

import java.awt.Component;

import java.awt.GridLayout;

import java.awt.Point;

import java.util.EventObject;

import javax.swing.JComponent;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.JTextField;

import javax.swing.ListSelectionModel;

import javax.swing.SwingUtilities;

import javax.swing.event.ListSelectionEvent;

import javax.swing.event.ListSelectionListener;

import javax.swing.event.TableModelEvent;

import javax.swing.event.TableModelListener;

import javax.swing.table.AbstractTableModel;

import javax.swing.table.TableCellEditor;

import javax.swing.table.TableModel;

import javax.swing.text.JTextComponent;

import com.bnt.iso.warehouse.swing.util.TableSorter;

public class PriceChangeSTableComponent extends JPanel implements

TableModelListener {

JTable table;

JTable tableSup;

private boolean ALLOW_COLUMN_SELECTION = true;

private boolean ALLOW_ROW_SELECTION = true;

// CONSTRUCTOR //

public PriceChangeSTableComponent(AbstractTableModel model) {

super(new GridLayout(1, 0));

// Create sorted model

TableSorter sorter = new TableSorter(model);

table = new JTable(sorter)

{

/*public void changeSelection(int row, int column, boolean toggle,

boolean extend) {

super.changeSelection(row, column, toggle, extend);

if (table.editCellAt(row, column))

table.getEditorComponent().requestFocusInWindow();

}*/

public Component prepareEditor(TableCellEditor editor, int row, int column) {

Component c = super.prepareEditor(editor, row, column);

if (c instanceof JTextComponent) {

((JTextField) c).selectAll();

}

returnc;

}

public boolean editCellAt(int row, int column, EventObject e) {

boolean result = super.editCellAt(row, column, e);

final Component editor = table.getEditorComponent();

if (editor != null && editor instanceof JTextComponent) {

if (e == null) {

((JTextComponent) editor).selectAll();

} else {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

((JTextComponent) editor).selectAll();

}

});

}

}

return result;

}

};

// Header Settings

sorter.setTableHeader(table.getTableHeader());

// Add all necessary listener

// 1. Table Listener (detect data update in the table)

model.addTableModelListener(this);

// 2. Selection Listener (detect data selection)

table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

if (ALLOW_ROW_SELECTION) { // true by default

ListSelectionModel rowSM = table.getSelectionModel();

rowSM.addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

// Ignore extra messages.

if (e.getValueIsAdjusting())

return;

ListSelectionModel lsm = (ListSelectionModel) e.getSource();

if (lsm.isSelectionEmpty()) {

//System.out.println("No rows are selected.");

} else {

int selectedRow = lsm.getMinSelectionIndex();

//System.out.println("Row " + selectedRow

//+ " is now selected.");

}

}

});

} else {

table.setRowSelectionAllowed(false);

}

if (ALLOW_COLUMN_SELECTION) { // false by default

if (ALLOW_ROW_SELECTION) {

// We allow both row and column selection, which

// implies that we *really* want to allow individual

// cell selection.

table.setCellSelectionEnabled(true);

}

table.setColumnSelectionAllowed(true);

ListSelectionModel colSM = table.getColumnModel()

.getSelectionModel();

colSM.addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

// Ignore extra messages.

if (e.getValueIsAdjusting())

return;

ListSelectionModel lsm = (ListSelectionModel) e.getSource();

if (lsm.isSelectionEmpty()) {

//System.out.println("No columns are selected.");

} else {

int selectedCol = lsm.getMinSelectionIndex();

//System.out.println("Column " + selectedCol

//+ " is now selected.");

}

}

});

}

//

JScrollPane ScollPanel = new JScrollPane(table);

this.add(ScollPanel);

}

public void changeSelection(int row, int column, boolean toggle,

boolean extend) {

table.changeSelection(row, column, toggle, extend);

if (table.editCellAt(row, column))

table.getEditorComponent().requestFocusInWindow();

}

private JComponent prepareEditor(TableCellEditor editor, int row, int column) {

Component c = table.prepareEditor(editor, row, column);

if (c instanceof JTextComponent) {

((JTextField) c).selectAll();

}

return (JComponent) c;

}

/*public boolean editCellAt(int row, int column, EventObject e) {

boolean result = table.editCellAt(row, column, e);

final Component editor = table.getEditorComponent();

if (editor != null && editor instanceof JTextComponent) {

if (e == null) {

((JTextComponent) editor).selectAll();

} else {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

((JTextComponent) editor).selectAll();

}

});

}

}

return result;

}*/

public TableModel getModel() {

TableSorter ts = ((TableSorter) table.getModel());

TableModel model = ts.getTableModel();

return model;

}

public JTable getTable() {

return table;

}

public void tableChanged(TableModelEvent e) {

if (e.getType() == TableModelEvent.UPDATE) {

int column = e.getColumn();

if (column == 11) {

int row = e.getFirstRow();

Double newPercentage = (Double) table.getModel().getValueAt(

row, column);

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 1);

Double NewSellPrice = new Double(AvPrice.doubleValue()

* (1 - (newPercentage.doubleValue() / 100)));

Double NewRealDis = new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewSellPrice, row, column + 1);

table.getModel().setValueAt(NewRealDis, row, column + 2);

}

if (column == 12) {

int row = e.getFirstRow();

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 2);

Double NewSellPrice = (Double) table.getModel().getValueAt(

row, column);

Double NewRealDis = new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewRealDis, row, column + 1);

}

if (column == 14) {

int row = e.getFirstRow();

Double newPercentage = (Double) table.getModel().getValueAt(

row, column - 3);

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 4);

Double NewSellPrice = new Double(AvPrice.doubleValue()

* (1 - (newPercentage.doubleValue() / 100)));

Double NewRealDis = new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewSellPrice, row, column - 2);

table.getModel().setValueAt(NewRealDis, row, column - 1);

}

}

}

}

With this version loading the table with 10.000 rows and 21 columns need more than 1 minutes (almost 2).

In the case in which I replace the tableChanged method with the following one :

public void tableChanged(TableModelEvent e) {

if (e.getType() == TableModelEvent.UPDATE) {

int column = e.getColumn();

/*if (column == 11) {

int row = e.getFirstRow();

Double newPercentage = (Double) table.getModel().getValueAt(

row, column);

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 1);

Double NewSellPrice = new Double(AvPrice.doubleValue()

* (1 - (newPercentage.doubleValue() / 100)));

Double NewRealDis = new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewSellPrice, row, column + 1);

table.getModel().setValueAt(NewRealDis, row, column + 2);

}

if (column == 12) {

int row = e.getFirstRow();

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 2);

Double NewSellPrice = (Double) table.getModel().getValueAt(

row, column);

Double NewRealDis = new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewRealDis, row, column + 1);

}

if (column == 14) {

int row = e.getFirstRow();

Double newPercentage = (Double) table.getModel().getValueAt(

row, column - 3);

Double AvPrice = (Double) table.getModel().getValueAt(row,

column - 4);

Double NewSellPrice = new Double(AvPrice.doubleValue()

* (1 - (newPercentage.doubleValue() / 100)));

Double NewRealDis = new Double((1 - NewSellPrice.doubleValue()

/ AvPrice.doubleValue()) * 100);

table.getModel().setValueAt(NewSellPrice, row, column - 2);

table.getModel().setValueAt(NewRealDis, row, column - 1);

}*/

}

}

Only 15-20 secods anre necessary.

Thank you and sorry for the mistake.

bronzestar at 2007-7-7 13:47:50 > top of Java-index,Archived Forums,Socket Programming...