-
Notifications
You must be signed in to change notification settings - Fork 5.9k
6318027: BasicScrollBarUI does not disable timer when enclosing frame is disabled. #20346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back psadhukhan! A progress list of the required criteria for merging this PR into |
@prsadhuk This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 360 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
Webrevs
|
frame = new JFrame(DisableFrameFromScrollBar.class.getName()); | ||
bar = new JScrollBar(); | ||
bar.getModel().addChangeListener(new DisableChangeListener(frame)); | ||
frame.getContentPane().setLayout(new FlowLayout()); | ||
frame.getContentPane().add(bar); | ||
|
||
frame.pack(); | ||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||
frame.setSize(150, 150); | ||
frame.setLocationRelativeTo(null); | ||
frame.setVisible(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be pushed to a helper method.
// Stop the timer if handledEvent is still set indicating | ||
// mouseReleased is not called after mousePressed when | ||
// this AcionEvent is being processed | ||
if (buttonListener.handledEvent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the fix is added in BasicScrollBarUI, will it affect Aqua ScrollBar also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think most L&F's ScrollBarUI classes are extending BasicScrollBarUI so it might be worth checking if this issue also occurs in those L&Fs too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aqua ScrollBar does not have arrowbutton so ArrowButtonListener, as mentioned in JBS, is not there but there is trackpad and there is similar issue with it but it cannot be handled with this "handledEvent" and needs to be handled separately so as of now AquaL&F is omitted from the testing..Other L&F are fine as per the testing..
frame.getContentPane().setLayout(new FlowLayout()); | ||
frame.getContentPane().add(bar); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess getContentPane
may be removed.
|
||
frame.pack(); | ||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||
frame.setSize(150, 150); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setting frame size explicitly after calling frame.pack()
looks redundant.
public void run() { | ||
Point p = bar.getLocationOnScreen(); | ||
Rectangle rect = bar.getBounds(); | ||
result[0] = new Point((int) (p.x + rect.width/2), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
result[0] = new Point((int) (p.x + rect.width/2), | |
result[0] = new Point((int) (p.x + rect.width / 2), |
|
||
public static class DisableChangeListener implements ChangeListener { | ||
private final JFrame m_frame; | ||
private boolean m_done = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default value for a boolean is false
, no need to set it explicitly.
} | ||
|
||
public void stateChanged(ChangeEvent p_e) { | ||
if (! m_done) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (! m_done) { | |
if (!m_done) { |
@prsadhuk I was verifying the test and for Aqua L&F looks like the timer is not stopped and scrollbar scrolls down to the end and it doesn't throw any exception also. |
@@ -527,6 +527,12 @@ void setScrollByBlock(final boolean block) { | |||
} | |||
|
|||
public void actionPerformed(final ActionEvent e) { | |||
if (fTrackHighlight != Hit.NONE && !fTrackListener.fStillInTrack) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fTrackListener.fStillInTrack
value is true
and here the condition is to check for negation which makes it to false
and overall condition evaluates to false
and that may be the reason that the timer is not stopped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes thats the drawback of indirect checking....I have modified PR to check for frame disable directly and stop the timer..
Thread.sleep(200); | ||
} while(isAdjusting && !doCheck); | ||
if (bar.getValue() == (bar.getMaximum() - bar.getVisibleAmount())) { | ||
throw new RuntimeException("ScrollBar did't disable timer"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw new RuntimeException("ScrollBar did't disable timer"); | |
throw new RuntimeException("ScrollBar didn't disable timer"); |
|
||
private static JFrame frame; | ||
private static JScrollBar bar; | ||
private static Robot robot; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
robot
can be local variable.
What happens if you make the scrollbar invisible in this case? |
do { | ||
if (parent instanceof javax.swing.JFrame par) { | ||
if (!par.isEnabled()) { | ||
((Timer)e.getSource()).stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the "TImer" always the source for the event?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the method employs same way to stop the timer in other cases too..
Also, if the scrollbar is made invisible and then visible instead of frame, it doesn't scroll to the end and behaves as expected..
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
Outdated
Show resolved
Hide resolved
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
Show resolved
Hide resolved
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
Outdated
Show resolved
Hide resolved
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
Outdated
Show resolved
Hide resolved
do { | ||
if (parent instanceof javax.swing.JFrame par) { | ||
if (!par.isEnabled()) { | ||
((Timer)e.getSource()).stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
((Timer)e.getSource()).stop(); | |
((Timer) e.getSource()).stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same spacing issue in other places too as mentioned above...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok... as you are changing the file I guess you can expand the wild imports, It's up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor sorting of imports.
import java.awt.Graphics; | ||
import java.awt.Point; | ||
import java.awt.Rectangle; | ||
import java.awt.Insets; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import java.awt.Graphics; | |
import java.awt.Point; | |
import java.awt.Rectangle; | |
import java.awt.Insets; | |
import java.awt.Graphics; | |
import java.awt.Insets; | |
import java.awt.Point; | |
import java.awt.Rectangle; | |
import apple.laf.JRSUIConstants.Hit; | ||
import apple.laf.JRSUIConstants.Orientation; | ||
import apple.laf.JRSUIConstants.NothingToScroll; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import apple.laf.JRSUIConstants.Hit; | |
import apple.laf.JRSUIConstants.Orientation; | |
import apple.laf.JRSUIConstants.NothingToScroll; | |
import apple.laf.JRSUIConstants.Hit; | |
import apple.laf.JRSUIConstants.NothingToScroll; | |
import apple.laf.JRSUIConstants.Orientation; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ran the test and verified the latest fix on different platforms (mac, windows and linux). It works as expected and looks good to me now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
/integrate |
Going to push as commit cafb3dc.
Your commit was automatically rebased without conflicts. |
Issue is
BasicScrollBarUI.ArrowButtonListener starts a timer in mousePressed(), and stops it in mouseReleased(). If the frame containing the scrollbar is disabled between the MOUSE_PRESSED and the MOUSE_RELEASED events, the mouseReleased() method is never called. If the frame is then re-enabled, the still-running timer causes it to scroll all the way to the end.
Fix is to check if ArrowButtonListener.handledEvent is still set when ActionEvent is processed then stop the timer and reset this variable.
CI testing is green and also SwingSet2 JScrollPane scrolling with this modification..
Progress
Warning
6318027: BasicScrollBarUI does not disable timer when enclosing frame is disabled.
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/20346/head:pull/20346
$ git checkout pull/20346
Update a local copy of the PR:
$ git checkout pull/20346
$ git pull https://git.openjdk.org/jdk.git pull/20346/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 20346
View PR using the GUI difftool:
$ git pr show -t 20346
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/20346.diff
Webrev
Link to Webrev Comment