Issue Details (XML | Word | Printable)

Key: UBA-7636
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Janak Mulani
Reporter: Janak Mulani
Votes: 1
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
ULCBase

Dragging large number of rows and columns from ULCTable results in OutOfMemory error.

Created: 17/Dec/08 10:33 AM   Updated: 05/Feb/09 10:56 AM
Component/s: dnd
Affects Version/s: UltraLightClient '08 Update 1
Fix Version/s: UltraLightClient '08 Update 2

Issue Links:
Part
 
Reference
 


 Description  « Hide
Dragging large number of rows and columns from ULCTable results in OutOfMemory error.

In the snippet below select entire table with ctrl-A and then drag. This results in the following a exception:

Exception in thread "AWT-EventQueue-1" java.lang.OutOfMemoryError: Java heap space
	at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
	at java.awt.image.Raster.createPackedRaster(Raster.java:458)
	at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1015)
	at java.awt.image.BufferedImage.<init>(BufferedImage.java:340)
	at com.ulcjava.base.client.dnd.DnDUtilities.createDragImage(DnDUtilities.java:27)
	at com.ulcjava.base.client.dnd.DnDUtilities.createDragImage(DnDUtilities.java:32)
	at com.ulcjava.base.client.UITable$TableDragGestureListener.createDragImage(UITable.java:19)
	at com.ulcjava.base.client.dnd.AbstractDragGestureListener.dragGestureRecognized(AbstractDragGestureListener.java:12)
	at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(DragGestureRecognizer.java:339)
	at com.ulcjava.base.client.dnd.DefaultDragGestureRecognizer.b(DefaultDragGestureRecognizer.java:3)
	at com.ulcjava.base.client.dnd.DefaultDragGestureRecognizer.a(DefaultDragGestureRecognizer.java:20)
	at com.ulcjava.base.client.dnd.DefaultDragGestureRecognizer.isBlockingMouseEvent(DefaultDragGestureRecognizer.java:43)
	at com.ulcjava.base.client.UITable$BasicTable.processMouseMotionEvent(UITable.java:37)
	at java.awt.Component.processEvent(Component.java:5810)
	at java.awt.Container.processEvent(Container.java:2058)
	at java.awt.Component.dispatchEventImpl(Component.java:4413)
	at java.awt.Container.dispatchEventImpl(Container.java:2116)
	at java.awt.Component.dispatchEvent(Component.java:4243)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4003)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
	at java.awt.Container.dispatchEventImpl(Container.java:2102)
	at java.awt.Window.dispatchEventImpl(Window.java:2440)
	at java.awt.Component.dispatchEvent(Component.java:4243)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at com.ulcjava.base.client.FilteringEventQueue.dispatchEvent(FilteringEventQueue.java:61)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

The snippet with a workaround:

import com.ulcjava.base.application.AbstractApplication;
import com.ulcjava.base.application.ULCTable;
import com.ulcjava.base.application.ULCFrame;
import com.ulcjava.base.application.ULCComponent;
import com.ulcjava.base.application.dnd.TransferHandler;
import com.ulcjava.base.application.dnd.Transferable;
import com.ulcjava.base.application.table.AbstractTableModel;
import com.ulcjava.base.development.DevelopmentRunner;
import com.ulcjava.base.client.UITable;
import com.ulcjava.base.client.dnd.*;

import java.awt.*;

public class PR7636 extends AbstractApplication {

     public void start() {
         ULCTable table = new ULCTable();
//         ULCTable table = new ULCFixedTable();
         initGrid(table);
         ULCFrame frame = new ULCFrame();
         frame.add(table);
         frame.setSize(640, 480);
         frame.setVisible(true);
     }

     public static void main(String[] args) {
         DevelopmentRunner.setApplicationClass(PR7636.class);
         DevelopmentRunner.main(args);
     }


     private void initGrid(final ULCTable table) {
         AbstractTableModel model = new AbstractTableModel() {
             public int getRowCount() {
                 return 10000;
             }

             public int getColumnCount() {
                 return 20;
             }

             public Object getValueAt(int row, int column) {
                 return "Large CellValue which in our case is multiline: " + row + "/" + column;
             }

             public void setValueAt(Object value, int rowIndex, int columnIndex) {

             }
         };

         table.setModel(model);

         table.setDragEnabled(true);
         table.setTransferHandler(new TransferHandler(){
             @Override
             public boolean importData(ULCComponent targetComponent, Transferable transferable) {
                 return false;
             }

             @Override
             public void exportDone(ULCComponent sourceComponent, Transferable transferable, int dropAction) {
             }
         });
     }

    public static class ULCFixedTable extends ULCTable {
        @Override
        protected String typeString() {
            return UIFixedTable.class.getName();
        }
    }

    public static class UIFixedTable extends UITable {
        protected AbstractDragGestureListener createDragGestureListener(AbstractDragSourceListener dragSourceListener) {
            return new FixedTableDragGestureListener(dragSourceListener);
        }

        public class FixedTableDragGestureListener extends TableDragGestureListener {
            public FixedTableDragGestureListener(AbstractDragSourceListener dragSourceListener) {
                super(dragSourceListener);
            }

            @Override
            protected DragImage createDragImage(Point dragOrigin) {
                if (getBasicTable().getSelectedRowCount() > 10){
                    return null;
                } else {
                    return super.createDragImage(dragOrigin);
                }
            }

            @Override
            protected IDnDData createDragData() {
                if (getBasicTable().getSelectedRowCount() > 100){
                    return new DnDTableData(UIFixedTable.this, getBasicTable().getSelectedRows(), getBasicTable().getSelectedColumns(), "");
                } else {
                    return super.createDragData();
                }
            }
        }
    }
}


 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Janak Mulani added a comment - 04/Feb/09 11:21 AM - edited
To build drag image consider only selected cells that are visible.