From e79cf123db2342391b3818d685752af44f5d82d7 Mon Sep 17 00:00:00 2001 From: Moshe Rubin Date: Sun, 18 Jun 2017 05:47:04 +0300 Subject: [PATCH] Fix data selection following zooming with mouse ##The Problem## Data selection works fine when the chart is unzoomed, with an app's ```selectionChanged()``` callback being invoked following data point selection. When the chart is zoomed, however, the ```selectionChanged()``` callback is not invoked. Playing with zooming shows that data selection always fails following zooming using the mouse (i.e., mouse button down + drag). When zooming using the mouse wheel, data selection works for the first few zoom-in mouse wheel works. Once the chart has been enlarged a few times, selection fails. ##Reproducing the Problem## The problem can be reproduced easily with a [minimally modified ```SelectionDemo1.java``` file](https://drive.google.com/open?id=0B09i2ZH5SsTHMmoxa3ZuMWd4WVU). ##The Technical Explanation## Examining the FSE code shows that the reason for ```SelectionChanged()``` not being called following zooming is because the hash value of the ```DatasetSelectionExtension``` object registered in function ```createDemoPanel()``` is modified because of zooming. This causes the statement "registeredExtensions.get(dataset)" in ```DatasetExtensionManager.getExtension()``` to return null: ```java public T getExtension(Dataset dataset, Class interfaceClass) { if (interfaceClass.isAssignableFrom(dataset.getClass())) { //the dataset supports the interface return interfaceClass.cast(dataset); } else { List extensionList = registeredExtensions.get(dataset); if (extensionList != null) { for (DatasetExtension extension : extensionList) { if (interfaceClass.isAssignableFrom(extension.getClass())) { //the dataset does not support the extension but //a matching helper object is registered for the dataset return interfaceClass.cast(extension); } } } } return null; } ``` Drilling down further shows that the ```Calendar``` member variable ```workingCalendar``` has some of its member variables changed due to zooming. The hash returned by the ```Calendar``` class takes these into account, causing the ```HashMap get()``` to fail and return null, preventing ```selectionChanged()``` from being invoked. For an explanation complete with screen captures, [see the following PDF file](https://drive.google.com/open?id=0B09i2ZH5SsTHZ3dpTmViWW5hRm8). ##The Proposed Fix## I believe ```workCalendar``` is unsafe to include in the hash of a ```TimesSeriesCollection``` object and should be removed. I would like to propose removing it from ```TimeSeriesCollection.hashCode()```. When I made the fix locally and rebuilt FSE, data selection works perfectly on both zoomed and non-zoomed charts. --- src/main/java/org/jfree/data/time/TimeSeriesCollection.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/jfree/data/time/TimeSeriesCollection.java b/src/main/java/org/jfree/data/time/TimeSeriesCollection.java index c5cc1094..9b2e1399 100644 --- a/src/main/java/org/jfree/data/time/TimeSeriesCollection.java +++ b/src/main/java/org/jfree/data/time/TimeSeriesCollection.java @@ -757,8 +757,6 @@ public boolean equals(Object obj) { public int hashCode() { int result; result = this.data.hashCode(); - result = 29 * result + (this.workingCalendar != null - ? this.workingCalendar.hashCode() : 0); result = 29 * result + (this.xPosition != null ? this.xPosition.hashCode() : 0); return result;