From pankaj.b.bansal at oracle.com Wed Feb 5 13:00:19 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Wed, 5 Feb 2020 05:00:19 -0800 (PST) Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> Message-ID: Hello Sergey, << ok. <; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition On 1/29/20 2:25 am, Pankaj Bansal wrote: > One more point, I am able to reproduce the current issue with Synth LookAndFeel in all platforms without fix and it works fine with the fix. ok. Do we need to remove the listener added to the menuItem? I guess it will be added every time we change L&F to the windows and will never be removed. > > Regards, > Pankaj > > -----Original Message----- > From: Pankaj Bansal > Sent: Wednesday, January 29, 2020 3:19 PM > To: Sergey Bylokhov; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > Hello Sergey, > > << Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? > < I changed the test in JDK-8152981 to run on all installed LookAndFeels on windows, linux and Mac after removing the windows only condition. The tests passes on all platforms with all LookAndFeels with the current fix. > I can check in this change in JDK-8152981 test along with the current fix if needed, though I feel it is not required as the issue was originally only in WindowsLookAndFeel. > > Regards, > Pankaj Bansal > > -----Original Message----- > From: Sergey Bylokhov > Sent: Wednesday, January 29, 2020 1:17 PM > To: Pankaj Bansal; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>> << It is not a big issue, but for such a fix we will need a proper specification and CSR, it is like adding a new method to the public class. It is preferable to try to fix it in some other way first. >>> I did not realize earlier that this can be done by making changes in WindowsMenuItemUI without calling the updateCheckIcon by moving the code in updateCheckIcon method in WindowsMenuItemUI class. I have made the changes for the same and all works fine. Also, I have removed the updateCheckIcon method from BasicMenuItemUI class as it is not needed. >> >> Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? > > For example if some other "basic" L&F will be used(Motif, Aqua)? > > -- Best regards, Sergey. From vladislav.volodin at sap.com Wed Feb 5 13:25:35 2020 From: vladislav.volodin at sap.com (Volodin, Vladislav) Date: Wed, 5 Feb 2020 13:25:35 +0000 Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> Message-ID: Hello Pankaj, I apologize, if I interfere your job, I decided to study your code to learn JDK better, and I found out that the class BasicMenuItemUI has the method that looks quite simple: /*Returns a property prefix * @return a property prefix */ protected String getPropertyPrefix() { return "MenuItem"; } I don't understand why it was created as the method. Since you are changing this part, maybe it will make sense and replace it with a constant string? I hope Java compile can optimize method calls in situations like this one, if you use constant strings: String prefix = getPropertyPrefix(); ... (...) iconFactory = (...) UIManager.get(prefix + ".checkIconFactory"); Another thing: I see that in your code, you extract checkIcon, that might be overwritten by "if" statement: checkIcon = UIManager.getIcon(prefix + ".checkIcon"); // here we assign, and (look down) boolean isColumnLayout = ...; if (isColumnLayout) { ... if (...) { checkIcon = iconFactory.getIcon(menuItem); // <-- here we might overwrite checkIcon } } What do you think, would it be more efficient, if your "first" line will be executed in the "else" branch of the "if" statement? Feel free to ignore my suggestion, if you think that it misleading. Thanks, Vlad -----Original Message----- From: swing-dev On Behalf Of Pankaj Bansal Sent: Mittwoch, 5. Februar 2020 14:00 To: Sergey Bylokhov ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition Hello Sergey, << ok. <; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition On 1/29/20 2:25 am, Pankaj Bansal wrote: > One more point, I am able to reproduce the current issue with Synth LookAndFeel in all platforms without fix and it works fine with the fix. ok. Do we need to remove the listener added to the menuItem? I guess it will be added every time we change L&F to the windows and will never be removed. > > Regards, > Pankaj > > -----Original Message----- > From: Pankaj Bansal > Sent: Wednesday, January 29, 2020 3:19 PM > To: Sergey Bylokhov; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > Hello Sergey, > > << Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? > < I changed the test in JDK-8152981 to run on all installed LookAndFeels on windows, linux and Mac after removing the windows only condition. The tests passes on all platforms with all LookAndFeels with the current fix. > I can check in this change in JDK-8152981 test along with the current fix if needed, though I feel it is not required as the issue was originally only in WindowsLookAndFeel. > > Regards, > Pankaj Bansal > > -----Original Message----- > From: Sergey Bylokhov > Sent: Wednesday, January 29, 2020 1:17 PM > To: Pankaj Bansal; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>> << It is not a big issue, but for such a fix we will need a proper specification and CSR, it is like adding a new method to the public class. It is preferable to try to fix it in some other way first. >>> I did not realize earlier that this can be done by making changes in WindowsMenuItemUI without calling the updateCheckIcon by moving the code in updateCheckIcon method in WindowsMenuItemUI class. I have made the changes for the same and all works fine. Also, I have removed the updateCheckIcon method from BasicMenuItemUI class as it is not needed. >> >> Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? > > For example if some other "basic" L&F will be used(Motif, Aqua)? > > -- Best regards, Sergey. From vladislav.volodin at sap.com Wed Feb 5 15:59:05 2020 From: vladislav.volodin at sap.com (Volodin, Vladislav) Date: Wed, 5 Feb 2020 15:59:05 +0000 Subject: Remove System.out.println from ImageIcon.loadImage In-Reply-To: References: <2310F0FD-DAA6-4E24-85AD-776D6F979CC0@sap.com> <549622d0-fe72-f267-c105-53b1399471dc@oracle.com>, , , <6CA1C9A2-3FE1-445D-93B7-57DC8818F0FB@sap.com>, , , , Message-ID: Hi Jason, thank you for your advice. I have changed my code, now it simulates the behavior of the interrupted thread. Can you please check my patch? I don't have the "bug" ticket, so in my test case "@bug JDK-123456" should be adjusted. I will appreciate if you and somebody else can review my patch and submit it to JDK. Thanks, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 17:55 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage 1. Agreed. 2. I was just pulling from the jdk8 source (because I'm lazy) to express the idea. Feel free to adjust. 3. Reasserting in the finally ensure we are not forcefully setting the interrupted status on the current thread and calling 'statusID' and 'removeImage'. It also ensures that the interrupt is set even if an unexpected exception is thrown. Reasserting at the end of 'e1' and never in 'e2' should work too. The main issue that I'm trying to convey to you is that your test is incomplete in that it does check that the interrupt was swallowed. Swallowing interrupts is bad practice. Reasserting in e2 only means that we swallow interrupts from e1. Change your test to this and retest: === public static void main(String[] args) throws Exception { Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); Thread.currentThread().interrupt(); ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { throw new RuntimeException("Couldn't load GIF from bytes after interruption"); } if (!Thread.currentThread().isInterrupted()) { throw new RuntimeException("Interrupt was swallowed"); } } } === ________________________________________ From: Volodin, Vladislav Sent: Wednesday, January 29, 2020 9:52 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, I have few questions: 1. The second assignment is probably redundant: } catch (InterruptedException e1) { wasInterrupted = true; // line #2, see comment below try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; // <-- this is redundant, because of the line #2 } } finally { 2. I think the first call of "addImage" is not necessary: boolean wasInterrupted = false; mTracker.addImage(image, id); // maybe I should remove this, because of another comment down below. try { loadStatus = 0; mTracker.addImage(image, id); // because of that May I also ask you a question? What is the purpose of interrupting the current thread in the finally block, instead of doing it in the second catch block (where e2 is created)? I assume that since we were able to handle the exception properly, and plus the entire block is in the synchronization area, in theory we have only one importer at the time. Kind regards, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 16:35 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Bug in that last version: Thread.currentThread().isInterrupted(); -> Thread.currentThread().interrupt(); === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().interrupt(); } } } } === ________________________________________ From: swing-dev on behalf of Jason Mehrens Sent: Wednesday, January 29, 2020 9:33 AM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage A shorter version is just to reassert at the end of catch e1. It is safer to just reassert as the last statement in the finally. === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().isInterrupted(); } } } } === Jason ________________________________________ From: Volodin, Vladislav Sent: Tuesday, January 28, 2020 4:02 PM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage This is a valid point, because I wasn?t sure that when the thread is interrupted, I handled the first exception, and my thought was that all other ?wait? calls (maybe in other threads) should get the same exception as well. And since I handled this exceptional case, I am restoring the interrupted status in case if I don?t know how to handle this exception the second time. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; Thread.currentThread().interrupt(); } If I restore the interrupted status BEFORE waitForID call, then this thread will immoderately fail. Should I restore it AFTER, e.g. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); Thread.currentThread().interrupt(); // On 28. Jan 2020, at 22:27, Jason Mehrens wrote: > > ?I see. Well I would have to do some more digging and testing to make myself more knowledgeable on MediaTracker. > > Then the only bug in your current code is that you are not reasserting interrupted status of the current thread in the case e1 is raised and e2 is not. It is usually best to reassert the interrupted state at the end of the method. > > Jason > > ________________________________________ > From: Volodin, Vladislav > Sent: Tuesday, January 28, 2020 2:54 PM > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from ImageIcon.loadImage > > Hi Jason, > > I am not sure about the loop, because I don?t know if we can trust results from mTracker.statusID at the moment when an exceptional case occurs. For example, I was experimenting with the code and found out that the MediaTracker can spawn a thread to load the image, or might use the current thread, and the ABORTED state is never returned (I don?t even know how to raise this state). That is why I don?t even know if your loop will ever stop. > > In my solution, I give the second chance only, and in case if the execution was interrupted the second time, I explicitly assign the ABORTED state to loadStatus. If the user wants to load this image once again, he can create ImageIcon again (or even do this in a loop), or reinitialize it with a single method (I don?t remember its name). > > What do you think? > > Kind regards, > Vlad > > Sent from myPad > >> On 28. Jan 2020, at 21:34, Jason Mehrens wrote: >> >> ?Vlad, >> >> I assume you would want to wait in a loop and reassert the interrupt at the end. >> >> === >> protected void loadImage(Image image) { >> MediaTracker mTracker = getTracker(); >> synchronized(mTracker) { >> int id = getNextID(); >> >> mTracker.addImage(image, id); >> boolean wasInterrupted = false; >> try { >> do { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e) { >> wasInterrupted = true; >> } >> loadStatus = mTracker.statusID(id, false); >> } while (loadStatus == MediaTracker.LOADING); >> mTracker.removeImage(image, id); >> >> width = image.getWidth(imageObserver); >> height = image.getHeight(imageObserver); >> } finally { >> if (wasInterrupted) { >> Thread.currentThread().interrupt(); >> } >> } >> } >> } >> === >> >> Jason >> ________________________________________ >> From: swing-dev on behalf of Volodin, Vladislav >> Sent: Monday, January 27, 2020 11:11 AM >> To: Sergey Bylokhov >> Cc: swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >> Hello Sergey, and others, >> >> here is the patch (made with "git diff") in the attachment. I have read that sometimes the attachments are lost. So here is my version with few comments regarding my code. I decided to use your approach with a small improvement. There is an excerpt of my patch. >> >> The idea is pretty simple: >> 1. I create an empty gif 1x1; >> 2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do not initialize the toolkit in advance, my test will fail at the beginning >> 3. Interrupt the main thread >> 4. Try to load the icon: >> >> import javax.swing.*; >> import java.awt.*; >> >> public class imageIconInterrupted { >> static byte[] EMPTY_GIF = new byte[]{ >> (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) 0x61, (byte) 0x01, (byte) 0x00, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, (byte) 0xF9, (byte) 0x04, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2C, (byte) 0x00, (byte) 0x00, >> (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x02 >> }; >> >> public static void main(String[] args) throws Exception { >> Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); >> >> Thread.currentThread().interrupt(); >> ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); >> if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { >> throw new RuntimeException("Couldn't load GIF from bytes after interruption"); >> } >> } >> } >> >> The code of loadImage I have changed as follows: >> 1. I clear loadStatus for "finally" part; >> 2. Check the interruption according to your comments; >> 3. Change the status to ABORTED, if the interruption happened again (this part I cannot test, because I cannot properly interrupt the thread whenever I want. Multithreading is quite fragile there :( ) >> 4. update the status "interrupted" again; >> 5. and then - finally block. >> >> protected void loadImage(Image image) { >> ... >> try { >> loadStatus = 0; >> mTracker.addImage(image, id); >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e1) { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e2) { >> loadStatus = MediaTracker.ABORTED; >> Thread.currentThread().interrupt(); >> } >> } finally { >> if (loadStatus == 0) { >> loadStatus = mTracker.statusID(id, false); >> } >> mTracker.removeImage(image, id); >> } >> >> P.S. if you think that my patch sounds fine, I will find a sponsor for the bug report and the patch preparation, so you can review it later. >> After the second attempt, my EMPTY_GIF was loaded successfully. The ABORTED part it seems that I don't know if it has ever worked. My patch (in the attachment) checks also the state ERROR for the URL that doesn't exist. Something like: >> >> ImageIcon iconNotExist = new ImageIcon(new URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this URL grammatically correct >> if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) { >> throw new RuntimeException("Got unexpected status from non-existing GIF"); >> } >> >> Thanks to everyone. >> >> Kind regards, >> Vlad >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Dienstag, 21. Januar 2020 22:26 >> To: Volodin, Vladislav >> Cc: Jason Mehrens ; swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >>>> On 1/21/20 1:14 pm, Volodin, Vladislav wrote: >>> Hi all, >>> >>> If I am not mistaken, this method is called from the constructor and other methods. How long should we try loading the icon using the unmanaged (by any thread pool, but I am not sure about this statement) thread? >>> >>> We don?t even have the flag ?interrupted?. So technically this icon has to be loaded. >> >> I think it is necessary to save the "interrupted" state in the catch >> block and try to call waitForID() again. It will be necessary to set >> "interrupted" flag for the Thread after that(when the waitForID will >> return without exception). >> >> >>> Sent from myFone >>> >>>>> On 21. Jan 2020, at 21:55, Sergey Bylokhov wrote: >>>> >>>> ?On 1/21/20 12:26 pm, Jason Mehrens wrote: >>>>> +1 for Sergey suggestion. >>>> >>>> Or probably we need to try to load the image again because of the spec of the method state this: >>>> "Loads the image, returning only when the image is loaded." >>>> >>>>> ________________________________________ >>>>> From: Sergey Bylokhov >>>>> Sent: Sunday, January 19, 2020 9:31 PM >>>>> To: Volodin, Vladislav; Jason Mehrens >>>>> Cc: swing-dev at openjdk.java.net >>>>> Subject: Re: Remove System.out.println from ImageIcon.loadImage >>>>> I guess there are no objections, probably the best way to fix >>>>> it is to drop the System.out.println and set interrupted flag. >>>>> On 1/16/20 7:05 am, Volodin, Vladislav wrote: >>>>>> If people in this distribution list agree, I can start working on a simple fix and either remove the logging (System.out.println), or replace it with PlatformLogger. I guess the second solution sounds better, but I don't know what is the better way to write a test-case for it. >>>>> -- >>>>> Best regards, Sergey. >>>> >>>> >>>> -- >>>> Best regards, Sergey. >> >> >> -- >> Best regards, Sergey. -------------- next part -------------- A non-text attachment was scrubbed... Name: imageIconBug-diff-2.patch Type: application/octet-stream Size: 5166 bytes Desc: imageIconBug-diff-2.patch URL: From christoph.langer at sap.com Wed Feb 5 22:49:59 2020 From: christoph.langer at sap.com (Langer, Christoph) Date: Wed, 5 Feb 2020 22:49:59 +0000 Subject: Remove System.out.println from ImageIcon.loadImage In-Reply-To: References: <2310F0FD-DAA6-4E24-85AD-776D6F979CC0@sap.com> <549622d0-fe72-f267-c105-53b1399471dc@oracle.com>, , , <6CA1C9A2-3FE1-445D-93B7-57DC8818F0FB@sap.com>, , , , Message-ID: Hi Vlad, I can help you generate a webrev and upload it to cr.o.j.n. Please ping me tomorrow. Another question to all: Shall I reopen https://bugs.openjdk.java.net/browse/JDK-6421373 for this? Thanks Christoph > -----Original Message----- > From: swing-dev On Behalf Of > Volodin, Vladislav > Sent: Mittwoch, 5. Februar 2020 16:59 > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: [CAUTION] Re: Remove System.out.println from > ImageIcon.loadImage > > Hi Jason, > > thank you for your advice. I have changed my code, now it simulates the > behavior of the interrupted thread. Can you please check my patch? > I don't have the "bug" ticket, so in my test case "@bug JDK-123456" should > be adjusted. > > I will appreciate if you and somebody else can review my patch and submit it > to JDK. > > Thanks, > Vlad > > -----Original Message----- > From: Jason Mehrens > Sent: Mittwoch, 29. Januar 2020 17:55 > To: Volodin, Vladislav > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from > ImageIcon.loadImage > > 1. Agreed. > 2. I was just pulling from the jdk8 source (because I'm lazy) to express the > idea. Feel free to adjust. > 3. Reasserting in the finally ensure we are not forcefully setting the > interrupted status on the current thread and calling 'statusID' and > 'removeImage'. It also ensures that the interrupt is set even if an > unexpected exception is thrown. Reasserting at the end of 'e1' and never in > 'e2' should work too. > > The main issue that I'm trying to convey to you is that your test is incomplete > in that it does check that the interrupt was swallowed. Swallowing interrupts > is bad practice. Reasserting in e2 only means that we swallow interrupts > from e1. > > Change your test to this and retest: > === > public static void main(String[] args) throws Exception { > Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); > > Thread.currentThread().interrupt(); > ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); > if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { > throw new RuntimeException("Couldn't load GIF from bytes after > interruption"); > } > > if (!Thread.currentThread().isInterrupted()) { > throw new RuntimeException("Interrupt was swallowed"); > } > } > } > === > ________________________________________ > From: Volodin, Vladislav > Sent: Wednesday, January 29, 2020 9:52 AM > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: RE: Remove System.out.println from > ImageIcon.loadImage > > Hi Jason, > > I have few questions: > > 1. The second assignment is probably redundant: > > } catch (InterruptedException e1) { > wasInterrupted = true; // line #2, see comment below > try { > mTracker.waitForID(id, 0); > } catch (InterruptedException e2) { > loadStatus = MediaTracker.ABORTED; > wasInterrupted = true; // <-- this is redundant, because of the line #2 > } > } finally { > > 2. I think the first call of "addImage" is not necessary: > > boolean wasInterrupted = false; > mTracker.addImage(image, id); // maybe I should remove this, because of > another comment down below. > try { > loadStatus = 0; > mTracker.addImage(image, id); // because of that > > May I also ask you a question? > What is the purpose of interrupting the current thread in the finally block, > instead of doing it in the second catch block (where e2 is created)? I assume > that since we were able to handle the exception properly, and plus the > entire block is in the synchronization area, in theory we have only one > importer at the time. > > Kind regards, > Vlad > > -----Original Message----- > From: Jason Mehrens > Sent: Mittwoch, 29. Januar 2020 16:35 > To: Volodin, Vladislav > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from > ImageIcon.loadImage > > Bug in that last version: > Thread.currentThread().isInterrupted(); -> > Thread.currentThread().interrupt(); > === > protected void loadImage(Image image) { > MediaTracker mTracker = getTracker(); > synchronized (mTracker) { > int id = getNextID(); > > boolean wasInterrupted = false; > mTracker.addImage(image, id); > try { > loadStatus = 0; > mTracker.addImage(image, id); > mTracker.waitForID(id, 0); > } catch (InterruptedException e1) { > wasInterrupted = true; > try { > mTracker.waitForID(id, 0); > } catch (InterruptedException e2) { > loadStatus = MediaTracker.ABORTED; > wasInterrupted = true; > } > } finally { > if (loadStatus == 0) { > loadStatus = mTracker.statusID(id, false); > } > mTracker.removeImage(image, id); > if (wasInterrupted) { > Thread.currentThread().interrupt(); > } > } > } > } > === > > ________________________________________ > From: swing-dev on behalf of > Jason Mehrens > Sent: Wednesday, January 29, 2020 9:33 AM > To: Volodin, Vladislav > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from > ImageIcon.loadImage > > A shorter version is just to reassert at the end of catch e1. It is safer to just > reassert as the last statement in the finally. > > === > protected void loadImage(Image image) { > MediaTracker mTracker = getTracker(); > synchronized (mTracker) { > int id = getNextID(); > > boolean wasInterrupted = false; > mTracker.addImage(image, id); > try { > loadStatus = 0; > mTracker.addImage(image, id); > mTracker.waitForID(id, 0); > } catch (InterruptedException e1) { > wasInterrupted = true; > try { > mTracker.waitForID(id, 0); > } catch (InterruptedException e2) { > loadStatus = MediaTracker.ABORTED; > } > } finally { > if (loadStatus == 0) { > loadStatus = mTracker.statusID(id, false); > } > mTracker.removeImage(image, id); > if (wasInterrupted) { > Thread.currentThread().isInterrupted(); > } > } > } > } > === > > Jason > ________________________________________ > From: Volodin, Vladislav > Sent: Tuesday, January 28, 2020 4:02 PM > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from > ImageIcon.loadImage > > This is a valid point, because I wasn?t sure that when the thread is > interrupted, I handled the first exception, and my thought was that all other > ?wait? calls (maybe in other threads) should get the same exception as well. > > And since I handled this exceptional case, I am restoring the interrupted > status in case if I don?t know how to handle this exception the second time. > > } catch (InterruptedException e1) { > try { > mTracker.waitForID(id, 0); > } catch (InterruptedException e2) { > loadStatus = MediaTracker.ABORTED; > Thread.currentThread().interrupt(); > } > > If I restore the interrupted status BEFORE waitForID call, then this thread will > immoderately fail. Should I restore it AFTER, e.g. > > } catch (InterruptedException e1) { > try { > mTracker.waitForID(id, 0); > Thread.currentThread().interrupt(); // } catch (InterruptedException e2) { > loadStatus = MediaTracker.ABORTED; > Thread.currentThread().interrupt(); > } > > Thanks, > Vlad > > Sent from myPad > > > On 28. Jan 2020, at 22:27, Jason Mehrens > wrote: > > > > ?I see. Well I would have to do some more digging and testing to make > myself more knowledgeable on MediaTracker. > > > > Then the only bug in your current code is that you are not reasserting > interrupted status of the current thread in the case e1 is raised and e2 is not. > It is usually best to reassert the interrupted state at the end of the method. > > > > Jason > > > > ________________________________________ > > From: Volodin, Vladislav > > Sent: Tuesday, January 28, 2020 2:54 PM > > To: Jason Mehrens > > Cc: swing-dev at openjdk.java.net > > Subject: Re: Remove System.out.println from > ImageIcon.loadImage > > > > Hi Jason, > > > > I am not sure about the loop, because I don?t know if we can trust results > from mTracker.statusID at the moment when an exceptional case occurs. For > example, I was experimenting with the code and found out that the > MediaTracker can spawn a thread to load the image, or might use the current > thread, and the ABORTED state is never returned (I don?t even know how to > raise this state). That is why I don?t even know if your loop will ever stop. > > > > In my solution, I give the second chance only, and in case if the execution > was interrupted the second time, I explicitly assign the ABORTED state to > loadStatus. If the user wants to load this image once again, he can create > ImageIcon again (or even do this in a loop), or reinitialize it with a single > method (I don?t remember its name). > > > > What do you think? > > > > Kind regards, > > Vlad > > > > Sent from myPad > > > >> On 28. Jan 2020, at 21:34, Jason Mehrens > wrote: > >> > >> ?Vlad, > >> > >> I assume you would want to wait in a loop and reassert the interrupt at > the end. > >> > >> === > >> protected void loadImage(Image image) { > >> MediaTracker mTracker = getTracker(); > >> synchronized(mTracker) { > >> int id = getNextID(); > >> > >> mTracker.addImage(image, id); > >> boolean wasInterrupted = false; > >> try { > >> do { > >> try { > >> mTracker.waitForID(id, 0); > >> } catch (InterruptedException e) { > >> wasInterrupted = true; > >> } > >> loadStatus = mTracker.statusID(id, false); > >> } while (loadStatus == MediaTracker.LOADING); > >> mTracker.removeImage(image, id); > >> > >> width = image.getWidth(imageObserver); > >> height = image.getHeight(imageObserver); > >> } finally { > >> if (wasInterrupted) { > >> Thread.currentThread().interrupt(); > >> } > >> } > >> } > >> } > >> === > >> > >> Jason > >> ________________________________________ > >> From: swing-dev on behalf of > Volodin, Vladislav > >> Sent: Monday, January 27, 2020 11:11 AM > >> To: Sergey Bylokhov > >> Cc: swing-dev at openjdk.java.net > >> Subject: Re: Remove System.out.println from > ImageIcon.loadImage > >> > >> Hello Sergey, and others, > >> > >> here is the patch (made with "git diff") in the attachment. I have read that > sometimes the attachments are lost. So here is my version with few > comments regarding my code. I decided to use your approach with a small > improvement. There is an excerpt of my patch. > >> > >> The idea is pretty simple: > >> 1. I create an empty gif 1x1; > >> 2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do > not initialize the toolkit in advance, my test will fail at the beginning > >> 3. Interrupt the main thread > >> 4. Try to load the icon: > >> > >> import javax.swing.*; > >> import java.awt.*; > >> > >> public class imageIconInterrupted { > >> static byte[] EMPTY_GIF = new byte[]{ > >> (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) > 0x61, (byte) 0x01, (byte) 0x00, > >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) > 0x21, (byte) 0xF9, (byte) 0x04, > >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) > 0x2C, (byte) 0x00, (byte) 0x00, > >> (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) > 0x00, (byte) 0x00, (byte) 0x02 > >> }; > >> > >> public static void main(String[] args) throws Exception { > >> Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); > >> > >> Thread.currentThread().interrupt(); > >> ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); > >> if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { > >> throw new RuntimeException("Couldn't load GIF from bytes after > interruption"); > >> } > >> } > >> } > >> > >> The code of loadImage I have changed as follows: > >> 1. I clear loadStatus for "finally" part; > >> 2. Check the interruption according to your comments; > >> 3. Change the status to ABORTED, if the interruption happened again (this > part I cannot test, because I cannot properly interrupt the thread whenever I > want. Multithreading is quite fragile there :( ) > >> 4. update the status "interrupted" again; > >> 5. and then - finally block. > >> > >> protected void loadImage(Image image) { > >> ... > >> try { > >> loadStatus = 0; > >> mTracker.addImage(image, id); > >> mTracker.waitForID(id, 0); > >> } catch (InterruptedException e1) { > >> try { > >> mTracker.waitForID(id, 0); > >> } catch (InterruptedException e2) { > >> loadStatus = MediaTracker.ABORTED; > >> Thread.currentThread().interrupt(); > >> } > >> } finally { > >> if (loadStatus == 0) { > >> loadStatus = mTracker.statusID(id, false); > >> } > >> mTracker.removeImage(image, id); > >> } > >> > >> P.S. if you think that my patch sounds fine, I will find a sponsor for the bug > report and the patch preparation, so you can review it later. > >> After the second attempt, my EMPTY_GIF was loaded successfully. The > ABORTED part it seems that I don't know if it has ever worked. My patch (in > the attachment) checks also the state ERROR for the URL that doesn't exist. > Something like: > >> > >> ImageIcon iconNotExist = new ImageIcon(new > URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this > URL grammatically correct > >> if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) { > >> throw new RuntimeException("Got unexpected status from non- > existing GIF"); > >> } > >> > >> Thanks to everyone. > >> > >> Kind regards, > >> Vlad > >> > >> -----Original Message----- > >> From: Sergey Bylokhov > >> Sent: Dienstag, 21. Januar 2020 22:26 > >> To: Volodin, Vladislav > >> Cc: Jason Mehrens ; swing- > dev at openjdk.java.net > >> Subject: Re: Remove System.out.println from > ImageIcon.loadImage > >> > >>>> On 1/21/20 1:14 pm, Volodin, Vladislav wrote: > >>> Hi all, > >>> > >>> If I am not mistaken, this method is called from the constructor and > other methods. How long should we try loading the icon using the > unmanaged (by any thread pool, but I am not sure about this statement) > thread? > >>> > >>> We don?t even have the flag ?interrupted?. So technically this icon has to > be loaded. > >> > >> I think it is necessary to save the "interrupted" state in the catch > >> block and try to call waitForID() again. It will be necessary to set > >> "interrupted" flag for the Thread after that(when the waitForID will > >> return without exception). > >> > >> > >>> Sent from myFone > >>> > >>>>> On 21. Jan 2020, at 21:55, Sergey Bylokhov > wrote: > >>>> > >>>> ?On 1/21/20 12:26 pm, Jason Mehrens wrote: > >>>>> +1 for Sergey suggestion. > >>>> > >>>> Or probably we need to try to load the image again because of the spec > of the method state this: > >>>> "Loads the image, returning only when the image is loaded." > >>>> > >>>>> ________________________________________ > >>>>> From: Sergey Bylokhov > >>>>> Sent: Sunday, January 19, 2020 9:31 PM > >>>>> To: Volodin, Vladislav; Jason Mehrens > >>>>> Cc: swing-dev at openjdk.java.net > >>>>> Subject: Re: Remove System.out.println from > ImageIcon.loadImage > >>>>> I guess there are no objections, probably the best way to fix > >>>>> it is to drop the System.out.println and set interrupted flag. > >>>>> On 1/16/20 7:05 am, Volodin, Vladislav wrote: > >>>>>> If people in this distribution list agree, I can start working on a simple > fix and either remove the logging (System.out.println), or replace it with > PlatformLogger. I guess the second solution sounds better, but I don't know > what is the better way to write a test-case for it. > >>>>> -- > >>>>> Best regards, Sergey. > >>>> > >>>> > >>>> -- > >>>> Best regards, Sergey. > >> > >> > >> -- > >> Best regards, Sergey. From vladislav.volodin at sap.com Wed Feb 5 23:04:48 2020 From: vladislav.volodin at sap.com (Volodin, Vladislav) Date: Wed, 5 Feb 2020 23:04:48 +0000 Subject: Remove System.out.println from ImageIcon.loadImage In-Reply-To: References: <2310F0FD-DAA6-4E24-85AD-776D6F979CC0@sap.com> <549622d0-fe72-f267-c105-53b1399471dc@oracle.com>, , , <6CA1C9A2-3FE1-445D-93B7-57DC8818F0FB@sap.com>, , , , , Message-ID: Hi Christoph, there are two issues that I was planning to resolve: * the presence of System.out.println * the absence of the thread interruption Do you know if a single bug report can contain them both? If yes, I think we need a new bug report and change a status of your as ?duplicate?. Is it fair? I will ping you tomorrow Thank you, Vlad Sent from myFone On 5. Feb 2020, at 23:50, Langer, Christoph wrote: ?Hi Vlad, I can help you generate a webrev and upload it to cr.o.j.n. Please ping me tomorrow. Another question to all: Shall I reopen https://bugs.openjdk.java.net/browse/JDK-6421373 for this? Thanks Christoph -----Original Message----- From: swing-dev On Behalf Of Volodin, Vladislav Sent: Mittwoch, 5. Februar 2020 16:59 To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: [CAUTION] Re: Remove System.out.println from ImageIcon.loadImage Hi Jason, thank you for your advice. I have changed my code, now it simulates the behavior of the interrupted thread. Can you please check my patch? I don't have the "bug" ticket, so in my test case "@bug JDK-123456" should be adjusted. I will appreciate if you and somebody else can review my patch and submit it to JDK. Thanks, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 17:55 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage 1. Agreed. 2. I was just pulling from the jdk8 source (because I'm lazy) to express the idea. Feel free to adjust. 3. Reasserting in the finally ensure we are not forcefully setting the interrupted status on the current thread and calling 'statusID' and 'removeImage'. It also ensures that the interrupt is set even if an unexpected exception is thrown. Reasserting at the end of 'e1' and never in 'e2' should work too. The main issue that I'm trying to convey to you is that your test is incomplete in that it does check that the interrupt was swallowed. Swallowing interrupts is bad practice. Reasserting in e2 only means that we swallow interrupts from e1. Change your test to this and retest: === public static void main(String[] args) throws Exception { Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); Thread.currentThread().interrupt(); ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { throw new RuntimeException("Couldn't load GIF from bytes after interruption"); } if (!Thread.currentThread().isInterrupted()) { throw new RuntimeException("Interrupt was swallowed"); } } } === ________________________________________ From: Volodin, Vladislav Sent: Wednesday, January 29, 2020 9:52 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, I have few questions: 1. The second assignment is probably redundant: } catch (InterruptedException e1) { wasInterrupted = true; // line #2, see comment below try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; // <-- this is redundant, because of the line #2 } } finally { 2. I think the first call of "addImage" is not necessary: boolean wasInterrupted = false; mTracker.addImage(image, id); // maybe I should remove this, because of another comment down below. try { loadStatus = 0; mTracker.addImage(image, id); // because of that May I also ask you a question? What is the purpose of interrupting the current thread in the finally block, instead of doing it in the second catch block (where e2 is created)? I assume that since we were able to handle the exception properly, and plus the entire block is in the synchronization area, in theory we have only one importer at the time. Kind regards, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 16:35 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Bug in that last version: Thread.currentThread().isInterrupted(); -> Thread.currentThread().interrupt(); === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().interrupt(); } } } } === ________________________________________ From: swing-dev on behalf of Jason Mehrens Sent: Wednesday, January 29, 2020 9:33 AM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage A shorter version is just to reassert at the end of catch e1. It is safer to just reassert as the last statement in the finally. === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().isInterrupted(); } } } } === Jason ________________________________________ From: Volodin, Vladislav Sent: Tuesday, January 28, 2020 4:02 PM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage This is a valid point, because I wasn?t sure that when the thread is interrupted, I handled the first exception, and my thought was that all other ?wait? calls (maybe in other threads) should get the same exception as well. And since I handled this exceptional case, I am restoring the interrupted status in case if I don?t know how to handle this exception the second time. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; Thread.currentThread().interrupt(); } If I restore the interrupted status BEFORE waitForID call, then this thread will immoderately fail. Should I restore it AFTER, e.g. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); Thread.currentThread().interrupt(); // wrote: ?I see. Well I would have to do some more digging and testing to make myself more knowledgeable on MediaTracker. Then the only bug in your current code is that you are not reasserting interrupted status of the current thread in the case e1 is raised and e2 is not. It is usually best to reassert the interrupted state at the end of the method. Jason ________________________________________ From: Volodin, Vladislav Sent: Tuesday, January 28, 2020 2:54 PM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Hi Jason, I am not sure about the loop, because I don?t know if we can trust results from mTracker.statusID at the moment when an exceptional case occurs. For example, I was experimenting with the code and found out that the MediaTracker can spawn a thread to load the image, or might use the current thread, and the ABORTED state is never returned (I don?t even know how to raise this state). That is why I don?t even know if your loop will ever stop. In my solution, I give the second chance only, and in case if the execution was interrupted the second time, I explicitly assign the ABORTED state to loadStatus. If the user wants to load this image once again, he can create ImageIcon again (or even do this in a loop), or reinitialize it with a single method (I don?t remember its name). What do you think? Kind regards, Vlad Sent from myPad On 28. Jan 2020, at 21:34, Jason Mehrens wrote: ?Vlad, I assume you would want to wait in a loop and reassert the interrupt at the end. === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized(mTracker) { int id = getNextID(); mTracker.addImage(image, id); boolean wasInterrupted = false; try { do { try { mTracker.waitForID(id, 0); } catch (InterruptedException e) { wasInterrupted = true; } loadStatus = mTracker.statusID(id, false); } while (loadStatus == MediaTracker.LOADING); mTracker.removeImage(image, id); width = image.getWidth(imageObserver); height = image.getHeight(imageObserver); } finally { if (wasInterrupted) { Thread.currentThread().interrupt(); } } } } === Jason ________________________________________ From: swing-dev on behalf of Volodin, Vladislav Sent: Monday, January 27, 2020 11:11 AM To: Sergey Bylokhov Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Hello Sergey, and others, here is the patch (made with "git diff") in the attachment. I have read that sometimes the attachments are lost. So here is my version with few comments regarding my code. I decided to use your approach with a small improvement. There is an excerpt of my patch. The idea is pretty simple: 1. I create an empty gif 1x1; 2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do not initialize the toolkit in advance, my test will fail at the beginning 3. Interrupt the main thread 4. Try to load the icon: import javax.swing.*; import java.awt.*; public class imageIconInterrupted { static byte[] EMPTY_GIF = new byte[]{ (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) 0x61, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, (byte) 0xF9, (byte) 0x04, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x02 }; public static void main(String[] args) throws Exception { Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); Thread.currentThread().interrupt(); ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { throw new RuntimeException("Couldn't load GIF from bytes after interruption"); } } } The code of loadImage I have changed as follows: 1. I clear loadStatus for "finally" part; 2. Check the interruption according to your comments; 3. Change the status to ABORTED, if the interruption happened again (this part I cannot test, because I cannot properly interrupt the thread whenever I want. Multithreading is quite fragile there :( ) 4. update the status "interrupted" again; 5. and then - finally block. protected void loadImage(Image image) { ... try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; Thread.currentThread().interrupt(); } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); } P.S. if you think that my patch sounds fine, I will find a sponsor for the bug report and the patch preparation, so you can review it later. After the second attempt, my EMPTY_GIF was loaded successfully. The ABORTED part it seems that I don't know if it has ever worked. My patch (in the attachment) checks also the state ERROR for the URL that doesn't exist. Something like: ImageIcon iconNotExist = new ImageIcon(new URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this URL grammatically correct if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) { throw new RuntimeException("Got unexpected status from non- existing GIF"); } Thanks to everyone. Kind regards, Vlad -----Original Message----- From: Sergey Bylokhov Sent: Dienstag, 21. Januar 2020 22:26 To: Volodin, Vladislav Cc: Jason Mehrens ; swing- dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage On 1/21/20 1:14 pm, Volodin, Vladislav wrote: Hi all, If I am not mistaken, this method is called from the constructor and other methods. How long should we try loading the icon using the unmanaged (by any thread pool, but I am not sure about this statement) thread? We don?t even have the flag ?interrupted?. So technically this icon has to be loaded. I think it is necessary to save the "interrupted" state in the catch block and try to call waitForID() again. It will be necessary to set "interrupted" flag for the Thread after that(when the waitForID will return without exception). Sent from myFone On 21. Jan 2020, at 21:55, Sergey Bylokhov wrote: ?On 1/21/20 12:26 pm, Jason Mehrens wrote: +1 for Sergey suggestion. Or probably we need to try to load the image again because of the spec of the method state this: "Loads the image, returning only when the image is loaded." ________________________________________ From: Sergey Bylokhov Sent: Sunday, January 19, 2020 9:31 PM To: Volodin, Vladislav; Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage I guess there are no objections, probably the best way to fix it is to drop the System.out.println and set interrupted flag. On 1/16/20 7:05 am, Volodin, Vladislav wrote: If people in this distribution list agree, I can start working on a simple fix and either remove the logging (System.out.println), or replace it with PlatformLogger. I guess the second solution sounds better, but I don't know what is the better way to write a test-case for it. -- Best regards, Sergey. -- Best regards, Sergey. -- Best regards, Sergey. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pankaj.b.bansal at oracle.com Thu Feb 6 07:46:35 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Wed, 5 Feb 2020 23:46:35 -0800 (PST) Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> Message-ID: Hello Vlad, Thanks for the review. < Cc: swing-dev at openjdk.java.net Subject: RE: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition Hello Pankaj, I apologize, if I interfere your job, I decided to study your code to learn JDK better, and I found out that the class BasicMenuItemUI has the method that looks quite simple: /*Returns a property prefix * @return a property prefix */ protected String getPropertyPrefix() { return "MenuItem"; } I don't understand why it was created as the method. Since you are changing this part, maybe it will make sense and replace it with a constant string? I hope Java compile can optimize method calls in situations like this one, if you use constant strings: String prefix = getPropertyPrefix(); ... (...) iconFactory = (...) UIManager.get(prefix + ".checkIconFactory"); Another thing: I see that in your code, you extract checkIcon, that might be overwritten by "if" statement: checkIcon = UIManager.getIcon(prefix + ".checkIcon"); // here we assign, and (look down) boolean isColumnLayout = ...; if (isColumnLayout) { ... if (...) { checkIcon = iconFactory.getIcon(menuItem); // <-- here we might overwrite checkIcon } } What do you think, would it be more efficient, if your "first" line will be executed in the "else" branch of the "if" statement? Feel free to ignore my suggestion, if you think that it misleading. Thanks, Vlad -----Original Message----- From: swing-dev On Behalf Of Pankaj Bansal Sent: Mittwoch, 5. Februar 2020 14:00 To: Sergey Bylokhov ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition Hello Sergey, << ok. <; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition On 1/29/20 2:25 am, Pankaj Bansal wrote: > One more point, I am able to reproduce the current issue with Synth LookAndFeel in all platforms without fix and it works fine with the fix. ok. Do we need to remove the listener added to the menuItem? I guess it will be added every time we change L&F to the windows and will never be removed. > > Regards, > Pankaj > > -----Original Message----- > From: Pankaj Bansal > Sent: Wednesday, January 29, 2020 3:19 PM > To: Sergey Bylokhov; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize > CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > Hello Sergey, > > << Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? > < I changed the test in JDK-8152981 to run on all installed LookAndFeels on windows, linux and Mac after removing the windows only condition. The tests passes on all platforms with all LookAndFeels with the current fix. > I can check in this change in JDK-8152981 test along with the current fix if needed, though I feel it is not required as the issue was originally only in WindowsLookAndFeel. > > Regards, > Pankaj Bansal > > -----Original Message----- > From: Sergey Bylokhov > Sent: Wednesday, January 29, 2020 1:17 PM > To: Pankaj Bansal; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize > CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>> << It is not a big issue, but for such a fix we will need a proper specification and CSR, it is like adding a new method to the public class. It is preferable to try to fix it in some other way first. >>> I did not realize earlier that this can be done by making changes in WindowsMenuItemUI without calling the updateCheckIcon by moving the code in updateCheckIcon method in WindowsMenuItemUI class. I have made the changes for the same and all works fine. Also, I have removed the updateCheckIcon method from BasicMenuItemUI class as it is not needed. >> >> Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? > > For example if some other "basic" L&F will be used(Motif, Aqua)? > > -- Best regards, Sergey. From pankaj.b.bansal at oracle.com Fri Feb 7 08:25:05 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Fri, 7 Feb 2020 00:25:05 -0800 (PST) Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue Message-ID: Hi All, Please review the following fix for jdk15. Bug: https://bugs.openjdk.java.net/browse/JDK-8220811 webrev: http://cr.openjdk.java.net/~pbansal/8220811/webrev00/ Issue: In case of JSpinner with double/float values, sometime the spinner value does not change even though the value is within the min, max range. Cause: The bug is caused by errors in floating point math. Eg, if we create a JSpinner with min=0.15, max=1.0, stepsize =.05, if current value is -.10, it is not possible to go to -.15 by pressing the decrement button. a=-.10, b=-.05, the c=a+b is not equal to -.15. Instead is something like -.150000000345. This caused issues as this values is considered lower than -.15, which minimum value allowed for the JSpinner. So the value of spinner cannot be decreased to -.15, though it should be possible. Fix: The fix is different for double and float values. For double values, just using the BigDecimal class to do the floating point math operations solves the issues. This change is needed for float values as well along with the change mentioned below. For float, there is one addition issue. There is no constructor in SpinnerNumberModel, which will accept float values. There is a constructor which accepts double values. So, even if all float values are passed to SpinnerNumberModel, the constructor accepting double values is called. So, the float values are implicitly casted to double. This implicit casting causes issue because if float a=.95, double b = a, then b is not exactly equal to .95. Instead it is something like .950000045. So in case of float values, the issue starts on from the creation of SpinnerNumberModel. So a new constructor for float values is added to the SpinnerNumberModel class. This fix will need CSR, I will get to it after the review is completed here. Regards, Pankaj Bansal -------------- next part -------------- An HTML attachment was scrubbed... URL: From Sergey.Bylokhov at oracle.com Fri Feb 7 22:44:19 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Fri, 7 Feb 2020 14:44:19 -0800 Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> Message-ID: <996f20a4-b238-bb29-a94b-2efe92be65c0@oracle.com> Hi, Vladislav. On 2/5/20 5:25 am, Volodin, Vladislav wrote: > /*Returns a property prefix > * @return a property prefix */ > protected String getPropertyPrefix() { > return "MenuItem"; > } > > I don't understand why it was created as the method. Since you are changing this part, maybe it will make sense and replace it with a constant string? I hope Java compile can optimize method calls in situations like this one, if you use constant strings: This is a protected method in the public class in "javax.swing.plaf.basic" package so this is the "Public API" which cannot be changed(at least hard to change) -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Fri Feb 7 22:44:47 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Fri, 7 Feb 2020 14:44:47 -0800 Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> Message-ID: Looks fine. On 2/5/20 5:00 am, Pankaj Bansal wrote: > Hello Sergey, > > << ok. > < < > > Yes, it should be done. > Webrev: http://cr.openjdk.java.net/~pbansal/8216329/webrev02/ > > Regards, > Pankaj > > -----Original Message----- > From: Sergey Bylokhov > Sent: Thursday, January 30, 2020 5:59 AM > To: Pankaj Bansal ; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > On 1/29/20 2:25 am, Pankaj Bansal wrote: >> One more point, I am able to reproduce the current issue with Synth LookAndFeel in all platforms without fix and it works fine with the fix. > > ok. > > Do we need to remove the listener added to the menuItem? > I guess it will be added every time we change L&F to the windows and will never be removed. > > >> >> Regards, >> Pankaj >> >> -----Original Message----- >> From: Pankaj Bansal >> Sent: Wednesday, January 29, 2020 3:19 PM >> To: Sergey Bylokhov; swing-dev at openjdk.java.net >> Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >> >> Hello Sergey, >> >> << Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? >> <> I changed the test in JDK-8152981 to run on all installed LookAndFeels on windows, linux and Mac after removing the windows only condition. The tests passes on all platforms with all LookAndFeels with the current fix. >> I can check in this change in JDK-8152981 test along with the current fix if needed, though I feel it is not required as the issue was originally only in WindowsLookAndFeel. >> >> Regards, >> Pankaj Bansal >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Wednesday, January 29, 2020 1:17 PM >> To: Pankaj Bansal; swing-dev at openjdk.java.net >> Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >> >> On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >>> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>>> << It is not a big issue, but for such a fix we will need a proper specification and CSR, it is like adding a new method to the public class. It is preferable to try to fix it in some other way first. >>>> I did not realize earlier that this can be done by making changes in WindowsMenuItemUI without calling the updateCheckIcon by moving the code in updateCheckIcon method in WindowsMenuItemUI class. I have made the changes for the same and all works fine. Also, I have removed the updateCheckIcon method from BasicMenuItemUI class as it is not needed. >>> >>> Can you please double check that it is not possible to reproduce JDK-8152981 even if the test is modified in some way? >> >> For example if some other "basic" L&F will be used(Motif, Aqua)? >> >> > > -- Best regards, Sergey. From philip.race at oracle.com Sat Feb 8 19:36:51 2020 From: philip.race at oracle.com (Philip Race) Date: Sat, 08 Feb 2020 11:36:51 -0800 Subject: RFR: 823872: Add failing client jtreg tests to the Problem List Message-ID: <5E3F0DD3.9030408@oracle.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8238721 Webrev : http://cr.openjdk.java.net/~prr/8238721/ -phil. From Sergey.Bylokhov at oracle.com Sat Feb 8 19:45:58 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Sat, 8 Feb 2020 11:45:58 -0800 Subject: RFR: 823872: Add failing client jtreg tests to the Problem List In-Reply-To: <5E3F0DD3.9030408@oracle.com> References: <5E3F0DD3.9030408@oracle.com> Message-ID: <016ef9ab-38a7-412a-fb5e-5fcb7f658d1a@oracle.com> +1 On 2/8/20 11:36 am, Philip Race wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8238721 > Webrev : http://cr.openjdk.java.net/~prr/8238721/ > > -phil. -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Tue Feb 11 02:16:35 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Mon, 10 Feb 2020 18:16:35 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: Message-ID: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> Hi, Pankaj. Could you please try to use Math.fma instead of direct using of xxx.toString+BigDecimal if (value instanceof Double) { newValue = Math.fma(stepSize.doubleValue(), dir, value.doubleValue()); } else { newValue = Math.fma(stepSize.floatValue(), dir, value.floatValue()); } Are you sure that it is necessary to add a new constructor? As far as I understand it is possible to pass a float value via: public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) { On 2/7/20 12:25 am, Pankaj Bansal wrote: > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8220811 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8220811/webrev00/ > > Issue: > > In case of JSpinner with double/float values, ?sometime the spinner value does not change even though the value is within the min, max range. > > Cause: > > The bug is caused by errors in floating point math. > > Eg, if we create a JSpinner with min=0.15, max=1.0, stepsize =.05, if current value is -.10, it is not possible to go to -.15 by pressing the decrement button. > > a=-.10, b=-.05, the c=a+b is not equal to -.15. Instead is something like -.150000000345. This caused issues as this values is considered lower than -.15, which minimum value allowed for the JSpinner. So the value of spinner cannot be decreased to -.15, though it should be possible. > > Fix: > > The fix is different for double and float values. > > For double values, just using the BigDecimal class to do the floating point math operations solves the issues. This change is needed for float values as well along with the change mentioned below. > > For float, there is one addition issue. There is no constructor in SpinnerNumberModel, which will accept float values. There is a constructor which accepts double values. So, even if all float values are passed to SpinnerNumberModel, the constructor accepting double values is called. So, the float values are implicitly casted to double. This implicit casting causes issue because if float a=.95, double b = a, then b is not exactly equal to .95. Instead it is something like .950000045. So in case of float values, the issue starts on from the creation of SpinnerNumberModel. So a new constructor for float values is added to the SpinnerNumberModel class. > > This fix will need CSR, I will get to it after the review is completed here. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From pankaj.b.bansal at oracle.com Tue Feb 11 11:40:52 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Tue, 11 Feb 2020 03:40:52 -0800 (PST) Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> Message-ID: <4db1f723-0f5a-4d66-8db6-529897885d79@default> Hello Sergey, Thanks for the review. I have created a Test.java file for the points I have mentioned below. http://cr.openjdk.java.net/~pbansal/8220811/Test.java << Could you please try to use Math.fma instead of direct using of xxx.toString+BigDecimal I tried using this, but Math.fma will not solve our issue of precision here. Math.fma internally creates BigDecimal, but it uses the [1] type constructor to create the BigDecimal. The [1] constructor takes the primitive double value and it tries to represent the primitive double as precisely as possible and adds the extra precision. After the calculations in fma, the BigDecimal is rounded off to create double, but as it has very high precision, the issue in spinner is still there. In my changes in webrev00, I have used the [2] form of constructor, which does not add extra precision and works fine for our case. I have created a dummy patch if you would like to try out this change with Math.fma (http://cr.openjdk.java.net/~pbansal/8220811/dummy.patch) [1] new BigDecimal(double d) [2] new BigDecimal(String s) https://stackoverflow.com/questions/7186204/bigdecimal-to-use-new-or-valueof << Are you sure that it is necessary to add a new constructor? As far as I understand it is possible to pass a float value via: In java the implicit type promotion (auto-widening) is preferred over the auto boxing/unboxing. The SpinnerNumberModel has two constructors, one accepts all primitive "double" arguments [4] and other accepts Objects [3]. Now when SpinnerNumberModel is passed primitive "float" values, it looks for constructor which accepts all primitive floats. As such constructor is not available, it checks for alternatives. It has two alternates, either box the primitive "float" into object "Float" and call [3] or widen the primitive "float" to primitive "double". As auto widening is preferred over auto boxing, [4] is called instead of [3]. As I mentioned in previous mail, implicitly casting primitive float to primitive double adds precision issues So either we need to add the constructor which accepts "float", or we can remove the constructor which accepts "double". Both will work fine. I just decided to add float one. There are few other wrong things in the class which are not causing any issue as of now. There is one constructor which accepts primitive int [5]. So if we use, primitives byte, short, int, it will call [5]. But if we try to use primitive "long", it will end up calling double constructor [4] as long can't be passes to int and as auto widening is preferred over auto boxing. It unnecessarily adds floating point calculations for long type. I think we should remove both [4] and [5] and keep only [3]. This should work for all the cases. But I am not sure if we would be removing some constructor, so I did not propose this. [3] public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) [4] public SpinnerNumberModel(double value, double minimum, double maximum, double stepSize) [5] public SpinnerNumberModel(int value, int minimum, int maximum, int stepSize) Regards, Pankaj -----Original Message----- From: Sergey Bylokhov Sent: Tuesday, February 11, 2020 7:47 AM To: Pankaj Bansal ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue Hi, Pankaj. Could you please try to use Math.fma instead of direct using of xxx.toString+BigDecimal if (value instanceof Double) { newValue = Math.fma(stepSize.doubleValue(), dir, value.doubleValue()); } else { newValue = Math.fma(stepSize.floatValue(), dir, value.floatValue()); } Are you sure that it is necessary to add a new constructor? As far as I understand it is possible to pass a float value via: public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) { On 2/7/20 12:25 am, Pankaj Bansal wrote: > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8220811 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8220811/webrev00/ > > Issue: > > In case of JSpinner with double/float values, ?sometime the spinner value does not change even though the value is within the min, max range. > > Cause: > > The bug is caused by errors in floating point math. > > Eg, if we create a JSpinner with min=0.15, max=1.0, stepsize =.05, if current value is -.10, it is not possible to go to -.15 by pressing the decrement button. > > a=-.10, b=-.05, the c=a+b is not equal to -.15. Instead is something like -.150000000345. This caused issues as this values is considered lower than -.15, which minimum value allowed for the JSpinner. So the value of spinner cannot be decreased to -.15, though it should be possible. > > Fix: > > The fix is different for double and float values. > > For double values, just using the BigDecimal class to do the floating point math operations solves the issues. This change is needed for float values as well along with the change mentioned below. > > For float, there is one addition issue. There is no constructor in SpinnerNumberModel, which will accept float values. There is a constructor which accepts double values. So, even if all float values are passed to SpinnerNumberModel, the constructor accepting double values is called. So, the float values are implicitly casted to double. This implicit casting causes issue because if float a=.95, double b = a, then b is not exactly equal to .95. Instead it is something like .950000045. So in case of float values, the issue starts on from the creation of SpinnerNumberModel. So a new constructor for float values is added to the SpinnerNumberModel class. > > This fix will need CSR, I will get to it after the review is completed here. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From jason_mehrens at hotmail.com Tue Feb 11 15:43:41 2020 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Tue, 11 Feb 2020 15:43:41 +0000 Subject: Remove System.out.println from ImageIcon.loadImage In-Reply-To: References: <2310F0FD-DAA6-4E24-85AD-776D6F979CC0@sap.com> <549622d0-fe72-f267-c105-53b1399471dc@oracle.com>, , , <6CA1C9A2-3FE1-445D-93B7-57DC8818F0FB@sap.com>, , , , , Message-ID: Vlad, Yea that looks good. Jason ________________________________________ From: Volodin, Vladislav Sent: Wednesday, February 5, 2020 9:59 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, thank you for your advice. I have changed my code, now it simulates the behavior of the interrupted thread. Can you please check my patch? I don't have the "bug" ticket, so in my test case "@bug JDK-123456" should be adjusted. I will appreciate if you and somebody else can review my patch and submit it to JDK. Thanks, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 17:55 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage 1. Agreed. 2. I was just pulling from the jdk8 source (because I'm lazy) to express the idea. Feel free to adjust. 3. Reasserting in the finally ensure we are not forcefully setting the interrupted status on the current thread and calling 'statusID' and 'removeImage'. It also ensures that the interrupt is set even if an unexpected exception is thrown. Reasserting at the end of 'e1' and never in 'e2' should work too. The main issue that I'm trying to convey to you is that your test is incomplete in that it does check that the interrupt was swallowed. Swallowing interrupts is bad practice. Reasserting in e2 only means that we swallow interrupts from e1. Change your test to this and retest: === public static void main(String[] args) throws Exception { Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); Thread.currentThread().interrupt(); ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { throw new RuntimeException("Couldn't load GIF from bytes after interruption"); } if (!Thread.currentThread().isInterrupted()) { throw new RuntimeException("Interrupt was swallowed"); } } } === ________________________________________ From: Volodin, Vladislav Sent: Wednesday, January 29, 2020 9:52 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, I have few questions: 1. The second assignment is probably redundant: } catch (InterruptedException e1) { wasInterrupted = true; // line #2, see comment below try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; // <-- this is redundant, because of the line #2 } } finally { 2. I think the first call of "addImage" is not necessary: boolean wasInterrupted = false; mTracker.addImage(image, id); // maybe I should remove this, because of another comment down below. try { loadStatus = 0; mTracker.addImage(image, id); // because of that May I also ask you a question? What is the purpose of interrupting the current thread in the finally block, instead of doing it in the second catch block (where e2 is created)? I assume that since we were able to handle the exception properly, and plus the entire block is in the synchronization area, in theory we have only one importer at the time. Kind regards, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 16:35 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Bug in that last version: Thread.currentThread().isInterrupted(); -> Thread.currentThread().interrupt(); === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().interrupt(); } } } } === ________________________________________ From: swing-dev on behalf of Jason Mehrens Sent: Wednesday, January 29, 2020 9:33 AM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage A shorter version is just to reassert at the end of catch e1. It is safer to just reassert as the last statement in the finally. === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().isInterrupted(); } } } } === Jason ________________________________________ From: Volodin, Vladislav Sent: Tuesday, January 28, 2020 4:02 PM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage This is a valid point, because I wasn?t sure that when the thread is interrupted, I handled the first exception, and my thought was that all other ?wait? calls (maybe in other threads) should get the same exception as well. And since I handled this exceptional case, I am restoring the interrupted status in case if I don?t know how to handle this exception the second time. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; Thread.currentThread().interrupt(); } If I restore the interrupted status BEFORE waitForID call, then this thread will immoderately fail. Should I restore it AFTER, e.g. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); Thread.currentThread().interrupt(); // On 28. Jan 2020, at 22:27, Jason Mehrens wrote: > > ?I see. Well I would have to do some more digging and testing to make myself more knowledgeable on MediaTracker. > > Then the only bug in your current code is that you are not reasserting interrupted status of the current thread in the case e1 is raised and e2 is not. It is usually best to reassert the interrupted state at the end of the method. > > Jason > > ________________________________________ > From: Volodin, Vladislav > Sent: Tuesday, January 28, 2020 2:54 PM > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from ImageIcon.loadImage > > Hi Jason, > > I am not sure about the loop, because I don?t know if we can trust results from mTracker.statusID at the moment when an exceptional case occurs. For example, I was experimenting with the code and found out that the MediaTracker can spawn a thread to load the image, or might use the current thread, and the ABORTED state is never returned (I don?t even know how to raise this state). That is why I don?t even know if your loop will ever stop. > > In my solution, I give the second chance only, and in case if the execution was interrupted the second time, I explicitly assign the ABORTED state to loadStatus. If the user wants to load this image once again, he can create ImageIcon again (or even do this in a loop), or reinitialize it with a single method (I don?t remember its name). > > What do you think? > > Kind regards, > Vlad > > Sent from myPad > >> On 28. Jan 2020, at 21:34, Jason Mehrens wrote: >> >> ?Vlad, >> >> I assume you would want to wait in a loop and reassert the interrupt at the end. >> >> === >> protected void loadImage(Image image) { >> MediaTracker mTracker = getTracker(); >> synchronized(mTracker) { >> int id = getNextID(); >> >> mTracker.addImage(image, id); >> boolean wasInterrupted = false; >> try { >> do { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e) { >> wasInterrupted = true; >> } >> loadStatus = mTracker.statusID(id, false); >> } while (loadStatus == MediaTracker.LOADING); >> mTracker.removeImage(image, id); >> >> width = image.getWidth(imageObserver); >> height = image.getHeight(imageObserver); >> } finally { >> if (wasInterrupted) { >> Thread.currentThread().interrupt(); >> } >> } >> } >> } >> === >> >> Jason >> ________________________________________ >> From: swing-dev on behalf of Volodin, Vladislav >> Sent: Monday, January 27, 2020 11:11 AM >> To: Sergey Bylokhov >> Cc: swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >> Hello Sergey, and others, >> >> here is the patch (made with "git diff") in the attachment. I have read that sometimes the attachments are lost. So here is my version with few comments regarding my code. I decided to use your approach with a small improvement. There is an excerpt of my patch. >> >> The idea is pretty simple: >> 1. I create an empty gif 1x1; >> 2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do not initialize the toolkit in advance, my test will fail at the beginning >> 3. Interrupt the main thread >> 4. Try to load the icon: >> >> import javax.swing.*; >> import java.awt.*; >> >> public class imageIconInterrupted { >> static byte[] EMPTY_GIF = new byte[]{ >> (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) 0x61, (byte) 0x01, (byte) 0x00, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, (byte) 0xF9, (byte) 0x04, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2C, (byte) 0x00, (byte) 0x00, >> (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x02 >> }; >> >> public static void main(String[] args) throws Exception { >> Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); >> >> Thread.currentThread().interrupt(); >> ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); >> if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { >> throw new RuntimeException("Couldn't load GIF from bytes after interruption"); >> } >> } >> } >> >> The code of loadImage I have changed as follows: >> 1. I clear loadStatus for "finally" part; >> 2. Check the interruption according to your comments; >> 3. Change the status to ABORTED, if the interruption happened again (this part I cannot test, because I cannot properly interrupt the thread whenever I want. Multithreading is quite fragile there :( ) >> 4. update the status "interrupted" again; >> 5. and then - finally block. >> >> protected void loadImage(Image image) { >> ... >> try { >> loadStatus = 0; >> mTracker.addImage(image, id); >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e1) { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e2) { >> loadStatus = MediaTracker.ABORTED; >> Thread.currentThread().interrupt(); >> } >> } finally { >> if (loadStatus == 0) { >> loadStatus = mTracker.statusID(id, false); >> } >> mTracker.removeImage(image, id); >> } >> >> P.S. if you think that my patch sounds fine, I will find a sponsor for the bug report and the patch preparation, so you can review it later. >> After the second attempt, my EMPTY_GIF was loaded successfully. The ABORTED part it seems that I don't know if it has ever worked. My patch (in the attachment) checks also the state ERROR for the URL that doesn't exist. Something like: >> >> ImageIcon iconNotExist = new ImageIcon(new URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this URL grammatically correct >> if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) { >> throw new RuntimeException("Got unexpected status from non-existing GIF"); >> } >> >> Thanks to everyone. >> >> Kind regards, >> Vlad >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Dienstag, 21. Januar 2020 22:26 >> To: Volodin, Vladislav >> Cc: Jason Mehrens ; swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >>>> On 1/21/20 1:14 pm, Volodin, Vladislav wrote: >>> Hi all, >>> >>> If I am not mistaken, this method is called from the constructor and other methods. How long should we try loading the icon using the unmanaged (by any thread pool, but I am not sure about this statement) thread? >>> >>> We don?t even have the flag ?interrupted?. So technically this icon has to be loaded. >> >> I think it is necessary to save the "interrupted" state in the catch >> block and try to call waitForID() again. It will be necessary to set >> "interrupted" flag for the Thread after that(when the waitForID will >> return without exception). >> >> >>> Sent from myFone >>> >>>>> On 21. Jan 2020, at 21:55, Sergey Bylokhov wrote: >>>> >>>> ?On 1/21/20 12:26 pm, Jason Mehrens wrote: >>>>> +1 for Sergey suggestion. >>>> >>>> Or probably we need to try to load the image again because of the spec of the method state this: >>>> "Loads the image, returning only when the image is loaded." >>>> >>>>> ________________________________________ >>>>> From: Sergey Bylokhov >>>>> Sent: Sunday, January 19, 2020 9:31 PM >>>>> To: Volodin, Vladislav; Jason Mehrens >>>>> Cc: swing-dev at openjdk.java.net >>>>> Subject: Re: Remove System.out.println from ImageIcon.loadImage >>>>> I guess there are no objections, probably the best way to fix >>>>> it is to drop the System.out.println and set interrupted flag. >>>>> On 1/16/20 7:05 am, Volodin, Vladislav wrote: >>>>>> If people in this distribution list agree, I can start working on a simple fix and either remove the logging (System.out.println), or replace it with PlatformLogger. I guess the second solution sounds better, but I don't know what is the better way to write a test-case for it. >>>>> -- >>>>> Best regards, Sergey. >>>> >>>> >>>> -- >>>> Best regards, Sergey. >> >> >> -- >> Best regards, Sergey. From Sergey.Bylokhov at oracle.com Tue Feb 11 20:47:02 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 11 Feb 2020 12:47:02 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <4db1f723-0f5a-4d66-8db6-529897885d79@default> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> Message-ID: On 2/11/20 3:40 am, Pankaj Bansal wrote: > << Could you please try to use Math.fma instead of direct using of xxx.toString+BigDecimal > I tried using this, but Math.fma will not solve our issue of precision here. Math.fma internally creates BigDecimal, but it uses the [1] type constructor to create the BigDecimal. The [1] constructor takes the primitive double value and it tries to represent the primitive double as precisely as possible and adds the extra precision. After the calculations in fma, the BigDecimal is rounded off to create double, but as it has very high precision, the issue in spinner is still there. So if the constructor [2] does not add an additional precision means that we actually lost the precision. What will happen if the user will use a tiny double parameters which is outside of your proposal? like 0.00000000000000001? I guess we should do the best to try not to lost a precision, and leave rounding issues as-is since this is well just floating arithmetics which works according the specification of SpinnerNumberModel.getNextValue: " @return value + stepSize " So we can use fma for the best result, or we could close this as not a bug. > In my changes in webrev00, I have used the [2] form of constructor, which does not add extra precision and works fine for our case. > I have created a dummy patch if you would like to try out this change with Math.fma (http://cr.openjdk.java.net/~pbansal/8220811/dummy.patch) > > [1] new BigDecimal(double d) > [2] new BigDecimal(String s) > https://stackoverflow.com/questions/7186204/bigdecimal-to-use-new-or-valueof > > > > << Are you sure that it is necessary to add a new constructor? As far as I understand it is possible to pass a float value via: > In java the implicit type promotion (auto-widening) is preferred over the auto boxing/unboxing. The SpinnerNumberModel has two constructors, one accepts all primitive "double" arguments [4] and other accepts Objects [3]. Now when SpinnerNumberModel is passed primitive "float" values, it looks for constructor which accepts all primitive floats. As such constructor is not available, it checks for alternatives. It has two alternates, either box the primitive "float" into object "Float" and call [3] or widen the primitive "float" to primitive "double". As auto widening is preferred over auto boxing, [4] is called instead of [3]. As I mentioned in previous mail, implicitly casting primitive float to primitive double adds precision issues But it is possible to create Float.valueOf(float) and pass it to this constructor, isn't it? this will work for any primitives. [3] public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) -- Best regards, Sergey. From pankaj.b.bansal at oracle.com Wed Feb 12 06:29:24 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Tue, 11 Feb 2020 22:29:24 -0800 (PST) Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> Message-ID: Hello Sergey, < minimum, Comparable maximum, Number stepSize) Yes, it is true. If we create "Float" objects from primitive float and pass to the constructor, things work fine. But what if the user is passing the primitive float values directly? As the double constructor is there, it is called instead of this constructor which accepts objects. This creates issue. I don?t see this in spec that users should not use primitive float directly and should first create "Float" object and then create SpinnerNumberModel. So they will use primitive floats directly and run into these issues. As I suggested earlier, either we should remove constructors with primitive double or add constructor for primitive float. Regards, Pankaj Bansal -----Original Message----- From: Sergey Bylokhov Sent: Wednesday, February 12, 2020 2:17 AM To: Pankaj Bansal ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue On 2/11/20 3:40 am, Pankaj Bansal wrote: > << Could you please try to use Math.fma instead of direct using of > xxx.toString+BigDecimal I tried using this, but Math.fma will not solve our issue of precision here. Math.fma internally creates BigDecimal, but it uses the [1] type constructor to create the BigDecimal. The [1] constructor takes the primitive double value and it tries to represent the primitive double as precisely as possible and adds the extra precision. After the calculations in fma, the BigDecimal is rounded off to create double, but as it has very high precision, the issue in spinner is still there. So if the constructor [2] does not add an additional precision means that we actually lost the precision. What will happen if the user will use a tiny double parameters which is outside of your proposal? like 0.00000000000000001? I guess we should do the best to try not to lost a precision, and leave rounding issues as-is since this is well just floating arithmetics which works according the specification of SpinnerNumberModel.getNextValue: " @return value + stepSize " So we can use fma for the best result, or we could close this as not a bug. > In my changes in webrev00, I have used the [2] form of constructor, which does not add extra precision and works fine for our case. > I have created a dummy patch if you would like to try out this change > with Math.fma > (http://cr.openjdk.java.net/~pbansal/8220811/dummy.patch) > > [1] new BigDecimal(double d) > [2] new BigDecimal(String s) > https://stackoverflow.com/questions/7186204/bigdecimal-to-use-new-or-v > alueof > > > > << Are you sure that it is necessary to add a new constructor? As far as I understand it is possible to pass a float value via: > In java the implicit type promotion (auto-widening) is preferred over > the auto boxing/unboxing. The SpinnerNumberModel has two constructors, > one accepts all primitive "double" arguments [4] and other accepts > Objects [3]. Now when SpinnerNumberModel is passed primitive "float" > values, it looks for constructor which accepts all primitive floats. > As such constructor is not available, it checks for alternatives. It > has two alternates, either box the primitive "float" into object > "Float" and call [3] or widen the primitive "float" to primitive > "double". As auto widening is preferred over auto boxing, [4] is > called instead of [3]. As I mentioned in previous mail, implicitly > casting primitive float to primitive double adds precision issues But it is possible to create Float.valueOf(float) and pass it to this constructor, isn't it? this will work for any primitives. [3] public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Wed Feb 12 07:39:05 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 11 Feb 2020 23:39:05 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> Message-ID: > I am not able to find any issue with this approach. Sometimes there are difference: double b = 0.10000000000000011; constructor [1]: 0.1000000000000001165734175856414367444813251495361328125 constructor [2]: 0.10000000000000012 > < <<[3] public SpinnerNumberModel(Number value, > Comparable minimum, > Comparable maximum, > Number stepSize) > > Yes, it is true. If we create "Float" objects from primitive float and pass to the constructor, things work fine. But what if the user is passing the primitive float values directly? As the double constructor is there, it is called instead of this constructor which accepts objects. This creates issue. > I don?t see this in spec that users should not use primitive float directly and should first create "Float" object and then create SpinnerNumberModel. So they will use primitive floats directly and run into these issues. This is described in the top level specification of this class. > As I suggested earlier, either we should remove constructors with primitive double or add constructor for primitive float. The primitive variants are there because it was decided that "integers and doubles" are quite common, so they have special constructors, this is also described in the top-level spec of the class. -- Best regards, Sergey. From pankaj.b.bansal at oracle.com Wed Feb 12 07:52:40 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Tue, 11 Feb 2020 23:52:40 -0800 (PST) Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> Message-ID: <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> Hi Sergey, << Sometimes there are difference: Ok, I see it now. So, should I just close this bug as not an issue with proper comments or make changes using Math.fma for best possible results? The probability of issue happening will decrease using Math.fma(b, c, a) as compared to normal a+b*c. Regards, Pankaj -----Original Message----- From: Sergey Bylokhov Sent: Wednesday, February 12, 2020 1:09 PM To: Pankaj Bansal ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue > I am not able to find any issue with this approach. Sometimes there are difference: double b = 0.10000000000000011; constructor [1]: 0.1000000000000001165734175856414367444813251495361328125 constructor [2]: 0.10000000000000012 > < <<[3] public SpinnerNumberModel(Number value, > Comparable minimum, > Comparable maximum, > Number stepSize) > > Yes, it is true. If we create "Float" objects from primitive float and pass to the constructor, things work fine. But what if the user is passing the primitive float values directly? As the double constructor is there, it is called instead of this constructor which accepts objects. This creates issue. > I don?t see this in spec that users should not use primitive float directly and should first create "Float" object and then create SpinnerNumberModel. So they will use primitive floats directly and run into these issues. This is described in the top level specification of this class. > As I suggested earlier, either we should remove constructors with primitive double or add constructor for primitive float. The primitive variants are there because it was decided that "integers and doubles" are quite common, so they have special constructors, this is also described in the top-level spec of the class. -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Wed Feb 12 07:59:46 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 11 Feb 2020 23:59:46 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> Message-ID: On 2/11/20 11:52 pm, Pankaj Bansal wrote: > Hi Sergey, > > << Sometimes there are difference: > Ok, I see it now. So, should I just close this bug as not an issue with proper comments or make changes using Math.fma for best possible results? The probability of issue happening will decrease using Math.fma(b, c, a) as compared to normal a+b*c. According to the source code, the multiplication is needed only to change the sign of the result so c is always -1 or 1, not sure is it possible to get some rounding issues or not(need to check somehow)? > > Regards, > Pankaj > > -----Original Message----- > From: Sergey Bylokhov > Sent: Wednesday, February 12, 2020 1:09 PM > To: Pankaj Bansal ; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue > >> I am not able to find any issue with this approach. > Sometimes there are difference: > > double b = 0.10000000000000011; > > constructor [1]: 0.1000000000000001165734175856414367444813251495361328125 > constructor [2]: 0.10000000000000012 > >> <> <<[3] public SpinnerNumberModel(Number value, >> Comparable minimum, >> Comparable maximum, >> Number stepSize) >> >> Yes, it is true. If we create "Float" objects from primitive float and pass to the constructor, things work fine. But what if the user is passing the primitive float values directly? As the double constructor is there, it is called instead of this constructor which accepts objects. This creates issue. >> I don?t see this in spec that users should not use primitive float directly and should first create "Float" object and then create SpinnerNumberModel. So they will use primitive floats directly and run into these issues. > > This is described in the top level specification of this class. > >> As I suggested earlier, either we should remove constructors with primitive double or add constructor for primitive float. > > The primitive variants are there because it was decided that "integers and doubles" are quite common, so they have special constructors, this is also described in the top-level spec of the class. > -- Best regards, Sergey. From alexey.ivanov at oracle.com Wed Feb 12 16:21:06 2020 From: alexey.ivanov at oracle.com (Alexey Ivanov) Date: Wed, 12 Feb 2020 16:21:06 +0000 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> Message-ID: Hi Sergey, Pankaj, On 12/02/2020 07:59, Sergey Bylokhov wrote: > On 2/11/20 11:52 pm, Pankaj Bansal wrote: >> Hi Sergey, >> >> << Sometimes there are difference: >> Ok, I see it now. So, should I just close this bug as not an issue >> with proper comments or make changes using Math.fma for best possible >> results? The probability of issue happening will decrease using >> Math.fma(b, c, a) as compared to normal a+b*c. > > According to the source code, the multiplication is needed only to > change the sign of the result so c is always -1 or 1, not sure is it > possible to get some rounding issues or not(need to check somehow)? Can it be replaced with simple addition / subtraction: newValue = currentValue - step; or newValue = currentValue + step; On another note, we know there's always a possibility for rounding errors; in addition, many decimal fractions cannot be represented exactly as a binary fraction. Can we solve the problem another way then? The bug report says that going from -0.15 to -0.10 does not allow going back to -0.15. This happens because the result of this sequence of operations cannot be represented exactly, or, in other words, because of rounding errors; or rather the result is less than the set minimal value. Can we set the value of the spinner to the set minimal value instead of disallowing the operation. I mean, after going up the displayed value is -0.10; going down by 0.05 gives the result which is less than the minimal value for the spinner, and thus going down is not allowed. What if we set the value of the spinner to its minimal value instead? Would it work? It should. > >> >> Regards, >> Pankaj >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Wednesday, February 12, 2020 1:09 PM >> To: Pankaj Bansal ; >> swing-dev at openjdk.java.net >> Subject: Re: [15] RFR JDK-8220811: SpinnerNumberModel >> floating point rounding issue >> >>> I am not able to find any issue with this approach. >> Sometimes there are difference: >> >> double b = 0.10000000000000011; >> >> constructor [1]: >> 0.1000000000000001165734175856414367444813251495361328125 >> constructor [2]: 0.10000000000000012 >> >>> <>> this constructor, isn't it? this will work for any primitives. >>> <<[3]???? public SpinnerNumberModel(Number value, >>> ?????????????????????????????????? Comparable minimum, >>> ?????????????????????????????????? Comparable maximum, >>> ?????????????????????????????????? Number stepSize) >>> >>> Yes, it is true. If we create "Float" objects from primitive float >>> and pass to the constructor, things work fine. But what if the user >>> is passing the primitive float values directly? As the double >>> constructor is there, it is called instead of this constructor which >>> accepts objects. This creates issue. >>> I don?t see this in spec that users should not use primitive float >>> directly and should first create "Float" object and then create >>> SpinnerNumberModel. So they will use primitive floats directly and >>> run into these issues. >> >> This is described in the top level specification of this class. >> >>> As I suggested earlier, either we should remove constructors with >>> primitive double or add constructor for primitive float. >> >> The primitive variants are there because it was decided that >> "integers and doubles" are quite common, so they have special >> constructors, this is also described in the top-level spec of the class. >> -- Regards, Alexey From Sergey.Bylokhov at oracle.com Thu Feb 13 21:33:40 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 13 Feb 2020 13:33:40 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> Message-ID: On 2/12/20 8:21 am, Alexey Ivanov wrote: > The bug report says that going from -0.15 to -0.10 does not allow going back to -0.15. This happens because the result of this sequence of operations cannot be represented exactly, or, in other words, because of rounding errors; or rather the result is less than the set minimal value. > > Can we set the value of the spinner to the set minimal value instead of disallowing the operation. I mean, after going up the displayed value is -0.10; going down by 0.05 gives the result which is less than the minimal value for the spinner, and thus going down is not allowed. What if we set the value of the spinner to its minimal value instead? In this case, we will need to update all types including int. Isn't it will be surprised that the spinner will show the value which is not calculated as "defaultValue + stepValue * stepCount"? -- Best regards, Sergey. From vladislav.volodin at sap.com Thu Feb 13 22:22:03 2020 From: vladislav.volodin at sap.com (Volodin, Vladislav) Date: Thu, 13 Feb 2020 22:22:03 +0000 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> , Message-ID: <75808EB0-5C20-4698-92F1-D14A3619E676@sap.com> Hello Sergey, Alexey and Pankaj, I am reading the current discussion and I was thinking about an idea changing the code in the way that instead of working with float/double numbers we work with integer ticks. For example, the model remembers the min/max/step values and calculates a number of steps required to reach from min to max. All increment/decrement actions are done against the current ?tick? value. If the current ?tick? reaches 0 - we return min; if maxTick ? we return max. And the current value can be always counted as (min + tick * step) if tick is neither zero, nor max tick count. At least if we deal with integer ticks, but all reading operations calculate on the fly, we will be able to control the representativeness of output. As always, I don?t know all the details and possible consequences, so feel free to ignore my email, if I am wrong. Kind regards, Vlad Sent from myPad > On 13. Feb 2020, at 22:34, Sergey Bylokhov wrote: > > ?On 2/12/20 8:21 am, Alexey Ivanov wrote: >> The bug report says that going from -0.15 to -0.10 does not allow going back to -0.15. This happens because the result of this sequence of operations cannot be represented exactly, or, in other words, because of rounding errors; or rather the result is less than the set minimal value. >> Can we set the value of the spinner to the set minimal value instead of disallowing the operation. I mean, after going up the displayed value is -0.10; going down by 0.05 gives the result which is less than the minimal value for the spinner, and thus going down is not allowed. What if we set the value of the spinner to its minimal value instead? > > In this case, we will need to update all types including int. Isn't it will be surprised that the spinner will show the value which is not calculated as > "defaultValue + stepValue * stepCount"? > > > -- > Best regards, Sergey. From David.Polock at innovas.de Fri Feb 14 13:46:45 2020 From: David.Polock at innovas.de (David Polock) Date: Fri, 14 Feb 2020 13:46:45 +0000 Subject: Followup to JDK-8187957 Tab Size does not work correctly in JTextArea Message-ID: <74fc7a7ed4ea4a188d01956676c7afa6@K-Mail-2.innovas.de> Hello, this is my first post on the mailing list - please point me tot he right places, if i'm off topic. I have an issue with tab stops in a JTextArea. The behaviour is very similar to the bug JDK-8187957, which was fixed for JDK10. I'm using JDK11 and see the same (wrong) behaviour in my code. After some tests i could confirm, that the bug was fixed for a JTextArea without line wrapping. But calling JTextArea::setLineWrap(true) leads again to the false behaviour. So in a next step I cloned the git Source repository and examined the patch for the Bug. Besides adding a testcase (TestTabSize.java) the fix is changing some float calculation to int: ================================================ commit 0da4c70d2d542d8ff37ee34e4878829af696b694 Author: Prasanta Sadhukhan Date: Tue Nov 14 10:32:31 2017 +0530 8187957: Tab Size does not work correctly in JTextArea Reviewed-by: ssadetsky, serb diff --git a/src/java.desktop/share/classes/javax/swing/text/PlainView.java b/src/java.desktop/share/classes/javax/swing/text/PlainView.java index 9d1b4fc..6aabc24 100644 --- a/src/java.desktop/share/classes/javax/swing/text/PlainView.java +++ b/src/java.desktop/share/classes/javax/swing/text/PlainView.java @@ -646,7 +646,7 @@ public class PlainView extends View implements TabExpander { if (tabSize == 0) { return x; } - float ntabs = (x - tabBase) / tabSize; + int ntabs = (int) ((x - tabBase) / tabSize); return tabBase + ((ntabs + 1) * tabSize); } ================================================ So in PlainView.java one line was changed. I can see in the source code, that the same (false) line exists in the class WrappedPlainView - which is used as the rendering class, when setLineWrap(true) was called. I think the same fix should be applied to the WrappedPlainView. I could not confirm this fix, because i'm not able to easily build / change the java.desktop module. The issue is reproducible with the following code (adopted from the mentioned bug): ------------- BEGIN CODE ------------------ public class TabTestJFrame extends javax.swing.JFrame { private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextArea jTextArea1; public TabTestJFrame() { initComponents(); jTextArea1.setTabSize( 8 ); } private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); setDefaultCloseOperation( javax.swing.WindowConstants.EXIT_ON_CLOSE ); jTextArea1.setFont( new java.awt.Font( "Monospaced", 0, 10 ) ); jTextArea1.setLineWrap( true ); // use WrappedPlainView as renderer jTextArea1.setText( "#################################################\n# Some Text\t\t\t\t\t#\n# Some Other Much Longer Text\t\t\t#\n#################################################" ); jScrollPane1.setViewportView( jTextArea1 ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout( getContentPane() ); getContentPane().setLayout( layout ); layout.setHorizontalGroup( layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING ).addGroup( layout.createSequentialGroup() .addContainerGap().addComponent( jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 446, Short.MAX_VALUE ).addContainerGap() ) ); layout.setVerticalGroup( layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING ) .addGroup( layout.createSequentialGroup().addContainerGap().addComponent( jScrollPane1 ).addContainerGap() ) ); pack(); } public static void main( String args[] ) { System.out.println( "Java Version: " + System.getProperty( "java.specification.version" ) ); java.awt.EventQueue.invokeLater( () -> { new TabTestJFrame().setVisible( true ); } ); } } ------------- END CODE ------------------ So my question: Can somebody easily confirm the problem? And if the answer is yes, what are the next steps (creating a bug report - but who and how ;-) ?) Best regards, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From vladislav.volodin at sap.com Sat Feb 15 13:08:49 2020 From: vladislav.volodin at sap.com (Volodin, Vladislav) Date: Sat, 15 Feb 2020 13:08:49 +0000 Subject: Followup to JDK-8187957 Tab Size does not work correctly in JTextArea In-Reply-To: <74fc7a7ed4ea4a188d01956676c7afa6@K-Mail-2.innovas.de> References: <74fc7a7ed4ea4a188d01956676c7afa6@K-Mail-2.innovas.de> Message-ID: Hi David, I was able to get the result by running your example on a freshly build JDK. The fix that you suggested should be applied to this line: https://github.com/openjdk/jdk/blob/master/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java#L469 (#469). You can contribute to JDK if you want, but I know that it takes some time to build it from sources, prepare the test and the patch. I think I can create the patch for you, and ask my colleague to create the bug report. But there is a usual difficulty is to cover this issue with a test file. Your example is not bad, no, but how to automate it? ?? I can try to invest some time to it after I come from vacation and find a spare time. I guess you have about 3-4 weeks to practice with the JDK building and tests writing (jtreg). Kind regards, Vlad From: swing-dev On Behalf Of David Polock Sent: Freitag, 14. Februar 2020 14:47 To: swing-dev at openjdk.java.net Subject: Followup to JDK-8187957 Tab Size does not work correctly in JTextArea Hello, this is my first post on the mailing list ? please point me tot he right places, if i?m off topic. I have an issue with tab stops in a JTextArea. The behaviour is very similar to the bug JDK-8187957, which was fixed for JDK10. I?m using JDK11 and see the same (wrong) behaviour in my code. After some tests i could confirm, that the bug was fixed for a JTextArea without line wrapping. But calling JTextArea::setLineWrap(true) leads again to the false behaviour. So in a next step I cloned the git Source repository and examined the patch for the Bug. Besides adding a testcase (TestTabSize.java) the fix is changing some float calculation to int: ================================================ commit 0da4c70d2d542d8ff37ee34e4878829af696b694 Author: Prasanta Sadhukhan > Date: Tue Nov 14 10:32:31 2017 +0530 8187957: Tab Size does not work correctly in JTextArea Reviewed-by: ssadetsky, serb diff --git a/src/java.desktop/share/classes/javax/swing/text/PlainView.java b/src/java.desktop/share/classes/javax/swing/text/PlainView.java index 9d1b4fc..6aabc24 100644 --- a/src/java.desktop/share/classes/javax/swing/text/PlainView.java +++ b/src/java.desktop/share/classes/javax/swing/text/PlainView.java @@ -646,7 +646,7 @@ public class PlainView extends View implements TabExpander { if (tabSize == 0) { return x; } - float ntabs = (x - tabBase) / tabSize; + int ntabs = (int) ((x - tabBase) / tabSize); return tabBase + ((ntabs + 1) * tabSize); } ================================================ So in PlainView.java one line was changed. I can see in the source code, that the same (false) line exists in the class WrappedPlainView ? which is used as the rendering class, when setLineWrap(true) was called. I think the same fix should be applied to the WrappedPlainView. I could not confirm this fix, because i?m not able to easily build / change the java.desktop module. The issue is reproducible with the following code (adopted from the mentioned bug): ------------- BEGIN CODE ------------------ public class TabTestJFrame extends javax.swing.JFrame { private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextArea jTextArea1; public TabTestJFrame() { initComponents(); jTextArea1.setTabSize( 8 ); } private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); setDefaultCloseOperation( javax.swing.WindowConstants.EXIT_ON_CLOSE ); jTextArea1.setFont( new java.awt.Font( "Monospaced", 0, 10 ) ); jTextArea1.setLineWrap( true ); // use WrappedPlainView as renderer jTextArea1.setText( "#################################################\n# Some Text\t\t\t\t\t#\n# Some Other Much Longer Text\t\t\t#\n#################################################" ); jScrollPane1.setViewportView( jTextArea1 ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout( getContentPane() ); getContentPane().setLayout( layout ); layout.setHorizontalGroup( layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING ).addGroup( layout.createSequentialGroup() .addContainerGap().addComponent( jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 446, Short.MAX_VALUE ).addContainerGap() ) ); layout.setVerticalGroup( layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING ) .addGroup( layout.createSequentialGroup().addContainerGap().addComponent( jScrollPane1 ).addContainerGap() ) ); pack(); } public static void main( String args[] ) { System.out.println( "Java Version: " + System.getProperty( "java.specification.version" ) ); java.awt.EventQueue.invokeLater( () -> { new TabTestJFrame().setVisible( true ); } ); } } ------------- END CODE ------------------ So my question: Can somebody easily confirm the problem? And if the answer is yes, what are the next steps (creating a bug report ? but who and how ;-) ?) Best regards, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From pankaj.b.bansal at oracle.com Mon Feb 17 06:48:38 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Sun, 16 Feb 2020 22:48:38 -0800 (PST) Subject: [15] RFR JDK-8153090: TAB key cannot change input focus after the radio button in the Color Selection dialog Message-ID: <260a4147-27fb-4ca1-9f6f-b6e0f89ea27f@default> Hi All, Please review the following fix for jdk15. Bug: https://bugs.openjdk.java.net/browse/JDK-8153090 webrev: http://cr.openjdk.java.net/~pbansal/8153090/webrev00/ Issue: In case of JColorChooser, if one of the color dialogs is activated and the focus is on JRadioButton and "TAB" key is pressed to move the focus to next component, the focus is not moving to next component. The JRadioButton remains in the focus. Due to this, the accessibility is not working properly. Cause: The JColorChooser is using the ContainerFocusTraversalPolicy to manage the focus traversal. This policy is causing issues in the JColorChooser. The problem is due to the way it creates the list of all the components in the container while deciding upon which component should be selected as focus owner on pressing the TAB key. Fix: The fix is to remove the use of ContainerFocusTraversalPolicy. When this policy is not explicitly set on JColorChooser, it will use the SortingFocusTraversalPolicy, which does not have these issues and works fine for JColorChooser. The fix can be verified by running SwingSet2 demo and using the JColorChooser demo. I have tested this on Windows, Mac and Linux. Regards, Pankaj Bansal -------------- next part -------------- An HTML attachment was scrubbed... URL: From prasanta.sadhukhan at oracle.com Mon Feb 17 06:53:26 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Mon, 17 Feb 2020 12:23:26 +0530 Subject: Followup to JDK-8187957 Tab Size does not work correctly in JTextArea In-Reply-To: <74fc7a7ed4ea4a188d01956676c7afa6@K-Mail-2.innovas.de> References: <74fc7a7ed4ea4a188d01956676c7afa6@K-Mail-2.innovas.de> Message-ID: <1dfd6585-11f6-f32a-22cc-1716c4ff8889@oracle.com> Hi David, I can take a look at this and create a JBS issue if you have not already created one. Regards Prasanta On 14-Feb-20 7:16 PM, David Polock wrote: > > Hello, > > this is my first post on the mailing list ? please point me tot he > right places, if i?m off topic. > > I have an issue with tab stops in a JTextArea. The behaviour is very > similar to the bug JDK-8187957, which was fixed for JDK10. I?m using > JDK11 and see the same (wrong) behaviour in my code. > > After some tests i could confirm, that the bug was fixed for a > JTextArea without line wrapping. But calling > JTextArea::setLineWrap(true) leads again to the false behaviour. > > So in a next step I cloned the git Source repository and examined the > patch for the Bug. Besides adding a testcase (TestTabSize.java) the > fix is changing some float calculation to int: > > ================================================ > > commit 0da4c70d2d542d8ff37ee34e4878829af696b694 > > Author: Prasanta Sadhukhan > > Date:?? Tue Nov 14 10:32:31 2017 +0530 > > ??? 8187957: Tab Size does not work correctly in JTextArea > > ??? Reviewed-by: ssadetsky, serb > > diff --git > a/src/java.desktop/share/classes/javax/swing/text/PlainView.java > b/src/java.desktop/share/classes/javax/swing/text/PlainView.java > > index 9d1b4fc..6aabc24 100644 > > --- a/src/java.desktop/share/classes/javax/swing/text/PlainView.java > > +++ b/src/java.desktop/share/classes/javax/swing/text/PlainView.java > > @@ -646,7 +646,7 @@ public class PlainView extends View implements > TabExpander { > > ???????? if (tabSize == 0) { > > ???????????? return x; > > ???????? } > > -??????? float ntabs = (x - tabBase) / tabSize; > > +??????? int ntabs = (int) ((x - tabBase) / tabSize); > > ???????? return tabBase + ((ntabs + 1) * tabSize); > > ???? } > > ================================================ > > So in PlainView.java one line was changed. I can see in the source > code, that the same (false) line exists in the class WrappedPlainView > ? which is used as the rendering class, when setLineWrap(true) was called. > > I think the same fix should be applied to the WrappedPlainView. I > could not confirm this fix, because i?m not able to easily build / > change the java.desktop module. > > The issue is reproducible with the following code (adopted from the > mentioned bug): > > ------------- BEGIN CODE ------------------ > > public class TabTestJFrame extends javax.swing.JFrame { > > ? private javax.swing.JScrollPane jScrollPane1; > > ? private javax.swing.JTextArea jTextArea1; > > ? public TabTestJFrame() { > > initComponents(); > > jTextArea1.setTabSize( 8 ); > > ? } > > ? private void initComponents() { > > jScrollPane1 = new javax.swing.JScrollPane(); > > jTextArea1 = new javax.swing.JTextArea(); > > setDefaultCloseOperation( javax.swing.WindowConstants.EXIT_ON_CLOSE ); > > jTextArea1.setFont( new java.awt.Font( "Monospaced", 0, 10 ) ); > > jTextArea1.setLineWrap( true ); // use WrappedPlainView as renderer > > jTextArea1.setText( > > "#################################################\n# Some > Text\t\t\t\t\t#\n# Some Other Much Longer > Text\t\t\t#\n#################################################" ); > > jScrollPane1.setViewportView( jTextArea1 ); > > javax.swing.GroupLayout layout = new javax.swing.GroupLayout( > getContentPane() ); > > getContentPane().setLayout( layout ); > > layout.setHorizontalGroup( layout.createParallelGroup( > javax.swing.GroupLayout.Alignment.LEADING ).addGroup( > layout.createSequentialGroup() > > .addContainerGap().addComponent( jScrollPane1, > javax.swing.GroupLayout.DEFAULT_SIZE, 446, Short.MAX_VALUE > ).addContainerGap() ) ); > > layout.setVerticalGroup( layout.createParallelGroup( > javax.swing.GroupLayout.Alignment.LEADING ) > > .addGroup( > layout.createSequentialGroup().addContainerGap().addComponent( > jScrollPane1 ).addContainerGap() ) ); > > ??? pack(); > > ? } > > ? public static void main( String args[] ) { > > System.out.println( "Java Version: " + System.getProperty( > "java.specification.version" ) ); > > java.awt.EventQueue.invokeLater( () -> { > > ????? new TabTestJFrame().setVisible( true ); > > ??? } ); > > ? } > > } > > ------------- END CODE ------------------ > > So my question: Can somebody easily confirm the problem? And if the > answer is yes, what are the next steps (creating a bug report ? but > who and how ;-) ?) > > Best regards, > > ? David > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexey.ivanov at oracle.com Mon Feb 17 09:50:31 2020 From: alexey.ivanov at oracle.com (Alexey Ivanov) Date: Mon, 17 Feb 2020 09:50:31 +0000 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> Message-ID: <0df576d4-bad9-5a72-29d2-e64e58e4aef3@oracle.com> On 13/02/2020 21:33, Sergey Bylokhov wrote: > On 2/12/20 8:21 am, Alexey Ivanov wrote: >> The bug report says that going from -0.15 to -0.10 does not allow >> going back to -0.15. This happens because the result of this sequence >> of operations cannot be represented exactly, or, in other words, >> because of rounding errors; or rather the result is less than the set >> minimal value. >> >> Can we set the value of the spinner to the set minimal value instead >> of disallowing the operation. I mean, after going up the displayed >> value is -0.10; going down by 0.05 gives the result which is less >> than the minimal value for the spinner, and thus going down is not >> allowed. What if we set the value of the spinner to its minimal value >> instead? > > In this case, we will need to update all types including int. Isn't it > will be surprised that the spinner will show the value which is not > calculated as > "defaultValue + stepValue * stepCount"? > Wouldn't a comment make the intention clear? Otherwise there will always be cases where Spinner with float/double behaves unexpectedly, i.e. does not allow increasing/decreasing a value where one expects it to. This new approach should also work for int too; although it's redundant as integer arithmetic is precise. -- Regards, Alexey From alexey.ivanov at oracle.com Mon Feb 17 09:59:40 2020 From: alexey.ivanov at oracle.com (Alexey Ivanov) Date: Mon, 17 Feb 2020 09:59:40 +0000 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <75808EB0-5C20-4698-92F1-D14A3619E676@sap.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> <75808EB0-5C20-4698-92F1-D14A3619E676@sap.com> Message-ID: <27f5dd3f-0d31-0690-1ea2-8277e8f969cf@oracle.com> Hi Vlad, The idea looks reasonable. However, it does not allow for manual editing. The cases where max and min values are not multiples of step would be hard to handle with this approach. For example: max = 10.05, min = 0.01, step = 0.1; how many ticks are there? What if the user enters 1.01015; the value should change to 1.11015 or 0.91015. On 13/02/2020 22:22, Volodin, Vladislav wrote: > Hello Sergey, Alexey and Pankaj, > > I am reading the current discussion and I was thinking about an idea changing the code in the way that instead of working with float/double numbers we work with integer ticks. For example, the model remembers the min/max/step values and calculates a number of steps required to reach from min to max. All increment/decrement actions are done against the current ?tick? value. If the current ?tick? reaches 0 - we return min; if maxTick ? we return max. And the current value can be always counted as (min + tick * step) if tick is neither zero, nor max tick count. > > At least if we deal with integer ticks, but all reading operations calculate on the fly, we will be able to control the representativeness of output. > > As always, I don?t know all the details and possible consequences, so feel free to ignore my email, if I am wrong. > > Kind regards, > Vlad > > Sent from myPad > >> On 13. Feb 2020, at 22:34, Sergey Bylokhov wrote: >> >> ?On 2/12/20 8:21 am, Alexey Ivanov wrote: >>> The bug report says that going from -0.15 to -0.10 does not allow going back to -0.15. This happens because the result of this sequence of operations cannot be represented exactly, or, in other words, because of rounding errors; or rather the result is less than the set minimal value. >>> Can we set the value of the spinner to the set minimal value instead of disallowing the operation. I mean, after going up the displayed value is -0.10; going down by 0.05 gives the result which is less than the minimal value for the spinner, and thus going down is not allowed. What if we set the value of the spinner to its minimal value instead? >> In this case, we will need to update all types including int. Isn't it will be surprised that the spinner will show the value which is not calculated as >> "defaultValue + stepValue * stepCount"? >> >> >> -- >> Best regards, Sergey. -- Regards, Alexey From Sergey.Bylokhov at oracle.com Mon Feb 17 10:10:06 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Mon, 17 Feb 2020 02:10:06 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <0df576d4-bad9-5a72-29d2-e64e58e4aef3@oracle.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> <0df576d4-bad9-5a72-29d2-e64e58e4aef3@oracle.com> Message-ID: <6ca12ddc-c28e-8a39-03ca-8720325a8162@oracle.com> On 2/17/20 1:50 am, Alexey Ivanov wrote: > Otherwise there will always be cases where Spinner with float/double behaves unexpectedly, i.e. does not allow increasing/decreasing a value where one expects it to. But what value is expected/unexpected? If the programmer wants to use float arithmetic and allow the user to select some value in the diapason by the JSpinner, is it expected that spinner return values which are exactly duplicate simple steps of float addition or not? > This new approach should also work for int too; although it's redundant as integer arithmetic is precise. As far as I understand your approach, is to select the minimum if the resulted float value after the calculation is a little bit smaller than the minimum. So if the minimum is -0.15 and resulted value is (-0.10d - 0.05d) = (-0.15000000000000002), what value should be shown by the spinner? the same logic for int: the minimum is -15 and resulted value is (-11 - 5) = -16, what value should be shown by the spinner? -- Best regards, Sergey. From alexey.ivanov at oracle.com Mon Feb 17 10:25:22 2020 From: alexey.ivanov at oracle.com (Alexey Ivanov) Date: Mon, 17 Feb 2020 10:25:22 +0000 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <6ca12ddc-c28e-8a39-03ca-8720325a8162@oracle.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> <0df576d4-bad9-5a72-29d2-e64e58e4aef3@oracle.com> <6ca12ddc-c28e-8a39-03ca-8720325a8162@oracle.com> Message-ID: <18dd4fbe-5912-1877-2869-a82a9acf36cd@oracle.com> On 17/02/2020 10:10, Sergey Bylokhov wrote: > On 2/17/20 1:50 am, Alexey Ivanov wrote: >> Otherwise there will always be cases where Spinner with float/double >> behaves unexpectedly, i.e. does not allow increasing/decreasing a >> value where one expects it to. > > But what value is expected/unexpected? If the programmer wants to use > float arithmetic and allow the user to select some value in the > diapason by the JSpinner, is it expected that spinner return values > which are exactly duplicate simple steps of float addition or not? This would be expected, I'd say. I mean the steps of float addition subtractions because this is how it works in maths. But it's not always possible with floating point calculations in computers. > >> This new approach should also work for int too; although it's >> redundant as integer arithmetic is precise. > > As far as I understand your approach, is to select the minimum if the > resulted float value after the calculation is a little bit smaller > than the minimum. > > So if the minimum is -0.15 and resulted value is (-0.10d - 0.05d) = > (-0.15000000000000002), what value should be shown by the spinner? > the same logic for int: > ????? the minimum is -15 and resulted value is (-11 - 5) = -16, what > value should be shown by the spinner? > The set minimum value: -0.15d and -15 correspondingly. -- Regards, Alexey From Sergey.Bylokhov at oracle.com Mon Feb 17 10:35:40 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Mon, 17 Feb 2020 02:35:40 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <18dd4fbe-5912-1877-2869-a82a9acf36cd@oracle.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> <0df576d4-bad9-5a72-29d2-e64e58e4aef3@oracle.com> <6ca12ddc-c28e-8a39-03ca-8720325a8162@oracle.com> <18dd4fbe-5912-1877-2869-a82a9acf36cd@oracle.com> Message-ID: <0136082c-386f-a892-fc32-7a04928ff74a@oracle.com> On 2/17/20 2:25 am, Alexey Ivanov wrote: >> As far as I understand your approach, is to select the minimum if the resulted float value after the calculation is a little bit smaller than the minimum. >> >> So if the minimum is -0.15 and resulted value is (-0.10d - 0.05d) = (-0.15000000000000002), what value should be shown by the spinner? >> the same logic for int: >> ????? the minimum is -15 and resulted value is (-11 - 5) = -16, what value should be shown by the spinner? >> > The set minimum value: -0.15d and -15 correspondingly. That will contradicts the spec of SpinnerNumberModel.getNextValue/getPreviousValue which states that "@returns value - stepSize, or null if the sum is less than minimum." -- Best regards, Sergey. From alexey.ivanov at oracle.com Mon Feb 17 10:56:21 2020 From: alexey.ivanov at oracle.com (Alexey Ivanov) Date: Mon, 17 Feb 2020 10:56:21 +0000 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <0136082c-386f-a892-fc32-7a04928ff74a@oracle.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> <0df576d4-bad9-5a72-29d2-e64e58e4aef3@oracle.com> <6ca12ddc-c28e-8a39-03ca-8720325a8162@oracle.com> <18dd4fbe-5912-1877-2869-a82a9acf36cd@oracle.com> <0136082c-386f-a892-fc32-7a04928ff74a@oracle.com> Message-ID: <24575a4e-f5a7-f27f-3940-69207ddb08f2@oracle.com> On 17/02/2020 10:35, Sergey Bylokhov wrote: > On 2/17/20 2:25 am, Alexey Ivanov wrote: >>> As far as I understand your approach, is to select the minimum if >>> the resulted float value after the calculation is a little bit >>> smaller than the minimum. >>> >>> So if the minimum is -0.15 and resulted value is (-0.10d - 0.05d) = >>> (-0.15000000000000002), what value should be shown by the spinner? >>> the same logic for int: >>> ????? the minimum is -15 and resulted value is (-11 - 5) = -16, what >>> value should be shown by the spinner? >>> >> The set minimum value: -0.15d and -15 correspondingly. > > That will contradicts the spec of > SpinnerNumberModel.getNextValue/getPreviousValue which states that > "@returns value - stepSize, or > null if the sum is less than minimum." Then it's not an option. (Unless we change the spec.) In this case, the only thing we can do is what is already proposed. Right? -- Regards, Alexey From alexey.ivanov at oracle.com Mon Feb 17 14:40:44 2020 From: alexey.ivanov at oracle.com (Alexey Ivanov) Date: Mon, 17 Feb 2020 14:40:44 +0000 Subject: [15] Review Request: 8237746 Fixing compiler warnings in src/demo/share/jfc In-Reply-To: References: Message-ID: Thank you, Marc, for your contribution. And thank you to Sergey for creating the review. *Font2DTest.java* 674???????? if ( selectedText == fp.USER_TEXT ) 675?????????? userTextDialog.setVisible(true); 676???????? else 677?????????? userTextDialog.setVisible(false); I'd put the braces around and indent the statements by 4 spaces. However, it's the style used throughout the file: if there's only one statement, there are no braces and the statement is indented by 2 spaces rather than 4. Probably, to keep the code consistent, it's better to leave it as is. 797???????????? else 798?????????????? fontInfoDialog.setVisible(false); *FontPanel.java* 1248??????????? if (valArray == null) { 1249??????????????? valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); 1250??????????? } 1259??????????? if (valArray == null) { 1260??????????????? valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); 1261??????????? } Can it be replaced with FMValues.values() as you did in Font2DTest.java lines 153, 156? And below 1311??????????????? valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); 1324??????????????? valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); *ButtonDemo.java* 64???? Vector buttons = new Vector<>(); Shall it be JComponent? *ComboBoxDemo.java* 60???? JComboBox hairCB; Why not JComboBox ? All createXXX methods use this type. Then the cast below would be unnecessary: 282???????????? String name = (String) parts.get(hairCB.getSelectedItem()); 114???????? presetCB = (JComboBox) comboBoxPanel.add(createPresetComboBox()); To avoid cast, you can use two statements: presetCB = createPresetComboBox(); comboBoxPanel.add(presetCB); *DirectionPanel.java* 97???????????????? AbstractButton b = e.nextElement(); 98???????????? if( b.getActionCommand().equals(selection) ) { Indentation on line 97 seems incorrect, it should align to line 98, shouldn't it? *SliderDemo.java* 167???????? @SuppressWarnings("unchecked") 168???????????????? Dictionary labelTable = s.getLabelTable(); Would using Dictionary suppress the warning automatically? I mean that @SuppressWarning would become unnecessary. *SplitPaneDemo.java* 168 divSize.setText(Integer.valueOf(splitPane.getDividerSize()).toString()); can be simplified to divSize.setText(Integer.toString(splitPane.getDividerSize())); by using static method Integer.toString() method. Shall the copyright year be updated in all the modified files? On 23/01/2020 08:54, Marc Hoffmann wrote: > Hi Sergey, > > thanks for sponsoring this patch! > > I successfully applied the webrev patch on current JDK head (57807:7bae17e00566). The build runs without warnings on the demo code :) > > But I noticed a minor glitch: I inserted a tab in src/demo/share/jfc/SwingSet2/DirectionPanel.java Line 97 where only spaces are used in the rest of the file. Probably this should be fixed before merge. > > Regards, > -marc > > >> On 23. Jan 2020, at 01:35, Sergey Bylokhov wrote: >> >> Hello. >> Please review the fix for compiler warnings in the demo/jfc in JDK 15. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8237746 >> Fix: http://cr.openjdk.java.net/~serb/8237746/webrev.00 >> >> This fix contributed by the Marc Hoffmann: >> https://mail.openjdk.java.net/pipermail/swing-dev/2019-October/009846.html >> >> Fixed warnings: raw types, deprecated APIs, deprecated Applet APIs. >> >> -- >> Best regards, Sergey. > -- Regards, Alexey From hoffmann at mountainminds.com Mon Feb 17 19:55:33 2020 From: hoffmann at mountainminds.com (Marc Hoffmann) Date: Mon, 17 Feb 2020 20:55:33 +0100 Subject: [15] Review Request: 8237746 Fixing compiler warnings in src/demo/share/jfc In-Reply-To: References: Message-ID: Thanks Alexey for the detailed review! I attached a updated version. The examples have many cleanup opportunities. I wanted to focus on compiler warnings for now and keep the changeset minimal. > *Font2DTest.java* > 674 if ( selectedText == fp.USER_TEXT ) > 675 userTextDialog.setVisible(true); > 676 else > 677 userTextDialog.setVisible(false); > > I'd put the braces around and indent the statements by 4 spaces. > However, it's the style used throughout the file: if there's only one statement, there are no braces and the statement is indented by 2 spaces rather than 4. Probably, to keep the code consistent, it's better to leave it as is. > > 797 else > 798 fontInfoDialog.setVisible(false); Maybe separate issue for formatting? > > *FontPanel.java* > 1248 if (valArray == null) { > 1249 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); > 1250 } > 1259 if (valArray == null) { > 1260 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); > 1261 } > Can it be replaced with FMValues.values() as you did in Font2DTest.java lines 153, 156? > > And below > 1311 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); > 1324 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); Done. > > *ButtonDemo.java* > 64 Vector buttons = new Vector<>(); > Shall it be JComponent? Doesn?t because JPanel.add() returns Component: buttons.add(p2.add(new JButton(getString("ButtonDemo.button1")))); Should I introduce a local variable? > > > *ComboBoxDemo.java* > 60 JComboBox hairCB; > Why not JComboBox ? > All createXXX methods use this type. > Then the cast below would be unnecessary: > 282 String name = (String) parts.get(hairCB.getSelectedItem()); This comes from the lookup in the parts Hashtable. Unfortunately it has String an ImageIcon values. > > > 114 presetCB = (JComboBox) comboBoxPanel.add(createPresetComboBox()); > To avoid cast, you can use two statements: > presetCB = createPresetComboBox(); > comboBoxPanel.add(presetCB); Done for all 4 occurrences. > > > *DirectionPanel.java* > 97 AbstractButton b = e.nextElement(); > 98 if( b.getActionCommand().equals(selection) ) { > Indentation on line 97 seems incorrect, it should align to line 98, shouldn't it? Done (replace tab with spaces). > > > *SliderDemo.java* > 167 @SuppressWarnings("unchecked") > 168 Dictionary labelTable = s.getLabelTable(); > Would using Dictionary suppress the warning automatically? > I mean that @SuppressWarning would become unnecessary. Dictionary does not allow put of specific types in the next line. But fixed tabs in the same line. > > > *SplitPaneDemo.java* > 168 divSize.setText(Integer.valueOf(splitPane.getDividerSize()).toString()); > can be simplified to > divSize.setText(Integer.toString(splitPane.getDividerSize())); > by using static method Integer.toString() method. Done. > > > Shall the copyright year be updated in all the modified files? Please let me know what would be the correct process. Cheers, -marc > On 17. Feb 2020, at 15:40, Alexey Ivanov wrote: > > Thank you, Marc, for your contribution. > And thank you to Sergey for creating the review. > > *Font2DTest.java* > 674 if ( selectedText == fp.USER_TEXT ) > 675 userTextDialog.setVisible(true); > 676 else > 677 userTextDialog.setVisible(false); > > I'd put the braces around and indent the statements by 4 spaces. > However, it's the style used throughout the file: if there's only one statement, there are no braces and the statement is indented by 2 spaces rather than 4. Probably, to keep the code consistent, it's better to leave it as is. > > 797 else > 798 fontInfoDialog.setVisible(false); > > > *FontPanel.java* > 1248 if (valArray == null) { > 1249 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); > 1250 } > 1259 if (valArray == null) { > 1260 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); > 1261 } > Can it be replaced with FMValues.values() as you did in Font2DTest.java lines 153, 156? > > And below > 1311 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); > 1324 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); > > > *ButtonDemo.java* > 64 Vector buttons = new Vector<>(); > Shall it be JComponent? > > > *ComboBoxDemo.java* > 60 JComboBox hairCB; > Why not JComboBox ? > All createXXX methods use this type. > Then the cast below would be unnecessary: > 282 String name = (String) parts.get(hairCB.getSelectedItem()); > > > 114 presetCB = (JComboBox) comboBoxPanel.add(createPresetComboBox()); > To avoid cast, you can use two statements: > presetCB = createPresetComboBox(); > comboBoxPanel.add(presetCB); > > > *DirectionPanel.java* > 97 AbstractButton b = e.nextElement(); > 98 if( b.getActionCommand().equals(selection) ) { > Indentation on line 97 seems incorrect, it should align to line 98, shouldn't it? > > > *SliderDemo.java* > 167 @SuppressWarnings("unchecked") > 168 Dictionary labelTable = s.getLabelTable(); > Would using Dictionary suppress the warning automatically? > I mean that @SuppressWarning would become unnecessary. > > > *SplitPaneDemo.java* > 168 divSize.setText(Integer.valueOf(splitPane.getDividerSize()).toString()); > can be simplified to > divSize.setText(Integer.toString(splitPane.getDividerSize())); > by using static method Integer.toString() method. > > > Shall the copyright year be updated in all the modified files? > > > On 23/01/2020 08:54, Marc Hoffmann wrote: >> Hi Sergey, >> >> thanks for sponsoring this patch! >> >> I successfully applied the webrev patch on current JDK head (57807:7bae17e00566). The build runs without warnings on the demo code :) >> >> But I noticed a minor glitch: I inserted a tab in src/demo/share/jfc/SwingSet2/DirectionPanel.java Line 97 where only spaces are used in the rest of the file. Probably this should be fixed before merge. >> >> Regards, >> -marc >> >> >>> On 23. Jan 2020, at 01:35, Sergey Bylokhov wrote: >>> >>> Hello. >>> Please review the fix for compiler warnings in the demo/jfc in JDK 15. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8237746 >>> Fix: http://cr.openjdk.java.net/~serb/8237746/webrev.00 >>> >>> This fix contributed by the Marc Hoffmann: >>> https://mail.openjdk.java.net/pipermail/swing-dev/2019-October/009846.html >>> >>> Fixed warnings: raw types, deprecated APIs, deprecated Applet APIs. >>> >>> -- >>> Best regards, Sergey. >> > -- > Regards, > Alexey -------------- next part -------------- A non-text attachment was scrubbed... Name: JDK8237746-review.01.patch Type: application/octet-stream Size: 91426 bytes Desc: not available URL: -------------- next part -------------- From pankaj.b.bansal at oracle.com Tue Feb 18 07:13:54 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Mon, 17 Feb 2020 23:13:54 -0800 (PST) Subject: [15] RFR JDK-8238985: [TESTBUG] The arrow image is blue instead of green Message-ID: <60dead5c-1764-479f-aeb1-9b844a463627@default> Hi All, Please review the following test only fix for jdk15. Bug: https://bugs.openjdk.java.net/browse/JDK-8238985 webrev: http://cr.openjdk.java.net/~pbansal/8238985/webrev00/ This test was added as part of fix done for HYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8224475"JDK-8224475. The image used in the test case is of blue arrow, but the instruction say that "Verify that the JTextPane is filled with blue arrow images". It is a typo as earlier the green arrow image was attached in JBS and used while writing the test case. The instructions should have been updated later when blue image was used. Fix is to update instruction that blue arrow image will be shown. Regards, Pankaj Bansal -------------- next part -------------- An HTML attachment was scrubbed... URL: From prasanta.sadhukhan at oracle.com Tue Feb 18 07:18:50 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Tue, 18 Feb 2020 12:48:50 +0530 Subject: [15] RFR JDK-8238985: [TESTBUG] The arrow image is blue instead of green In-Reply-To: <60dead5c-1764-479f-aeb1-9b844a463627@default> References: <60dead5c-1764-479f-aeb1-9b844a463627@default> Message-ID: <5f4efcfe-17e7-c17a-5fd3-fc0583fed197@oracle.com> Looks ok. But I guess, you meant "current" instruction say that "JTextPane is filled with *green* arrow images? not "blue". Regards Prasanta On 18-Feb-20 12:43 PM, Pankaj Bansal wrote: > > Hi All, > > Please review the following test only fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8238985 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8238985/webrev00/ > > This test was added as part of fix done for JDK-8224475 > . The image used in > the test case is of blue arrow, but the instruction say that ?Verify > that the JTextPane is filled with blue arrow images?. It is a typo as > earlier the green arrow image was attached in JBS and used while > writing the test case. The instructions should have been updated later > when blue image was used. > > Fix is to update instruction that blue arrow image will be shown. > > > Regards, > Pankaj Bansal > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pankaj.b.bansal at oracle.com Tue Feb 18 07:20:36 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Mon, 17 Feb 2020 23:20:36 -0800 (PST) Subject: [15] RFR JDK-8238985: [TESTBUG] The arrow image is blue instead of green In-Reply-To: <5f4efcfe-17e7-c17a-5fd3-fc0583fed197@oracle.com> References: <60dead5c-1764-479f-aeb1-9b844a463627@default> <5f4efcfe-17e7-c17a-5fd3-fc0583fed197@oracle.com> Message-ID: <291a72a4-514c-4d39-b8bf-47e2d33abd66@default> Hi Prasanta, Thanks for the review. Yes, I meant that only. Regards, Pankaj From: Prasanta Sadhukhan Sent: Tuesday, February 18, 2020 12:49 PM To: Pankaj Bansal ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8238985: [TESTBUG] The arrow image is blue instead of green Looks ok. But I guess, you meant "current" instruction say that "JTextPane is filled with green arrow images" not "blue". Regards Prasanta On 18-Feb-20 12:43 PM, Pankaj Bansal wrote: Hi All, Please review the following test only fix for jdk15. Bug: https://bugs.openjdk.java.net/browse/JDK-8238985 webrev: http://cr.openjdk.java.net/~pbansal/8238985/webrev00/ This test was added as part of fix done for HYPERLINK "https://bugs.openjdk.java.net/browse/JDK-8224475"JDK-8224475. The image used in the test case is of blue arrow, but the instruction say that "Verify that the JTextPane is filled with blue arrow images". It is a typo as earlier the green arrow image was attached in JBS and used while writing the test case. The instructions should have been updated later when blue image was used. Fix is to update instruction that blue arrow image will be shown. Regards, Pankaj Bansal -------------- next part -------------- An HTML attachment was scrubbed... URL: From prasanta.sadhukhan at oracle.com Tue Feb 18 10:10:18 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Tue, 18 Feb 2020 15:40:18 +0530 Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> Message-ID: <68d3c75f-0a94-60d3-4748-ce8cf6f33908@oracle.com> Looks ok to me. Only thing I have some doubt is "propertyChangeListener" object is "private" in windowsMenuItemUI whereas it was "protected" in BasicMenuItemUI. I guess it should be protected too. Regards Prasanta On 08-Feb-20 4:14 AM, Sergey Bylokhov wrote: > Looks fine. > > On 2/5/20 5:00 am, Pankaj Bansal wrote: >> Hello Sergey, >> >> << ok. >> <> <> and will never be removed. >> >> >> Yes, it should be done. >> Webrev: http://cr.openjdk.java.net/~pbansal/8216329/webrev02/ >> >> Regards, >> Pankaj >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Thursday, January 30, 2020 5:59 AM >> To: Pankaj Bansal ; >> swing-dev at openjdk.java.net >> Subject: Re: [15] RFR JDK-8216329: Cannot resize >> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >> >> On 1/29/20 2:25 am, Pankaj Bansal wrote: >>> One more point, I am able to reproduce the current issue with Synth >>> LookAndFeel in all platforms without fix and it works fine with the >>> fix. >> >> ok. >> >> Do we need to remove the listener added to the menuItem? >> I guess it will be added every time we change L&F to the windows and >> will never be removed. >> >> >>> >>> Regards, >>> Pankaj >>> >>> -----Original Message----- >>> From: Pankaj Bansal >>> Sent: Wednesday, January 29, 2020 3:19 PM >>> To: Sergey Bylokhov; swing-dev at openjdk.java.net >>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>> >>> Hello Sergey, >>> >>> << Can you please double check that it is not possible to reproduce >>> JDK-8152981 even if the test is modified in some way? >>> <>> I changed the test in JDK-8152981 to run on all installed >>> LookAndFeels on windows, linux and Mac after removing the windows >>> only condition. The tests passes on all platforms with all >>> LookAndFeels with the current fix. >>> I can check in this change in JDK-8152981? test along with the >>> current fix if needed, though I feel it is not required as the issue >>> was originally only in WindowsLookAndFeel. >>> >>> Regards, >>> Pankaj Bansal >>> >>> -----Original Message----- >>> From: Sergey Bylokhov >>> Sent: Wednesday, January 29, 2020 1:17 PM >>> To: Pankaj Bansal; swing-dev at openjdk.java.net >>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>> >>> On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >>>> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>>>> << It is not a big issue, but for such a fix we will need a proper >>>>> specification and CSR, it is like adding a new method to the >>>>> public class. It is preferable to try to fix it in some other way >>>>> first. >>>>> I did not realize earlier that this can be done by making changes >>>>> in WindowsMenuItemUI without calling the updateCheckIcon by moving >>>>> the code in updateCheckIcon method in WindowsMenuItemUI class. I >>>>> have made the changes for the same and all works fine. Also, I >>>>> have removed the updateCheckIcon method from BasicMenuItemUI class >>>>> as it is not needed. >>>> >>>> Can you please double check that it is not possible to reproduce >>>> JDK-8152981 even if the test is modified in some way? >>> >>> For example if some other "basic" L&F will be used(Motif, Aqua)? >>> >>> >> >> > > From pankaj.b.bansal at oracle.com Tue Feb 18 10:28:11 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Tue, 18 Feb 2020 02:28:11 -0800 (PST) Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: <68d3c75f-0a94-60d3-4748-ce8cf6f33908@oracle.com> References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> <68d3c75f-0a94-60d3-4748-ce8cf6f33908@oracle.com> Message-ID: <780e8643-301a-499a-939b-01917f9558cf@default> Hello Prasanta, Thanks for the review. I don?t think this field needs to be accessed outside the class windowsMenuItemUI. So we should keep it private only. Please let me know if you think otherwise, else I will be pushing this as it is. Regards, Pankaj -----Original Message----- From: Prasanta Sadhukhan Sent: Tuesday, February 18, 2020 3:40 PM To: Pankaj Bansal ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition Looks ok to me. Only thing I have some doubt is "propertyChangeListener" object is "private" in windowsMenuItemUI whereas it was "protected" in BasicMenuItemUI. I guess it should be protected too. Regards Prasanta On 08-Feb-20 4:14 AM, Sergey Bylokhov wrote: > Looks fine. > > On 2/5/20 5:00 am, Pankaj Bansal wrote: >> Hello Sergey, >> >> << ok. >> <> <> and will never be removed. >> >> >> Yes, it should be done. >> Webrev: http://cr.openjdk.java.net/~pbansal/8216329/webrev02/ >> >> Regards, >> Pankaj >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Thursday, January 30, 2020 5:59 AM >> To: Pankaj Bansal ; >> swing-dev at openjdk.java.net >> Subject: Re: [15] RFR JDK-8216329: Cannot resize >> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >> >> On 1/29/20 2:25 am, Pankaj Bansal wrote: >>> One more point, I am able to reproduce the current issue with Synth >>> LookAndFeel in all platforms without fix and it works fine with the >>> fix. >> >> ok. >> >> Do we need to remove the listener added to the menuItem? >> I guess it will be added every time we change L&F to the windows and >> will never be removed. >> >> >>> >>> Regards, >>> Pankaj >>> >>> -----Original Message----- >>> From: Pankaj Bansal >>> Sent: Wednesday, January 29, 2020 3:19 PM >>> To: Sergey Bylokhov; swing-dev at openjdk.java.net >>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>> >>> Hello Sergey, >>> >>> << Can you please double check that it is not possible to reproduce >>> JDK-8152981 even if the test is modified in some way? >>> <>> I changed the test in JDK-8152981 to run on all installed >>> LookAndFeels on windows, linux and Mac after removing the windows >>> only condition. The tests passes on all platforms with all >>> LookAndFeels with the current fix. >>> I can check in this change in JDK-8152981? test along with the >>> current fix if needed, though I feel it is not required as the issue >>> was originally only in WindowsLookAndFeel. >>> >>> Regards, >>> Pankaj Bansal >>> >>> -----Original Message----- >>> From: Sergey Bylokhov >>> Sent: Wednesday, January 29, 2020 1:17 PM >>> To: Pankaj Bansal; swing-dev at openjdk.java.net >>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>> >>> On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >>>> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>>>> << It is not a big issue, but for such a fix we will need a proper >>>>> specification and CSR, it is like adding a new method to the >>>>> public class. It is preferable to try to fix it in some other way >>>>> first. >>>>> I did not realize earlier that this can be done by making changes >>>>> in WindowsMenuItemUI without calling the updateCheckIcon by moving >>>>> the code in updateCheckIcon method in WindowsMenuItemUI class. I >>>>> have made the changes for the same and all works fine. Also, I >>>>> have removed the updateCheckIcon method from BasicMenuItemUI class >>>>> as it is not needed. >>>> >>>> Can you please double check that it is not possible to reproduce >>>> JDK-8152981 even if the test is modified in some way? >>> >>> For example if some other "basic" L&F will be used(Motif, Aqua)? >>> >>> >> >> > > From prasanta.sadhukhan at oracle.com Tue Feb 18 10:32:50 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Tue, 18 Feb 2020 16:02:50 +0530 Subject: RFR : JDK-8239334:Tab Size does not work correctly in JTextArea with setLineWrap on Message-ID: Hi All, Bug: https://bugs.openjdk.java.net/browse/JDK-8239334 webrev: http://cr.openjdk.java.net/~psadhukhan/8239334/webrev.0/ Please review a fix for an issue where it is seen string with "tab" in them are not aligned properly with linewrap on. This is in continuation to a fix done in JDK-8187957 where the fix was done in PlainView. This is because while calculating tab stop postion, it is calculating number of tabs in float value (an aftereffect of JDK-8156217 ) so next tab stop location is coming out wrong. Fix is to use "number of tabs" as an integer value in order to calculate the tab position correctly. The same fix should be done for WrappedPlainView for line wrap path. Regards Prasanta -------------- next part -------------- An HTML attachment was scrubbed... URL: From prasanta.sadhukhan at oracle.com Tue Feb 18 10:33:34 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Tue, 18 Feb 2020 16:03:34 +0530 Subject: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition In-Reply-To: <780e8643-301a-499a-939b-01917f9558cf@default> References: <90cea53e-117d-4252-86d7-7d7b2163d6f3@default> <37805088-6e0e-5b39-44fd-3fdc6d5f89b0@oracle.com> <03c19198-abc0-4b5d-8430-147d6c2b0e11@default> <479e09b7-ea1b-4156-b127-4a57414cb4f0@default> <6f2da1e0-ce0c-169b-2c9a-15776b656a69@oracle.com> <0a4ed98d-6af8-86cd-f9d5-6b2b2d5930c5@oracle.com> <68d3c75f-0a94-60d3-4748-ce8cf6f33908@oracle.com> <780e8643-301a-499a-939b-01917f9558cf@default> Message-ID: <10f383f0-abc4-66b3-786d-4ae732d56034@oracle.com> OK. On 18-Feb-20 3:58 PM, Pankaj Bansal wrote: > Hello Prasanta, > > Thanks for the review. > I don?t think this field needs to be accessed outside the class windowsMenuItemUI. So we should keep it private only. Please let me know if you think otherwise, else I will be pushing this as it is. > > Regards, > Pankaj > > -----Original Message----- > From: Prasanta Sadhukhan > Sent: Tuesday, February 18, 2020 3:40 PM > To: Pankaj Bansal ; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8216329: Cannot resize CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition > > Looks ok to me. Only thing I have some doubt is "propertyChangeListener" > object is "private" in windowsMenuItemUI whereas it was "protected" in BasicMenuItemUI. I guess it should be protected too. > > Regards > > Prasanta > > On 08-Feb-20 4:14 AM, Sergey Bylokhov wrote: >> Looks fine. >> >> On 2/5/20 5:00 am, Pankaj Bansal wrote: >>> Hello Sergey, >>> >>> << ok. >>> <>> <>> and will never be removed. >>> >>> >>> Yes, it should be done. >>> Webrev: http://cr.openjdk.java.net/~pbansal/8216329/webrev02/ >>> >>> Regards, >>> Pankaj >>> >>> -----Original Message----- >>> From: Sergey Bylokhov >>> Sent: Thursday, January 30, 2020 5:59 AM >>> To: Pankaj Bansal ; >>> swing-dev at openjdk.java.net >>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>> >>> On 1/29/20 2:25 am, Pankaj Bansal wrote: >>>> One more point, I am able to reproduce the current issue with Synth >>>> LookAndFeel in all platforms without fix and it works fine with the >>>> fix. >>> ok. >>> >>> Do we need to remove the listener added to the menuItem? >>> I guess it will be added every time we change L&F to the windows and >>> will never be removed. >>> >>> >>>> Regards, >>>> Pankaj >>>> >>>> -----Original Message----- >>>> From: Pankaj Bansal >>>> Sent: Wednesday, January 29, 2020 3:19 PM >>>> To: Sergey Bylokhov; swing-dev at openjdk.java.net >>>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>>> >>>> Hello Sergey, >>>> >>>> << Can you please double check that it is not possible to reproduce >>>> JDK-8152981 even if the test is modified in some way? >>>> <>>> I changed the test in JDK-8152981 to run on all installed >>>> LookAndFeels on windows, linux and Mac after removing the windows >>>> only condition. The tests passes on all platforms with all >>>> LookAndFeels with the current fix. >>>> I can check in this change in JDK-8152981? test along with the >>>> current fix if needed, though I feel it is not required as the issue >>>> was originally only in WindowsLookAndFeel. >>>> >>>> Regards, >>>> Pankaj Bansal >>>> >>>> -----Original Message----- >>>> From: Sergey Bylokhov >>>> Sent: Wednesday, January 29, 2020 1:17 PM >>>> To: Pankaj Bansal; swing-dev at openjdk.java.net >>>> Subject: Re: [15] RFR JDK-8216329: Cannot resize >>>> CheckBoxItemMenu in Synth L&F with setHorizontalTextPosition >>>> >>>> On 1/28/20 4:33 pm, Sergey Bylokhov wrote: >>>>> On 1/27/20 7:15 am, Pankaj Bansal wrote: >>>>>> << It is not a big issue, but for such a fix we will need a proper >>>>>> specification and CSR, it is like adding a new method to the >>>>>> public class. It is preferable to try to fix it in some other way >>>>>> first. >>>>>> I did not realize earlier that this can be done by making changes >>>>>> in WindowsMenuItemUI without calling the updateCheckIcon by moving >>>>>> the code in updateCheckIcon method in WindowsMenuItemUI class. I >>>>>> have made the changes for the same and all works fine. Also, I >>>>>> have removed the updateCheckIcon method from BasicMenuItemUI class >>>>>> as it is not needed. >>>>> Can you please double check that it is not possible to reproduce >>>>> JDK-8152981 even if the test is modified in some way? >>>> For example if some other "basic" L&F will be used(Motif, Aqua)? >>>> >>>> >>> >> From Sergey.Bylokhov at oracle.com Tue Feb 18 22:19:13 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 18 Feb 2020 14:19:13 -0800 Subject: [15] RFR JDK-8220811: SpinnerNumberModel floating point rounding issue In-Reply-To: <27f5dd3f-0d31-0690-1ea2-8277e8f969cf@oracle.com> References: <92ca9fe1-6bbc-47c6-bc62-3f78ae7c7194@oracle.com> <4db1f723-0f5a-4d66-8db6-529897885d79@default> <4cfd1bd2-0a45-4b23-97a3-e1a773db1785@default> <75808EB0-5C20-4698-92F1-D14A3619E676@sap.com> <27f5dd3f-0d31-0690-1ea2-8277e8f969cf@oracle.com> Message-ID: I think it should work, the step will counts from the default value. So currently: 1. if the user set default value to X1 and then he iterates forward 100 times then he will get some X2. During this calculation, he could get "100" rounding issues. 2. If later the user decides iterates backward then most probably he will not get X1, and the amount of possible "rounding issues" will be 200. If the user will repeat steps 1. and 2. then each time the values will "float". If we will use counter then in the worst case we will get only two roundings per step: X1+step*100 = X2(if we will use fma we will get only one for every step). It will not solve all issues but at least will make the iteration "stable". On 2/17/20 1:59 am, Alexey Ivanov wrote: > Hi Vlad, > > The idea looks reasonable. However, it does not allow for manual editing. The cases where max and min values are not multiples of step would be hard to handle with this approach. For example: max = 10.05, min = 0.01, step = 0.1; how many ticks are there? What if the user enters 1.01015; the value should change to 1.11015 or 0.91015. > > On 13/02/2020 22:22, Volodin, Vladislav wrote: >> Hello Sergey, Alexey and Pankaj, >> >> I am reading the current discussion and I was thinking about an idea changing the code in the way that instead of working with float/double numbers we work with integer ticks. For example, the model remembers the min/max/step values and calculates a number of steps required to reach from min to max. All increment/decrement actions are done against the current ?tick? value. If the current ?tick? reaches 0 - we return min; if maxTick ? we return max. And the current value can be always counted as (min + tick * step) if tick is neither zero, nor max tick count. >> >> At least if we deal with integer ticks, but all reading operations calculate on the fly, we will be able to control the representativeness of output. >> >> As always, I don?t know all the details and possible consequences, so feel free to ignore my email, if I am wrong. >> >> Kind regards, >> Vlad >> >> Sent from myPad >> >>> On 13. Feb 2020, at 22:34, Sergey Bylokhov wrote: >>> >>> ?On 2/12/20 8:21 am, Alexey Ivanov wrote: >>>> The bug report says that going from -0.15 to -0.10 does not allow going back to -0.15. This happens because the result of this sequence of operations cannot be represented exactly, or, in other words, because of rounding errors; or rather the result is less than the set minimal value. >>>> Can we set the value of the spinner to the set minimal value instead of disallowing the operation. I mean, after going up the displayed value is -0.10; going down by 0.05 gives the result which is less than the minimal value for the spinner, and thus going down is not allowed. What if we set the value of the spinner to its minimal value instead? >>> In this case, we will need to update all types including int. Isn't it will be surprised that the spinner will show the value which is not calculated as >>> "defaultValue + stepValue * stepCount"? >>> >>> >>> -- >>> Best regards, Sergey. -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Tue Feb 18 22:20:43 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 18 Feb 2020 14:20:43 -0800 Subject: [15] RFR JDK-8238985: [TESTBUG] The arrow image is blue instead of green In-Reply-To: <291a72a4-514c-4d39-b8bf-47e2d33abd66@default> References: <60dead5c-1764-479f-aeb1-9b844a463627@default> <5f4efcfe-17e7-c17a-5fd3-fc0583fed197@oracle.com> <291a72a4-514c-4d39-b8bf-47e2d33abd66@default> Message-ID: <323a7725-6810-0a8f-32f6-920786eab164@oracle.com> +1 On 2/17/20 11:20 pm, Pankaj Bansal wrote: > Hi Prasanta, > > Thanks for the review. Yes, I meant that only. > > Regards, > > Pankaj > > *From:*Prasanta Sadhukhan > *Sent:* Tuesday, February 18, 2020 12:49 PM > *To:* Pankaj Bansal ; swing-dev at openjdk.java.net > *Subject:* Re: [15] RFR JDK-8238985: [TESTBUG] The arrow image is blue instead of green > > Looks ok. > > But I guess, you meant "current" instruction say that "JTextPane is filled with *green* arrow images? not "blue". > > Regards > > Prasanta > > On 18-Feb-20 12:43 PM, Pankaj Bansal wrote: > > Hi All, > > Please review the following test only fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8238985 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8238985/webrev00/ > > This test was added as part of fix done for JDK-8224475 . The image used in the test case is of blue arrow, but the instruction say that ?Verify that the JTextPane is filled with blue arrow images?. It is a typo as earlier the green arrow image was attached in JBS and used while writing the test case. The instructions should have been updated later when blue image was used. > > Fix is to update instruction that blue arrow image will be shown. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Tue Feb 18 23:39:57 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 18 Feb 2020 15:39:57 -0800 Subject: [15] RFR JDK-8153090: TAB key cannot change input focus after the radio button in the Color Selection dialog In-Reply-To: <260a4147-27fb-4ca1-9f6f-b6e0f89ea27f@default> References: <260a4147-27fb-4ca1-9f6f-b6e0f89ea27f@default> Message-ID: Looks fine. On 2/16/20 10:48 pm, Pankaj Bansal wrote: > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8153090 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8153090/webrev00/ > > Issue: > > In case of JColorChooser, if one of the color dialogs is activated and the focus is on JRadioButton and ?TAB? key is pressed to move the focus to next component, the focus is not moving to next component. The JRadioButton remains in the focus. Due to this, the accessibility is not working properly. > > Cause: > > The JColorChooser is using the ContainerFocusTraversalPolicy to manage the focus traversal. This policy is causing issues in the JColorChooser. The problem is due to the way it creates the list of all the components in the container while deciding upon which component should be selected as focus owner on pressing the TAB key. > > Fix: > > The fix is to remove the use of ContainerFocusTraversalPolicy. When this policy is not explicitly set on JColorChooser, it will use the SortingFocusTraversalPolicy, which does not have these issues and works fine for JColorChooser. > > The fix can be verified by running SwingSet2 demo and using the JColorChooser demo. I have tested this on Windows, Mac and Linux. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Wed Feb 19 09:09:30 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Wed, 19 Feb 2020 01:09:30 -0800 Subject: RFR : JDK-8239334:Tab Size does not work correctly in JTextArea with setLineWrap on In-Reply-To: References: Message-ID: Looks fine. On 2/18/20 2:32 am, Prasanta Sadhukhan wrote: > Hi All, > > Bug: https://bugs.openjdk.java.net/browse/JDK-8239334 > webrev: http://cr.openjdk.java.net/~psadhukhan/8239334/webrev.0/ > > Please review a fix for an issue where it is seen string with "tab" in them are not aligned properly with linewrap on. > > This is in continuation to a fix done in JDK-8187957 where the fix was done in PlainView. > This is because while calculating tab stop postion, it is calculating number of tabs in float value (an aftereffect of JDK-8156217 ) > so next tab stop location is coming out wrong. > Fix is to use "number of tabs" as an integer value in order to calculate the tab position correctly. > > The same fix should be done for WrappedPlainView for line wrap path. > > Regards > Prasanta > -- Best regards, Sergey. From pankaj.b.bansal at oracle.com Thu Feb 20 06:17:52 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Wed, 19 Feb 2020 22:17:52 -0800 (PST) Subject: RFR : JDK-8239334:Tab Size does not work correctly in JTextArea with setLineWrap on In-Reply-To: References: Message-ID: Hello Prasanta, The fix looks good. I have couple of minor comments about the test. There is an indentation issue at line 59 You have imported classes like JScrollPane, JTextArea and while using them, you have used full path like javax.swing.JScrollPane, javax.swing.JTextArea etc. Regards, Pankaj -----Original Message----- From: Sergey Bylokhov Sent: Wednesday, February 19, 2020 2:40 PM To: Prasanta Sadhukhan ; swing-dev at openjdk.java.net Subject: Re: RFR : JDK-8239334:Tab Size does not work correctly in JTextArea with setLineWrap on Looks fine. On 2/18/20 2:32 am, Prasanta Sadhukhan wrote: > Hi All, > > Bug: https://bugs.openjdk.java.net/browse/JDK-8239334 > webrev: http://cr.openjdk.java.net/~psadhukhan/8239334/webrev.0/ > > Please review a fix for an issue where it is seen string with "tab" in them are not aligned properly with linewrap on. > > This is in continuation to a fix done in JDK-8187957 where the fix was done in PlainView. > This is because while calculating tab stop postion, it is calculating number of tabs in float value (an aftereffect of JDK-8156217 ) > so next tab stop location is coming out wrong. > Fix is to use "number of tabs" as an integer value in order to calculate the tab position correctly. > > The same fix should be done for WrappedPlainView for line wrap path. > > Regards > Prasanta > -- Best regards, Sergey. From prasanta.sadhukhan at oracle.com Thu Feb 20 06:37:44 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Thu, 20 Feb 2020 12:07:44 +0530 Subject: RFR : JDK-8239334:Tab Size does not work correctly in JTextArea with setLineWrap on In-Reply-To: References: Message-ID: <294d967b-1da6-0268-0227-f82434c20073@oracle.com> Thanks Pankaj for the review. I will fix it during the push. Regards Prasanta On 20-Feb-20 11:47 AM, Pankaj Bansal wrote: > Hello Prasanta, > > The fix looks good. I have couple of minor comments about the test. > There is an indentation issue at line 59 > You have imported classes like JScrollPane, JTextArea and while using them, you have used full path like javax.swing.JScrollPane, javax.swing.JTextArea etc. > > Regards, > Pankaj > > -----Original Message----- > From: Sergey Bylokhov > Sent: Wednesday, February 19, 2020 2:40 PM > To: Prasanta Sadhukhan ; swing-dev at openjdk.java.net > Subject: Re: RFR : JDK-8239334:Tab Size does not work correctly in JTextArea with setLineWrap on > > Looks fine. > > On 2/18/20 2:32 am, Prasanta Sadhukhan wrote: >> Hi All, >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8239334 >> webrev: http://cr.openjdk.java.net/~psadhukhan/8239334/webrev.0/ >> >> Please review a fix for an issue where it is seen string with "tab" in them are not aligned properly with linewrap on. >> >> This is in continuation to a fix done in JDK-8187957 where the fix was done in PlainView. >> This is because while calculating tab stop postion, it is calculating number of tabs in float value (an aftereffect of JDK-8156217 ) >> so next tab stop location is coming out wrong. >> Fix is to use "number of tabs" as an integer value in order to calculate the tab position correctly. >> >> The same fix should be done for WrappedPlainView for line wrap path. >> >> Regards >> Prasanta >> > From prasanta.sadhukhan at oracle.com Fri Feb 21 09:24:30 2020 From: prasanta.sadhukhan at oracle.com (Prasanta Sadhukhan) Date: Fri, 21 Feb 2020 14:54:30 +0530 Subject: [15] RFR JDK-8153090: TAB key cannot change input focus after the radio button in the Color Selection dialog In-Reply-To: <260a4147-27fb-4ca1-9f6f-b6e0f89ea27f@default> References: <260a4147-27fb-4ca1-9f6f-b6e0f89ea27f@default> Message-ID: Looks good to me. Please add noreg-demo label to JBS. Regards Prasanta On 17-Feb-20 12:18 PM, Pankaj Bansal wrote: > > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8153090 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8153090/webrev00/ > > Issue: > > In case of JColorChooser, if one of the color dialogs is activated and > the focus is on JRadioButton and ?TAB? key is pressed to move the > focus to next component, the focus is not moving to next component. > The JRadioButton remains in the focus. Due to this, the accessibility > is not working properly. > > Cause: > > The JColorChooser is using the ContainerFocusTraversalPolicy to manage > the focus traversal. This policy is causing issues in the > JColorChooser. The problem is due to the way it creates the list of > all the components in the container while deciding upon which > component should be selected as focus owner on pressing the TAB key. > > Fix: > > The fix is to remove the use of ContainerFocusTraversalPolicy. When > this policy is not explicitly set on JColorChooser, it will use the > SortingFocusTraversalPolicy, which does not have these issues and > works fine for JColorChooser. > > The fix can be verified by running SwingSet2 demo and using the > JColorChooser demo. I have tested this on Windows, Mac and Linux. > > > Regards, > Pankaj Bansal > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Sergey.Bylokhov at oracle.com Sat Feb 22 09:50:20 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Sat, 22 Feb 2020 01:50:20 -0800 Subject: [15] Review Request: 8237746 Fixing compiler warnings in src/demo/share/jfc In-Reply-To: References: Message-ID: <9eae8ba3-dfe8-1e9e-1997-51e213bb45f5@oracle.com> Thank you, an updated version is upload: http://cr.openjdk.java.net/~serb/8237746/webrev.01 On 2/17/20 11:55 am, Marc Hoffmann wrote: > Thanks Alexey for the detailed review! I attached a updated version. > > The examples have many cleanup opportunities. I wanted to focus on compiler warnings for now and keep the changeset minimal. > > >> *Font2DTest.java* >> 674 if ( selectedText == fp.USER_TEXT ) >> 675 userTextDialog.setVisible(true); >> 676 else >> 677 userTextDialog.setVisible(false); >> >> I'd put the braces around and indent the statements by 4 spaces. >> However, it's the style used throughout the file: if there's only one statement, there are no braces and the statement is indented by 2 spaces rather than 4. Probably, to keep the code consistent, it's better to leave it as is. >> >> 797 else >> 798 fontInfoDialog.setVisible(false); > > Maybe separate issue for formatting? > >> >> *FontPanel.java* >> 1248 if (valArray == null) { >> 1249 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); >> 1250 } >> 1259 if (valArray == null) { >> 1260 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); >> 1261 } >> Can it be replaced with FMValues.values() as you did in Font2DTest.java lines 153, 156? >> >> And below >> 1311 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); >> 1324 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); > > Done. > >> >> *ButtonDemo.java* >> 64 Vector buttons = new Vector<>(); >> Shall it be JComponent? > > Doesn?t because JPanel.add() returns Component: > > buttons.add(p2.add(new JButton(getString("ButtonDemo.button1")))); > > Should I introduce a local variable? > >> >> >> *ComboBoxDemo.java* >> 60 JComboBox hairCB; >> Why not JComboBox ? >> All createXXX methods use this type. >> Then the cast below would be unnecessary: >> 282 String name = (String) parts.get(hairCB.getSelectedItem()); > > This comes from the lookup in the parts Hashtable. Unfortunately it has String an ImageIcon values. > >> >> >> 114 presetCB = (JComboBox) comboBoxPanel.add(createPresetComboBox()); >> To avoid cast, you can use two statements: >> presetCB = createPresetComboBox(); >> comboBoxPanel.add(presetCB); > > Done for all 4 occurrences. > >> >> >> *DirectionPanel.java* >> 97 AbstractButton b = e.nextElement(); >> 98 if( b.getActionCommand().equals(selection) ) { >> Indentation on line 97 seems incorrect, it should align to line 98, shouldn't it? > > Done (replace tab with spaces). > >> >> >> *SliderDemo.java* >> 167 @SuppressWarnings("unchecked") >> 168 Dictionary labelTable = s.getLabelTable(); >> Would using Dictionary suppress the warning automatically? >> I mean that @SuppressWarning would become unnecessary. > > Dictionary does not allow put of specific types in the next line. But fixed tabs in the same line. > >> >> >> *SplitPaneDemo.java* >> 168 divSize.setText(Integer.valueOf(splitPane.getDividerSize()).toString()); >> can be simplified to >> divSize.setText(Integer.toString(splitPane.getDividerSize())); >> by using static method Integer.toString() method. > > Done. > >> >> >> Shall the copyright year be updated in all the modified files? > > Please let me know what would be the correct process. > > Cheers, > -marc > > > > >> On 17. Feb 2020, at 15:40, Alexey Ivanov wrote: >> >> Thank you, Marc, for your contribution. >> And thank you to Sergey for creating the review. >> >> *Font2DTest.java* >> 674 if ( selectedText == fp.USER_TEXT ) >> 675 userTextDialog.setVisible(true); >> 676 else >> 677 userTextDialog.setVisible(false); >> >> I'd put the braces around and indent the statements by 4 spaces. >> However, it's the style used throughout the file: if there's only one statement, there are no braces and the statement is indented by 2 spaces rather than 4. Probably, to keep the code consistent, it's better to leave it as is. >> >> 797 else >> 798 fontInfoDialog.setVisible(false); >> >> >> *FontPanel.java* >> 1248 if (valArray == null) { >> 1249 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); >> 1250 } >> 1259 if (valArray == null) { >> 1260 valArray = EnumSet.allOf(FMValues.class).toArray(new FMValues[0]); >> 1261 } >> Can it be replaced with FMValues.values() as you did in Font2DTest.java lines 153, 156? >> >> And below >> 1311 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); >> 1324 valArray = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]); >> >> >> *ButtonDemo.java* >> 64 Vector buttons = new Vector<>(); >> Shall it be JComponent? >> >> >> *ComboBoxDemo.java* >> 60 JComboBox hairCB; >> Why not JComboBox ? >> All createXXX methods use this type. >> Then the cast below would be unnecessary: >> 282 String name = (String) parts.get(hairCB.getSelectedItem()); >> >> >> 114 presetCB = (JComboBox) comboBoxPanel.add(createPresetComboBox()); >> To avoid cast, you can use two statements: >> presetCB = createPresetComboBox(); >> comboBoxPanel.add(presetCB); >> >> >> *DirectionPanel.java* >> 97 AbstractButton b = e.nextElement(); >> 98 if( b.getActionCommand().equals(selection) ) { >> Indentation on line 97 seems incorrect, it should align to line 98, shouldn't it? >> >> >> *SliderDemo.java* >> 167 @SuppressWarnings("unchecked") >> 168 Dictionary labelTable = s.getLabelTable(); >> Would using Dictionary suppress the warning automatically? >> I mean that @SuppressWarning would become unnecessary. >> >> >> *SplitPaneDemo.java* >> 168 divSize.setText(Integer.valueOf(splitPane.getDividerSize()).toString()); >> can be simplified to >> divSize.setText(Integer.toString(splitPane.getDividerSize())); >> by using static method Integer.toString() method. >> >> >> Shall the copyright year be updated in all the modified files? >> >> >> On 23/01/2020 08:54, Marc Hoffmann wrote: >>> Hi Sergey, >>> >>> thanks for sponsoring this patch! >>> >>> I successfully applied the webrev patch on current JDK head (57807:7bae17e00566). The build runs without warnings on the demo code :) >>> >>> But I noticed a minor glitch: I inserted a tab in src/demo/share/jfc/SwingSet2/DirectionPanel.java Line 97 where only spaces are used in the rest of the file. Probably this should be fixed before merge. >>> >>> Regards, >>> -marc >>> >>> >>>> On 23. Jan 2020, at 01:35, Sergey Bylokhov wrote: >>>> >>>> Hello. >>>> Please review the fix for compiler warnings in the demo/jfc in JDK 15. >>>> >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8237746 >>>> Fix: http://cr.openjdk.java.net/~serb/8237746/webrev.00 >>>> >>>> This fix contributed by the Marc Hoffmann: >>>> https://mail.openjdk.java.net/pipermail/swing-dev/2019-October/009846.html >>>> >>>> Fixed warnings: raw types, deprecated APIs, deprecated Applet APIs. >>>> >>>> -- >>>> Best regards, Sergey. >>> >> -- >> Regards, >> Alexey > > > > -- Best regards, Sergey. From vladislav.volodin at sap.com Sat Feb 22 10:38:32 2020 From: vladislav.volodin at sap.com (Volodin, Vladislav) Date: Sat, 22 Feb 2020 10:38:32 +0000 Subject: Remove System.out.println from ImageIcon.loadImage In-Reply-To: References: <2310F0FD-DAA6-4E24-85AD-776D6F979CC0@sap.com> <549622d0-fe72-f267-c105-53b1399471dc@oracle.com>, , , <6CA1C9A2-3FE1-445D-93B7-57DC8818F0FB@sap.com>, , , , , , Message-ID: Hello Jason and everyone else, here is my webrev that my colleague published http://cr.openjdk.java.net/~clanger/webrevs/6421373.0/ Can you please review it and let me know if I should change anything? Currently I am OOO, but I will do the changes in March. Kind regards, Vlad Get Outlook for iOS ________________________________ From: Jason Mehrens Sent: Tuesday, February 11, 2020 9:13:41 PM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Vlad, Yea that looks good. Jason ________________________________________ From: Volodin, Vladislav Sent: Wednesday, February 5, 2020 9:59 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, thank you for your advice. I have changed my code, now it simulates the behavior of the interrupted thread. Can you please check my patch? I don't have the "bug" ticket, so in my test case "@bug JDK-123456" should be adjusted. I will appreciate if you and somebody else can review my patch and submit it to JDK. Thanks, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 17:55 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage 1. Agreed. 2. I was just pulling from the jdk8 source (because I'm lazy) to express the idea. Feel free to adjust. 3. Reasserting in the finally ensure we are not forcefully setting the interrupted status on the current thread and calling 'statusID' and 'removeImage'. It also ensures that the interrupt is set even if an unexpected exception is thrown. Reasserting at the end of 'e1' and never in 'e2' should work too. The main issue that I'm trying to convey to you is that your test is incomplete in that it does check that the interrupt was swallowed. Swallowing interrupts is bad practice. Reasserting in e2 only means that we swallow interrupts from e1. Change your test to this and retest: === public static void main(String[] args) throws Exception { Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); Thread.currentThread().interrupt(); ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { throw new RuntimeException("Couldn't load GIF from bytes after interruption"); } if (!Thread.currentThread().isInterrupted()) { throw new RuntimeException("Interrupt was swallowed"); } } } === ________________________________________ From: Volodin, Vladislav Sent: Wednesday, January 29, 2020 9:52 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, I have few questions: 1. The second assignment is probably redundant: } catch (InterruptedException e1) { wasInterrupted = true; // line #2, see comment below try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; // <-- this is redundant, because of the line #2 } } finally { 2. I think the first call of "addImage" is not necessary: boolean wasInterrupted = false; mTracker.addImage(image, id); // maybe I should remove this, because of another comment down below. try { loadStatus = 0; mTracker.addImage(image, id); // because of that May I also ask you a question? What is the purpose of interrupting the current thread in the finally block, instead of doing it in the second catch block (where e2 is created)? I assume that since we were able to handle the exception properly, and plus the entire block is in the synchronization area, in theory we have only one importer at the time. Kind regards, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 16:35 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Bug in that last version: Thread.currentThread().isInterrupted(); -> Thread.currentThread().interrupt(); === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().interrupt(); } } } } === ________________________________________ From: swing-dev on behalf of Jason Mehrens Sent: Wednesday, January 29, 2020 9:33 AM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage A shorter version is just to reassert at the end of catch e1. It is safer to just reassert as the last statement in the finally. === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().isInterrupted(); } } } } === Jason ________________________________________ From: Volodin, Vladislav Sent: Tuesday, January 28, 2020 4:02 PM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage This is a valid point, because I wasn?t sure that when the thread is interrupted, I handled the first exception, and my thought was that all other ?wait? calls (maybe in other threads) should get the same exception as well. And since I handled this exceptional case, I am restoring the interrupted status in case if I don?t know how to handle this exception the second time. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; Thread.currentThread().interrupt(); } If I restore the interrupted status BEFORE waitForID call, then this thread will immoderately fail. Should I restore it AFTER, e.g. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); Thread.currentThread().interrupt(); // On 28. Jan 2020, at 22:27, Jason Mehrens wrote: > > ?I see. Well I would have to do some more digging and testing to make myself more knowledgeable on MediaTracker. > > Then the only bug in your current code is that you are not reasserting interrupted status of the current thread in the case e1 is raised and e2 is not. It is usually best to reassert the interrupted state at the end of the method. > > Jason > > ________________________________________ > From: Volodin, Vladislav > Sent: Tuesday, January 28, 2020 2:54 PM > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from ImageIcon.loadImage > > Hi Jason, > > I am not sure about the loop, because I don?t know if we can trust results from mTracker.statusID at the moment when an exceptional case occurs. For example, I was experimenting with the code and found out that the MediaTracker can spawn a thread to load the image, or might use the current thread, and the ABORTED state is never returned (I don?t even know how to raise this state). That is why I don?t even know if your loop will ever stop. > > In my solution, I give the second chance only, and in case if the execution was interrupted the second time, I explicitly assign the ABORTED state to loadStatus. If the user wants to load this image once again, he can create ImageIcon again (or even do this in a loop), or reinitialize it with a single method (I don?t remember its name). > > What do you think? > > Kind regards, > Vlad > > Sent from myPad > >> On 28. Jan 2020, at 21:34, Jason Mehrens wrote: >> >> ?Vlad, >> >> I assume you would want to wait in a loop and reassert the interrupt at the end. >> >> === >> protected void loadImage(Image image) { >> MediaTracker mTracker = getTracker(); >> synchronized(mTracker) { >> int id = getNextID(); >> >> mTracker.addImage(image, id); >> boolean wasInterrupted = false; >> try { >> do { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e) { >> wasInterrupted = true; >> } >> loadStatus = mTracker.statusID(id, false); >> } while (loadStatus == MediaTracker.LOADING); >> mTracker.removeImage(image, id); >> >> width = image.getWidth(imageObserver); >> height = image.getHeight(imageObserver); >> } finally { >> if (wasInterrupted) { >> Thread.currentThread().interrupt(); >> } >> } >> } >> } >> === >> >> Jason >> ________________________________________ >> From: swing-dev on behalf of Volodin, Vladislav >> Sent: Monday, January 27, 2020 11:11 AM >> To: Sergey Bylokhov >> Cc: swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >> Hello Sergey, and others, >> >> here is the patch (made with "git diff") in the attachment. I have read that sometimes the attachments are lost. So here is my version with few comments regarding my code. I decided to use your approach with a small improvement. There is an excerpt of my patch. >> >> The idea is pretty simple: >> 1. I create an empty gif 1x1; >> 2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do not initialize the toolkit in advance, my test will fail at the beginning >> 3. Interrupt the main thread >> 4. Try to load the icon: >> >> import javax.swing.*; >> import java.awt.*; >> >> public class imageIconInterrupted { >> static byte[] EMPTY_GIF = new byte[]{ >> (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) 0x61, (byte) 0x01, (byte) 0x00, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, (byte) 0xF9, (byte) 0x04, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2C, (byte) 0x00, (byte) 0x00, >> (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x02 >> }; >> >> public static void main(String[] args) throws Exception { >> Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); >> >> Thread.currentThread().interrupt(); >> ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); >> if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { >> throw new RuntimeException("Couldn't load GIF from bytes after interruption"); >> } >> } >> } >> >> The code of loadImage I have changed as follows: >> 1. I clear loadStatus for "finally" part; >> 2. Check the interruption according to your comments; >> 3. Change the status to ABORTED, if the interruption happened again (this part I cannot test, because I cannot properly interrupt the thread whenever I want. Multithreading is quite fragile there :( ) >> 4. update the status "interrupted" again; >> 5. and then - finally block. >> >> protected void loadImage(Image image) { >> ... >> try { >> loadStatus = 0; >> mTracker.addImage(image, id); >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e1) { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e2) { >> loadStatus = MediaTracker.ABORTED; >> Thread.currentThread().interrupt(); >> } >> } finally { >> if (loadStatus == 0) { >> loadStatus = mTracker.statusID(id, false); >> } >> mTracker.removeImage(image, id); >> } >> >> P.S. if you think that my patch sounds fine, I will find a sponsor for the bug report and the patch preparation, so you can review it later. >> After the second attempt, my EMPTY_GIF was loaded successfully. The ABORTED part it seems that I don't know if it has ever worked. My patch (in the attachment) checks also the state ERROR for the URL that doesn't exist. Something like: >> >> ImageIcon iconNotExist = new ImageIcon(new URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this URL grammatically correct >> if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) { >> throw new RuntimeException("Got unexpected status from non-existing GIF"); >> } >> >> Thanks to everyone. >> >> Kind regards, >> Vlad >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Dienstag, 21. Januar 2020 22:26 >> To: Volodin, Vladislav >> Cc: Jason Mehrens ; swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >>>> On 1/21/20 1:14 pm, Volodin, Vladislav wrote: >>> Hi all, >>> >>> If I am not mistaken, this method is called from the constructor and other methods. How long should we try loading the icon using the unmanaged (by any thread pool, but I am not sure about this statement) thread? >>> >>> We don?t even have the flag ?interrupted?. So technically this icon has to be loaded. >> >> I think it is necessary to save the "interrupted" state in the catch >> block and try to call waitForID() again. It will be necessary to set >> "interrupted" flag for the Thread after that(when the waitForID will >> return without exception). >> >> >>> Sent from myFone >>> >>>>> On 21. Jan 2020, at 21:55, Sergey Bylokhov wrote: >>>> >>>> ?On 1/21/20 12:26 pm, Jason Mehrens wrote: >>>>> +1 for Sergey suggestion. >>>> >>>> Or probably we need to try to load the image again because of the spec of the method state this: >>>> "Loads the image, returning only when the image is loaded." >>>> >>>>> ________________________________________ >>>>> From: Sergey Bylokhov >>>>> Sent: Sunday, January 19, 2020 9:31 PM >>>>> To: Volodin, Vladislav; Jason Mehrens >>>>> Cc: swing-dev at openjdk.java.net >>>>> Subject: Re: Remove System.out.println from ImageIcon.loadImage >>>>> I guess there are no objections, probably the best way to fix >>>>> it is to drop the System.out.println and set interrupted flag. >>>>> On 1/16/20 7:05 am, Volodin, Vladislav wrote: >>>>>> If people in this distribution list agree, I can start working on a simple fix and either remove the logging (System.out.println), or replace it with PlatformLogger. I guess the second solution sounds better, but I don't know what is the better way to write a test-case for it. >>>>> -- >>>>> Best regards, Sergey. >>>> >>>> >>>> -- >>>> Best regards, Sergey. >> >> >> -- >> Best regards, Sergey. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pankaj.b.bansal at oracle.com Tue Feb 25 16:43:41 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Tue, 25 Feb 2020 08:43:41 -0800 (PST) Subject: [15] RFR JDK-8231042: [macos] JFileChooser creates new folder on ESC Message-ID: <644bb91d-5b4b-4cb5-b0d0-08ecae8a12f6@default> Hi All, Please review the following fix for jdk15. Bug: https://bugs.openjdk.java.net/browse/JDK-8231042 webrev: http://cr.openjdk.java.net/~pbansal/8231042/webrev00/ Issue: In case of AquaLookAndFeel, if a JFileChooser is created and if we try to abort the "New Folder" create action by pressing "ESC" key, there is a new folder created named " uninitializedValue". If the new folder creation is aborted, it should not create any folder as pressing "ESC" key is equivalent to cancelling the folder creation. Cause: In JFileChooser, the check if the JOptionPane is cancelled is missing. This issue is specific to AquaLookAndFeel. Fix: The fix is to add the required check in JFileChoose create NewFolder Action for a Cancelled JOptionPane. I this case, no folder should be created. Regards, Pankaj Bansal -------------- next part -------------- An HTML attachment was scrubbed... URL: From pankaj.b.bansal at oracle.com Thu Feb 27 10:45:42 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Thu, 27 Feb 2020 02:45:42 -0800 (PST) Subject: [15] RFR JDK-8239902: Remove direct usage of JSlider, JProgressBar classes in CAccessible class Message-ID: Hi All, Please review the following fix for jdk15. Bug: https://bugs.openjdk.java.net/browse/JDK-8239902 webrev: http://cr.openjdk.java.net/~pbansal/8239902/webrev00/ Issue: In class CAccessible, the JSlider and JProgressBar class are being used directly, as it is adding changeListeners directly to JSlider or JProgressBar classes. The Accessibility classes should never access swing component classes directly. Instead, they should be accessing the AccessibleContext for the corresponding swing component and use them. Fix: Removed the direct usage of JSlider and JProgressBar classes. CAccessible is adding AXChangeNotifiers notificationListeners for all Accessible swing components. Both JSlider and JProgressBar classes are firing the property change events with property name "ACCESSIBLE_VALUE_PROPERTY" in setValue function using the AccessibleContext. So, these events will be listened to by AXChangeNotifiers and can be processed there instead of adding separate changeListeners. This is a cleanup and will not affect the functionality. This can be verified by running the JSliderDemo and JProgressBarDemo attached in JBS. Regards, Pankaj Bansal -------------- next part -------------- An HTML attachment was scrubbed... URL: From Sergey.Bylokhov at oracle.com Thu Feb 27 10:53:05 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 27 Feb 2020 02:53:05 -0800 Subject: [15] RFR JDK-8239902: Remove direct usage of JSlider, JProgressBar classes in CAccessible class In-Reply-To: References: Message-ID: <85fb0cef-3fd9-bd57-ac7a-fbdde5b0c565@oracle.com> Looks fine. On 2/27/20 2:45 am, Pankaj Bansal wrote: > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8239902 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8239902/webrev00/ > > Issue: > > In class CAccessible, the JSlider and JProgressBar class are being used directly, as it is adding changeListeners directly to JSlider or JProgressBar classes. The Accessibility classes should never access swing component classes directly. Instead, they should be accessing the AccessibleContext for the corresponding swing component and use them. > > Fix: > > Removed the direct usage of JSlider and JProgressBar classes. > > CAccessible is adding AXChangeNotifiers notificationListeners for all Accessible swing components. Both JSlider and JProgressBar classes are firing the property change events with property name ?ACCESSIBLE_VALUE_PROPERTY? in setValue function using the AccessibleContext. So, these events will be listened to by AXChangeNotifiers and can be processed there instead of adding separate changeListeners. > > This is a cleanup and will not affect the functionality. ?This can be verified by running the JSliderDemo and JProgressBarDemo attached in JBS. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Thu Feb 27 11:02:18 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 27 Feb 2020 03:02:18 -0800 Subject: [15] RFR JDK-8231042: [macos] JFileChooser creates new folder on ESC In-Reply-To: <644bb91d-5b4b-4cb5-b0d0-08ecae8a12f6@default> References: <644bb91d-5b4b-4cb5-b0d0-08ecae8a12f6@default> Message-ID: <7fa3c030-9bd6-50e7-9610-923b40ce17f2@oracle.com> Hi, Pankaj. It would be good to filter out the test on non-mac systems by the "@requires" tag. On 2/25/20 8:43 am, Pankaj Bansal wrote: > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8231042 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8231042/webrev00/ > > Issue: > > In case of AquaLookAndFeel, if a JFileChooser is created and if we try to abort the ?New Folder? create action by pressing ?ESC? key, there is a new folder created named ?uninitializedValue?. If the new folder creation is aborted, it should not create any folder as pressing ?ESC? key is equivalent to cancelling the folder creation. > > Cause: > > In JFileChooser, the check if the JOptionPane is cancelled is missing. This issue is specific to AquaLookAndFeel. > > Fix: > > The fix is to add the required check in JFileChoose create NewFolder Action for a Cancelled JOptionPane. I this case, no folder should be created. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From pankaj.b.bansal at oracle.com Thu Feb 27 12:22:23 2020 From: pankaj.b.bansal at oracle.com (Pankaj Bansal) Date: Thu, 27 Feb 2020 04:22:23 -0800 (PST) Subject: [15] RFR JDK-8231042: [macos] JFileChooser creates new folder on ESC In-Reply-To: <7fa3c030-9bd6-50e7-9610-923b40ce17f2@oracle.com> References: <644bb91d-5b4b-4cb5-b0d0-08ecae8a12f6@default> <7fa3c030-9bd6-50e7-9610-923b40ce17f2@oracle.com> Message-ID: <1ab83dd5-4f7b-4356-aa45-501ab270497f@default> Hi Sergey, Thanks for the review. << It would be good to filter out the test on non-mac systems by the "@requires" tag. I added the filter in main method, so if someone is running this as standalone test, even then the test is filtered out. But yes, adding the tag is useful when using jtreg to stop the test from running altogether. I have added the tag "@requires". Please have a look. webrev: http://cr.openjdk.java.net/~pbansal/8231042/webrev01/ Regards, Pankaj -----Original Message----- From: Sergey Bylokhov Sent: Thursday, February 27, 2020 4:32 PM To: Pankaj Bansal ; swing-dev at openjdk.java.net Subject: Re: [15] RFR JDK-8231042: [macos] JFileChooser creates new folder on ESC Hi, Pankaj. It would be good to filter out the test on non-mac systems by the "@requires" tag. On 2/25/20 8:43 am, Pankaj Bansal wrote: > Hi All, > > Please review the following fix for jdk15. > > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8231042 > > webrev: > > http://cr.openjdk.java.net/~pbansal/8231042/webrev00/ > > Issue: > > In case of AquaLookAndFeel, if a JFileChooser is created and if we try to abort the "New Folder" create action by pressing "ESC" key, there is a new folder created named "uninitializedValue". If the new folder creation is aborted, it should not create any folder as pressing "ESC" key is equivalent to cancelling the folder creation. > > Cause: > > In JFileChooser, the check if the JOptionPane is cancelled is missing. This issue is specific to AquaLookAndFeel. > > Fix: > > The fix is to add the required check in JFileChoose create NewFolder Action for a Cancelled JOptionPane. I this case, no folder should be created. > > > Regards, > Pankaj Bansal > -- Best regards, Sergey. From jason_mehrens at hotmail.com Fri Feb 28 01:46:43 2020 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Fri, 28 Feb 2020 01:46:43 +0000 Subject: Remove System.out.println from ImageIcon.loadImage In-Reply-To: References: <2310F0FD-DAA6-4E24-85AD-776D6F979CC0@sap.com> <549622d0-fe72-f267-c105-53b1399471dc@oracle.com>, , , <6CA1C9A2-3FE1-445D-93B7-57DC8818F0FB@sap.com>, , , , , , , Message-ID: Looks good to me. ________________________________________ From: Volodin, Vladislav Sent: Saturday, February 22, 2020 4:38 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Hello Jason and everyone else, here is my webrev that my colleague published http://cr.openjdk.java.net/~clanger/webrevs/6421373.0/ Can you please review it and let me know if I should change anything? Currently I am OOO, but I will do the changes in March. Kind regards, Vlad Get Outlook for iOS ________________________________ From: Jason Mehrens Sent: Tuesday, February 11, 2020 9:13:41 PM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Vlad, Yea that looks good. Jason ________________________________________ From: Volodin, Vladislav Sent: Wednesday, February 5, 2020 9:59 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, thank you for your advice. I have changed my code, now it simulates the behavior of the interrupted thread. Can you please check my patch? I don't have the "bug" ticket, so in my test case "@bug JDK-123456" should be adjusted. I will appreciate if you and somebody else can review my patch and submit it to JDK. Thanks, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 17:55 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage 1. Agreed. 2. I was just pulling from the jdk8 source (because I'm lazy) to express the idea. Feel free to adjust. 3. Reasserting in the finally ensure we are not forcefully setting the interrupted status on the current thread and calling 'statusID' and 'removeImage'. It also ensures that the interrupt is set even if an unexpected exception is thrown. Reasserting at the end of 'e1' and never in 'e2' should work too. The main issue that I'm trying to convey to you is that your test is incomplete in that it does check that the interrupt was swallowed. Swallowing interrupts is bad practice. Reasserting in e2 only means that we swallow interrupts from e1. Change your test to this and retest: === public static void main(String[] args) throws Exception { Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); Thread.currentThread().interrupt(); ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { throw new RuntimeException("Couldn't load GIF from bytes after interruption"); } if (!Thread.currentThread().isInterrupted()) { throw new RuntimeException("Interrupt was swallowed"); } } } === ________________________________________ From: Volodin, Vladislav Sent: Wednesday, January 29, 2020 9:52 AM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: RE: Remove System.out.println from ImageIcon.loadImage Hi Jason, I have few questions: 1. The second assignment is probably redundant: } catch (InterruptedException e1) { wasInterrupted = true; // line #2, see comment below try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; // <-- this is redundant, because of the line #2 } } finally { 2. I think the first call of "addImage" is not necessary: boolean wasInterrupted = false; mTracker.addImage(image, id); // maybe I should remove this, because of another comment down below. try { loadStatus = 0; mTracker.addImage(image, id); // because of that May I also ask you a question? What is the purpose of interrupting the current thread in the finally block, instead of doing it in the second catch block (where e2 is created)? I assume that since we were able to handle the exception properly, and plus the entire block is in the synchronization area, in theory we have only one importer at the time. Kind regards, Vlad -----Original Message----- From: Jason Mehrens Sent: Mittwoch, 29. Januar 2020 16:35 To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage Bug in that last version: Thread.currentThread().isInterrupted(); -> Thread.currentThread().interrupt(); === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; wasInterrupted = true; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().interrupt(); } } } } === ________________________________________ From: swing-dev on behalf of Jason Mehrens Sent: Wednesday, January 29, 2020 9:33 AM To: Volodin, Vladislav Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage A shorter version is just to reassert at the end of catch e1. It is safer to just reassert as the last statement in the finally. === protected void loadImage(Image image) { MediaTracker mTracker = getTracker(); synchronized (mTracker) { int id = getNextID(); boolean wasInterrupted = false; mTracker.addImage(image, id); try { loadStatus = 0; mTracker.addImage(image, id); mTracker.waitForID(id, 0); } catch (InterruptedException e1) { wasInterrupted = true; try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; } } finally { if (loadStatus == 0) { loadStatus = mTracker.statusID(id, false); } mTracker.removeImage(image, id); if (wasInterrupted) { Thread.currentThread().isInterrupted(); } } } } === Jason ________________________________________ From: Volodin, Vladislav Sent: Tuesday, January 28, 2020 4:02 PM To: Jason Mehrens Cc: swing-dev at openjdk.java.net Subject: Re: Remove System.out.println from ImageIcon.loadImage This is a valid point, because I wasn?t sure that when the thread is interrupted, I handled the first exception, and my thought was that all other ?wait? calls (maybe in other threads) should get the same exception as well. And since I handled this exceptional case, I am restoring the interrupted status in case if I don?t know how to handle this exception the second time. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); } catch (InterruptedException e2) { loadStatus = MediaTracker.ABORTED; Thread.currentThread().interrupt(); } If I restore the interrupted status BEFORE waitForID call, then this thread will immoderately fail. Should I restore it AFTER, e.g. } catch (InterruptedException e1) { try { mTracker.waitForID(id, 0); Thread.currentThread().interrupt(); // On 28. Jan 2020, at 22:27, Jason Mehrens wrote: > > ?I see. Well I would have to do some more digging and testing to make myself more knowledgeable on MediaTracker. > > Then the only bug in your current code is that you are not reasserting interrupted status of the current thread in the case e1 is raised and e2 is not. It is usually best to reassert the interrupted state at the end of the method. > > Jason > > ________________________________________ > From: Volodin, Vladislav > Sent: Tuesday, January 28, 2020 2:54 PM > To: Jason Mehrens > Cc: swing-dev at openjdk.java.net > Subject: Re: Remove System.out.println from ImageIcon.loadImage > > Hi Jason, > > I am not sure about the loop, because I don?t know if we can trust results from mTracker.statusID at the moment when an exceptional case occurs. For example, I was experimenting with the code and found out that the MediaTracker can spawn a thread to load the image, or might use the current thread, and the ABORTED state is never returned (I don?t even know how to raise this state). That is why I don?t even know if your loop will ever stop. > > In my solution, I give the second chance only, and in case if the execution was interrupted the second time, I explicitly assign the ABORTED state to loadStatus. If the user wants to load this image once again, he can create ImageIcon again (or even do this in a loop), or reinitialize it with a single method (I don?t remember its name). > > What do you think? > > Kind regards, > Vlad > > Sent from myPad > >> On 28. Jan 2020, at 21:34, Jason Mehrens wrote: >> >> ?Vlad, >> >> I assume you would want to wait in a loop and reassert the interrupt at the end. >> >> === >> protected void loadImage(Image image) { >> MediaTracker mTracker = getTracker(); >> synchronized(mTracker) { >> int id = getNextID(); >> >> mTracker.addImage(image, id); >> boolean wasInterrupted = false; >> try { >> do { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e) { >> wasInterrupted = true; >> } >> loadStatus = mTracker.statusID(id, false); >> } while (loadStatus == MediaTracker.LOADING); >> mTracker.removeImage(image, id); >> >> width = image.getWidth(imageObserver); >> height = image.getHeight(imageObserver); >> } finally { >> if (wasInterrupted) { >> Thread.currentThread().interrupt(); >> } >> } >> } >> } >> === >> >> Jason >> ________________________________________ >> From: swing-dev on behalf of Volodin, Vladislav >> Sent: Monday, January 27, 2020 11:11 AM >> To: Sergey Bylokhov >> Cc: swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >> Hello Sergey, and others, >> >> here is the patch (made with "git diff") in the attachment. I have read that sometimes the attachments are lost. So here is my version with few comments regarding my code. I decided to use your approach with a small improvement. There is an excerpt of my patch. >> >> The idea is pretty simple: >> 1. I create an empty gif 1x1; >> 2. Initialize DefaultToolkit (I plan to interrupt the main thread, and if I do not initialize the toolkit in advance, my test will fail at the beginning >> 3. Interrupt the main thread >> 4. Try to load the icon: >> >> import javax.swing.*; >> import java.awt.*; >> >> public class imageIconInterrupted { >> static byte[] EMPTY_GIF = new byte[]{ >> (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, (byte) 0x61, (byte) 0x01, (byte) 0x00, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, (byte) 0xF9, (byte) 0x04, >> (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2C, (byte) 0x00, (byte) 0x00, >> (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x02 >> }; >> >> public static void main(String[] args) throws Exception { >> Toolkit ignoreToolkit = Toolkit.getDefaultToolkit(); >> >> Thread.currentThread().interrupt(); >> ImageIcon iconInterrupt = new ImageIcon(EMPTY_GIF); >> if (iconInterrupt.getImageLoadStatus() != MediaTracker.COMPLETE) { >> throw new RuntimeException("Couldn't load GIF from bytes after interruption"); >> } >> } >> } >> >> The code of loadImage I have changed as follows: >> 1. I clear loadStatus for "finally" part; >> 2. Check the interruption according to your comments; >> 3. Change the status to ABORTED, if the interruption happened again (this part I cannot test, because I cannot properly interrupt the thread whenever I want. Multithreading is quite fragile there :( ) >> 4. update the status "interrupted" again; >> 5. and then - finally block. >> >> protected void loadImage(Image image) { >> ... >> try { >> loadStatus = 0; >> mTracker.addImage(image, id); >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e1) { >> try { >> mTracker.waitForID(id, 0); >> } catch (InterruptedException e2) { >> loadStatus = MediaTracker.ABORTED; >> Thread.currentThread().interrupt(); >> } >> } finally { >> if (loadStatus == 0) { >> loadStatus = mTracker.statusID(id, false); >> } >> mTracker.removeImage(image, id); >> } >> >> P.S. if you think that my patch sounds fine, I will find a sponsor for the bug report and the patch preparation, so you can review it later. >> After the second attempt, my EMPTY_GIF was loaded successfully. The ABORTED part it seems that I don't know if it has ever worked. My patch (in the attachment) checks also the state ERROR for the URL that doesn't exist. Something like: >> >> ImageIcon iconNotExist = new ImageIcon(new URL("http://doesnt.exist.anywhere/1.gif")); // I am not sure if I spelled this URL grammatically correct >> if (iconNotExist.getImageLoadStatus() != MediaTracker.ERRORED) { >> throw new RuntimeException("Got unexpected status from non-existing GIF"); >> } >> >> Thanks to everyone. >> >> Kind regards, >> Vlad >> >> -----Original Message----- >> From: Sergey Bylokhov >> Sent: Dienstag, 21. Januar 2020 22:26 >> To: Volodin, Vladislav >> Cc: Jason Mehrens ; swing-dev at openjdk.java.net >> Subject: Re: Remove System.out.println from ImageIcon.loadImage >> >>>> On 1/21/20 1:14 pm, Volodin, Vladislav wrote: >>> Hi all, >>> >>> If I am not mistaken, this method is called from the constructor and other methods. How long should we try loading the icon using the unmanaged (by any thread pool, but I am not sure about this statement) thread? >>> >>> We don?t even have the flag ?interrupted?. So technically this icon has to be loaded. >> >> I think it is necessary to save the "interrupted" state in the catch >> block and try to call waitForID() again. It will be necessary to set >> "interrupted" flag for the Thread after that(when the waitForID will >> return without exception). >> >> >>> Sent from myFone >>> >>>>> On 21. Jan 2020, at 21:55, Sergey Bylokhov wrote: >>>> >>>> ?On 1/21/20 12:26 pm, Jason Mehrens wrote: >>>>> +1 for Sergey suggestion. >>>> >>>> Or probably we need to try to load the image again because of the spec of the method state this: >>>> "Loads the image, returning only when the image is loaded." >>>> >>>>> ________________________________________ >>>>> From: Sergey Bylokhov >>>>> Sent: Sunday, January 19, 2020 9:31 PM >>>>> To: Volodin, Vladislav; Jason Mehrens >>>>> Cc: swing-dev at openjdk.java.net >>>>> Subject: Re: Remove System.out.println from ImageIcon.loadImage >>>>> I guess there are no objections, probably the best way to fix >>>>> it is to drop the System.out.println and set interrupted flag. >>>>> On 1/16/20 7:05 am, Volodin, Vladislav wrote: >>>>>> If people in this distribution list agree, I can start working on a simple fix and either remove the logging (System.out.println), or replace it with PlatformLogger. I guess the second solution sounds better, but I don't know what is the better way to write a test-case for it. >>>>> -- >>>>> Best regards, Sergey. >>>> >>>> >>>> -- >>>> Best regards, Sergey. >> >> >> -- >> Best regards, Sergey. From Sergey.Bylokhov at oracle.com Fri Feb 28 18:41:18 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Fri, 28 Feb 2020 10:41:18 -0800 Subject: RFR: 8240202 A few client tests leave mouse buttons pressed Message-ID: Hello. Please review the fix for jdk/client. Bug: https://bugs.openjdk.java.net/browse/JDK-8240202 Fix: http://cr.openjdk.java.net/~serb/8240202/webrev.00 Two tests leave the mouse button pressed: test/jdk/javax/swing/JButton/PressedButtonRightClickTest.java : affects our CI test/jdk/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java : not a big issue, the test is in the problem list already -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Fri Feb 28 18:52:08 2020 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Fri, 28 Feb 2020 10:52:08 -0800 Subject: [15] RFR JDK-8231042: [macos] JFileChooser creates new folder on ESC In-Reply-To: <1ab83dd5-4f7b-4356-aa45-501ab270497f@default> References: <644bb91d-5b4b-4cb5-b0d0-08ecae8a12f6@default> <7fa3c030-9bd6-50e7-9610-923b40ce17f2@oracle.com> <1ab83dd5-4f7b-4356-aa45-501ab270497f@default> Message-ID: <87ed22b0-894e-e795-e7f9-671bff6a6e3c@oracle.com> Looks fine. On 2/27/20 4:22 am, Pankaj Bansal wrote: > Hi Sergey, > > Thanks for the review. > > << It would be good to filter out the test on non-mac systems by the "@requires" tag. > I added the filter in main method, so if someone is running this as standalone test, even then the test is filtered out. But yes, adding the tag is useful when using jtreg to stop the test from running altogether. I have added the tag "@requires". Please have a look. > webrev: http://cr.openjdk.java.net/~pbansal/8231042/webrev01/ > > Regards, > Pankaj > > -----Original Message----- > From: Sergey Bylokhov > Sent: Thursday, February 27, 2020 4:32 PM > To: Pankaj Bansal ; swing-dev at openjdk.java.net > Subject: Re: [15] RFR JDK-8231042: [macos] JFileChooser creates new folder on ESC > > Hi, Pankaj. > > It would be good to filter out the test on non-mac systems by the "@requires" tag. > > On 2/25/20 8:43 am, Pankaj Bansal wrote: >> Hi All, >> >> Please review the following fix for jdk15. >> >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8231042 >> >> webrev: >> >> http://cr.openjdk.java.net/~pbansal/8231042/webrev00/ >> >> Issue: >> >> In case of AquaLookAndFeel, if a JFileChooser is created and if we try to abort the "New Folder" create action by pressing "ESC" key, there is a new folder created named "uninitializedValue". If the new folder creation is aborted, it should not create any folder as pressing "ESC" key is equivalent to cancelling the folder creation. >> >> Cause: >> >> In JFileChooser, the check if the JOptionPane is cancelled is missing. This issue is specific to AquaLookAndFeel. >> >> Fix: >> >> The fix is to add the required check in JFileChoose create NewFolder Action for a Cancelled JOptionPane. I this case, no folder should be created. >> >> >> Regards, >> Pankaj Bansal >> > > -- Best regards, Sergey. From philip.race at oracle.com Fri Feb 28 19:35:57 2020 From: philip.race at oracle.com (Phil Race) Date: Fri, 28 Feb 2020 11:35:57 -0800 Subject: RFR: 8240202 A few client tests leave mouse buttons pressed In-Reply-To: References: Message-ID: <0db74ad5-f5ed-67e0-c7ef-24b331541a65@oracle.com> +1 -phil On 2/28/20 10:41 AM, Sergey Bylokhov wrote: > Hello. > Please review the fix for jdk/client. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8240202 > Fix: http://cr.openjdk.java.net/~serb/8240202/webrev.00 > > Two tests leave the mouse button pressed: > ? test/jdk/javax/swing/JButton/PressedButtonRightClickTest.java : > affects our CI > ? test/jdk/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java : not > a big issue, the test is in the problem list already >