Skip to content
This repository has been archived by the owner on Apr 24, 2019. It is now read-only.

Exceptions thrown when scrolling fast in spreadsheet #39

Closed
jvlasblom opened this issue Jul 25, 2013 · 1 comment
Closed

Exceptions thrown when scrolling fast in spreadsheet #39

jvlasblom opened this issue Jul 25, 2013 · 1 comment
Assignees
Milestone

Comments

@jvlasblom
Copy link

If you highlight a row in the spreadsheet, and then just hold down the arrow keys to quickly scroll through the entries, then exceptions are generated, and it also feels sluggish.

The exact exceptions generated vary.

Example 1

at java.lang.String.substring(String.java:1911)
at org.ut.biolab.medsavant.client.view.component.KeyValuePairPanel.ellipsifyValues(KeyValuePairPanel.java:508)
at org.ut.biolab.medsavant.client.view.genetics.variantinfo.DetailedVariantSubInspector.setVariantRecord(DetailedVariantSubInspector.java:300)
at org.ut.biolab.medsavant.client.view.genetics.inspector.ComprehensiveInspector$4.doInBackground(ComprehensiveInspector.java:189)
at org.ut.biolab.medsavant.client.util.MedSavantWorker$1.doInBackground(MedSavantWorker.java:64)
at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at javax.swing.SwingWorker.run(SwingWorker.java:335)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)

Example 2

java.lang.IndexOutOfBoundsException: Index: 4, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at org.ut.biolab.medsavant.client.view.genetics.variantinfo.OtherIndividualsSubInspector$SubInspectorTableModel.getValueAt(OtherIndividualsSubInspector.java:717)
at com.jidesoft.grid.TableModelWrapperImpl.getValueAt(Unknown Source)
at com.jidesoft.grid.DefaultTableModelWrapper.getValueAt(Unknown Source)
at com.jidesoft.grid.TableModelWrapperImpl.getValueAt(Unknown Source)
at com.jidesoft.grid.DefaultTableModelWrapper.getValueAt(Unknown Source)
at com.jidesoft.pivot.TableModelPivotDataSource.getValueAt(Unknown Source)
at com.jidesoft.pivot.PivotDataModel.getCompoundKeyAt(Unknown Source)
at com.jidesoft.pivot.PivotDataModel.j(Unknown Source)
at com.jidesoft.pivot.PivotDataModel.d(Unknown Source)
at com.jidesoft.pivot.AggregateTableModel$AggregateTablePivotDataModel.d(Unknown Source)
at com.jidesoft.pivot.PivotDataModel.forceCalculate(Unknown Source)
at com.jidesoft.pivot.PivotDataModel.calculate(Unknown Source)
at com.jidesoft.pivot.AggregateTableModel$AggregateTablePivotDataModel.calculate(Unknown Source)
at com.jidesoft.pivot.AggregateTableModel.aggregate(Unknown Source)
at com.jidesoft.pivot.AggregateTable.aggregate(Unknown Source)
at com.jidesoft.pivot.AggregateTable.aggregate(Unknown Source)
at org.ut.biolab.medsavant.client.view.genetics.variantinfo.OtherIndividualsSubInspector$2.showSuccess(OtherIndividualsSubInspector.java:540)
at org.ut.biolab.medsavant.client.view.genetics.variantinfo.OtherIndividualsSubInspector$2.showSuccess(OtherIndividualsSubInspector.java:315)
at org.ut.biolab.medsavant.client.util.MedSavantWorker.done(MedSavantWorker.java:111)
at org.ut.biolab.medsavant.client.util.MedSavantWorker$1.done(MedSavantWorker.java:60)
at javax.swing.SwingWorker$5.run(SwingWorker.java:737)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
at javax.swing.Timer.fireActionPerformed(Timer.java:312)
at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

@ghost ghost assigned jvlasblom Jul 31, 2013
jvlasblom pushed a commit that referenced this issue Aug 6, 2013
…0.9, height*0.9)

- Fixed notifications being cutoff.  (width increased from 260 to 290 in UpdatesPanel.java)
- When removing an annotation, if that annotation exists in any project, a dialog is shown telling the user to remove it from the project first. See also issue #25
- Disabled "Restrict DNA IDs" button in browser.  See also issue #31.
- Fixed exceptions thrown when scrolling fast in spreadsheet.  See issue #39 (closed).
@jvlasblom
Copy link
Author

Some more detailed notes on this, for reference:

To address this, I detect when an arrow key is held down and do not launch any infopanel-updating threads if that is the case. The difficulty here is detecting when an arrow key is held down. On linux, nearly simultaneous keypressed/keyreleased events are fired every 30ms, except the first time when it is fired after 500ms. The ordering of these events and the 'selectionChanged' events is not defined. The only way to detect a held-down key that I've found is to use a timer that is reset on every keypress event, and expires after >30ms. When it expires, I launch the threads that update the side info panel.

The key-repeat delay varies by platform, and users may have changed it from the default. If the delay is set too short, the infopanel can sometimes be desynchronized from the current selection. A more annoying problem is that I may end up firing too many threads that could, if the server is slow, cause exceptions. To fix this, I do the following:

  1. Set a conservative value for the initial keypress delay of 1000ms and repeat delay of 200ms. This initial keypress delay is never changed.
  2. If I detect a run of 5 keypress intervals where the delays differed by <5ms*, I assume this is the actual key repeat delay and adjust it accordingly, adding 20ms of padding. If the above keypress delays were set too fast, this code should compensate.
    *This isn't quite what I end up doing, but it's the same idea.

For users with keyboards setup faster than #1, there are no issues. For users with keyboards slower than #1, it's possible they'll see a few visual artifacts (e.g. multiple progress bars in the variant info panel) until #2 corrects for it. However, I haven't encountered exceptions related to this and the display does correct itself.

To make your SearchableTablePanels safe to use with scrolling, use the following instead of a selection change listener:

SearchableTablePanel stp = ....;
stp.scrollSafeSelectAction(new Runnable(){
            @Override
            public void run() {
                //this code executes in a new thread
            }
});

I've used the above in the spreadsheet view and the FamilyMatters view.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant