From cda549c2c280ed548079f795ef0efbefa7546ccb Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Tue, 3 Jun 2008 18:00:04 +0400 Subject: [PATCH] 4987336: JSlider doesn't show label's animated icon JSlider registers as an image observer of label's icon Reviewed-by: alexp --- .../share/classes/javax/swing/JSlider.java | 30 ++++- .../javax/swing/plaf/basic/BasicSliderUI.java | 20 +-- jdk/test/javax/swing/JSlider/4987336/box.gif | Bin 0 -> 4241 bytes .../swing/JSlider/4987336/bug4987336.html | 9 ++ .../swing/JSlider/4987336/bug4987336.java | 120 ++++++++++++++++++ .../javax/swing/JSlider/4987336/cupanim.gif | Bin 0 -> 5856 bytes 6 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 jdk/test/javax/swing/JSlider/4987336/box.gif create mode 100644 jdk/test/javax/swing/JSlider/4987336/bug4987336.html create mode 100644 jdk/test/javax/swing/JSlider/4987336/bug4987336.java create mode 100644 jdk/test/javax/swing/JSlider/4987336/cupanim.gif diff --git a/jdk/src/share/classes/javax/swing/JSlider.java b/jdk/src/share/classes/javax/swing/JSlider.java index 95b49164b9a..d436f32f1a6 100644 --- a/jdk/src/share/classes/javax/swing/JSlider.java +++ b/jdk/src/share/classes/javax/swing/JSlider.java @@ -33,8 +33,7 @@ import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.IOException; -import java.awt.Color; -import java.awt.Font; +import java.awt.*; import java.util.*; import java.beans.*; @@ -761,6 +760,33 @@ public class JSlider extends JComponent implements SwingConstants, Accessible { updateLabelSizes(); } + /** + * {@inheritDoc} + * @since 1.7 + */ + public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) { + if (!isShowing()) { + return false; + } + + // Check that there is a label with such image + Enumeration elements = labelTable.elements(); + + while (elements.hasMoreElements()) { + Component component = (Component) elements.nextElement(); + + if (component instanceof JLabel) { + JLabel label = (JLabel) component; + + if (SwingUtilities.doesIconReferenceImage(label.getIcon(), img) || + SwingUtilities.doesIconReferenceImage(label.getDisabledIcon(), img)) { + return super.imageUpdate(img, infoflags, x, y, w, h); + } + } + } + + return false; + } /** * Returns the dictionary of what labels to draw at which values. diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java index 2b604301761..635efb04433 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSliderUI.java @@ -25,16 +25,8 @@ package javax.swing.plaf.basic; -import java.awt.Component; import java.awt.event.*; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.Insets; -import java.awt.Color; -import java.awt.IllegalComponentStateException; -import java.awt.Polygon; +import java.awt.*; import java.beans.*; import java.util.Dictionary; import java.util.Enumeration; @@ -1101,6 +1093,16 @@ public class BasicSliderUI extends SliderUI{ JComponent label = (JComponent) dictionary.get(key); label.setEnabled(enabled); + if (label instanceof JLabel) { + Icon icon = label.isEnabled() ? ((JLabel) label).getIcon() : ((JLabel) label).getDisabledIcon(); + + if (icon instanceof ImageIcon) { + // Register Slider as an image observer. It allows to catch notifications about + // image changes (e.g. gif animation) + Toolkit.getDefaultToolkit().checkImage(((ImageIcon) icon).getImage(), -1, -1, slider); + } + } + if ( slider.getOrientation() == JSlider.HORIZONTAL ) { g.translate( 0, labelBounds.y ); paintHorizontalLabel( g, value, label ); diff --git a/jdk/test/javax/swing/JSlider/4987336/box.gif b/jdk/test/javax/swing/JSlider/4987336/box.gif new file mode 100644 index 0000000000000000000000000000000000000000..69d8cdf9d423958daffe16554e41e68b08095bd2 GIT binary patch literal 4241 zcmX}rd0Y~C+`#eS5Jt|yBhl1ANb#tk)FiDCHI=lK4vj7pEsd=u*>>G2c$v!}!GHka2RTebTC*n4Fj~)IMP~OgP3q{kX%BBjdQ^zE3+e zF*L(*V;&kZ>xazRA)_PBP`lMSVVz+%Sj~E?S!*?FtVUJecwe8jZ-!Cd*RJVnSM?b* z=5e#xYW|PW+^#V@o)}=WUSrl6&9K2ZWHefh#y+FbXm%{4L1i?+M!h3NyV1}-!_aQf zw(H?`ts_OdNM*1Z41EU2p20y28?*|8#*y40fDL@P-l*3b94Yh;8iigZ*TYghSE}bo z^c<14PpdUM(rDYY|B-7oj-*?Z1mnh^Sg+!>}OBGa50S3x7@)=U0 zTq2Z1R5=(Z)kvi(sT7t-719|JkyIj-N(53cP@KxIzI}$mI$_ zx6mj`NK3~B950}s7%$(+PxHAH|oIuBgOQ&-|M^ui0!{G*U zIDC#nAe{q1f&9Q3bb26_PUleRfgHMHm_emeA;+2lK~%sI=$N4yAOwQ{zf2|*zy|;j zaG-xeBLH9u2$>mX{s|s94SaI;PH53}6oalon|fR7y7og1L0jd-sT&8WFA^U2o^OcX z*TpXP<}Q2`O%7ufY`T)FsX}0>y-_kTkmPo4?7{5#*5=CkB(|Nt+mLYJVF7BF zx`#AeN=Ojw@%OCyd;Vs?)Eg^f zG0Otay#{qTQwh|TN5xpN_zsn`jW&jf*=A9O?Lu#8RC_`<8>?56p7Agbr__EiAt{Vb zbjrd9jYq_#pT^Lx`H5LaQv7U~C0R=z%&lGJ*U}x7X8m4GsW0n?L6DZxbW~aX%)gqb zDO^n!?0ujF$1J(y4Qkvs#k6{DUILCtvj9h3RrXalKd3ssvGK3~qMz8%wwl;NVQkpt)5y59$KIvhE5?}m*DU>QN(TTQ5z*H4 zqaWAal2Xk69f7O9Ut7d|ba`Oj*8y!Y!iD!QzSxz%EbJ{W*F8$7ME*muMUxW0;tM$A zA2S8)sWGU8wj;vtU|^efLvqBhtuw)kOZ{W@yopy%!wAaDygssTnUxk-dIT(nI@DpWDT$v(Ztyw`~BFr$RsGM*yDRB*Y>Zt+LibA&*jAZ|WTc7uV|Z-Q(i1Q9U+0HDV9Tem z77s?7KK)`fnd&T$p zU9$?+F|@;b;sYOy9afvRLbsi@OrT7X@fhIKti|Le`$T!2!)PO2xp>; zmXvgQGR|Z`2}Knxx0ayvSxYM2;s>*pQo-)@gWKCDUj7+p>A;(=T4R<3wih*$vbpP#eh_8g6+LzcJ10ZV4G0L^~xxD9)K^pKVi&+4Ga1?^ElDZp;g5 zR8xt-4_T7G7TFNC$%;3t>FI5Btl-9~*#(t|y~}cPei{VbE+Rq$w+;BafF0D2w$e4d z^=`)#im>lcN^EHHtWX0Tvt@W$#cx&UuyhoM7F|klvKn4jnr26EN{QY)bQ`q;p=rLl zEN}sek;8Wnd4rcm#LTwZx?Q%|22t92*OO=6=jU6{%cnmMyA>X9-hhp*j`1!^8jva{ zY2&~8)g9RFm!FE7vaAs8j{YVi$OjqA#)xvdJiE(ETzF6sCAT&Hk*sSZ--FA@Ep|O9 zA9{OrOi65eD-ULw!CQ@6SUZ7a*OXl-CcyBOWuiv$8Z~4;_~6iLV+Nl`_T~&s)&MR+ z_IuU0(ze{J{LZ+$2*p+2j>K&jBVDLn3fFXKPUr}wtflDhr@^e}PPeYb1pTqB42b&M zIXCrs&WhqhZ;DG}hKG9aUitB~NWU->@#)6?`rg7dzDI6hH?MvQY-0mhLNbayzNoJDVpWn zo*)0+6r4+y&FNyaogKq=tqXj(mPsWL7UZ3bk2yoC_D%G{2#e;obhaTEm7IQMa`Lzg zfW9ql{HDs>s>^(&;l}fg;)P1GmI7;HArP z^>E&IQov8Pf!_t?`N(cU3~RU&Yl`FV zP`)eG0N&Oz#t>S!|D+B%F@ell{h<<7ebO!LeP+!B@3o>C|wwNlq!TnU=SfbQq}9{&R>A10oxs(E*2-g+GV|f4 z=sT#_5Gh8i92I2nrk8w}r)D&cI^FWEK+H-h-`!@y&w3V@=VrT^v}qCLw2E%h6w_pO+A&hqND_-jURK)Yn`FYCZ zPm@@=nlLMxSfKarnIv=B3oc|WxW@+{0!XBCF;I3ue>3i1GdHZmcyI0y1D%QD{ zw2&*sdp|S1Hs*x6^Kj(vC|}s5E$X6wE2+~!Dxk(nEDBV8>KJV&Wf)OJ!@oQqavdUb zr+L7Dhu7)5uy{bIPG7Y*=Ri~{0nNjCtcwVxZDq9%r-0Gw`7N9qE1lk1S% z`qn{r`z7)^^}ZZAa6zf?uEbt}kP{q$WXD*Qq!uMQLS5dooxEi6!Hg$}do)Z~Z(a~B z$NMhgn3y;_z#|++#HKj6vWa?|(>zmQUs+g!jbLKMg$@($%%yDBk(;4XWSZ-*bY!d@ z(=8(zEf{z8f$>_j)%0!1edh)iC525oir#lM&X1r(el1I@WIOpPOXkIa*LdoD36PXR z^r^!=;#IhO=XSjcA(0V=ZKP2XerHO-X9WHlt&AVzF~OodS0*v0oy(b-fQt?ltKQiN z;9)kY2LhN#k5CHy!+F4(g7is6Gyu468$r{8zTjWYP4q>n5zR6}>nM3ku5+vn+s4B; z^YGWQiH|JKhg(s9HE;BitgaE08Z%K1G@OEs9;&I~=Of!}ST^4uv_&Ay5p0)b`xYVt zep)hN!)K}ytvnLR2DbM*P15k|Xz1*cnipBXS{ZJ(nsw-HMBMsF7aHP+5%$Ip;Hhd% z!3f}LLhX|g`b^G-W(MKeO1#NAQCQosq4vePrJGupHKYUw`yqBA8OLjod)6H;)g4Lv zG%K+#b-0Grp(obpm^TI@%>x;x7(&>CpexgAq-g_Fa}Nl#V|sYRUwK501f%8Dd%gDTW~H z_6`3ho|`#KGC!km_buo;=i}Rjx{pU2-wyy@7XzOZZw*?~uxbTD#3N(?%Z_!mNj}H6#nZrZVkhig@o&|QV_~fL!&zIsj;Vy&GbHCD&Q z*R<<5FKOP^4~!SHGWr3=E*`1iVKXioafn7}gHS|EeJRerq^KDcjv25^)j^ba8m@we zwiW}m52HX6_OtG^^)2Rt%bAe7h?Ep?mp$T#%sRjyIblIz*@$bl>{daLdkSg~gje&> ZW6uKqw&9Cgn!0ubx$%}eyFozY{{a+l1oQv^ literal 0 HcmV?d00001 diff --git a/jdk/test/javax/swing/JSlider/4987336/bug4987336.html b/jdk/test/javax/swing/JSlider/4987336/bug4987336.html new file mode 100644 index 00000000000..b5c9a191f56 --- /dev/null +++ b/jdk/test/javax/swing/JSlider/4987336/bug4987336.html @@ -0,0 +1,9 @@ + + + +There are four Sliders. Each of them has a label with animated gif (a cup of coffee) +and a label with static image. + +Check that for every LAF animation works for all Sliders. + + diff --git a/jdk/test/javax/swing/JSlider/4987336/bug4987336.java b/jdk/test/javax/swing/JSlider/4987336/bug4987336.java new file mode 100644 index 00000000000..0e0e373034a --- /dev/null +++ b/jdk/test/javax/swing/JSlider/4987336/bug4987336.java @@ -0,0 +1,120 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + @bug 4987336 + @summary JSlider doesn't show label's animated icon. + @author Pavel Porvatov + @run applet/manual=done bug4987336.html +*/ + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Hashtable; + +public class bug4987336 extends JApplet { + private static final String IMAGE_RES = "box.gif"; + + private static final String ANIM_IMAGE_RES = "cupanim.gif"; + + public void init() { + JPanel pnLafs = new JPanel(); + pnLafs.setLayout(new BoxLayout(pnLafs, BoxLayout.Y_AXIS)); + + ButtonGroup group = new ButtonGroup(); + + pnLafs.setBorder(new TitledBorder("Available Lafs")); + + for (UIManager.LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) { + LafRadioButton comp = new LafRadioButton(lafInfo); + + pnLafs.add(comp); + group.add(comp); + } + + JPanel pnContent = new JPanel(); + + pnContent.setLayout(new BoxLayout(pnContent, BoxLayout.Y_AXIS)); + + pnContent.add(pnLafs); + pnContent.add(createSlider(true, IMAGE_RES, IMAGE_RES, ANIM_IMAGE_RES, ANIM_IMAGE_RES)); + pnContent.add(createSlider(false, IMAGE_RES, IMAGE_RES, ANIM_IMAGE_RES, ANIM_IMAGE_RES)); + pnContent.add(createSlider(true, ANIM_IMAGE_RES, null, IMAGE_RES, IMAGE_RES)); + pnContent.add(createSlider(false, ANIM_IMAGE_RES, null, IMAGE_RES, IMAGE_RES)); + + getContentPane().add(new JScrollPane(pnContent)); + } + + private static JSlider createSlider(boolean enabled, + String firstEnabledImage, String firstDisabledImage, + String secondEnabledImage, String secondDisabledImage) { + Hashtable dictionary = new Hashtable(); + + dictionary.put(0, createLabel(firstEnabledImage, firstDisabledImage)); + dictionary.put(1, createLabel(secondEnabledImage, secondDisabledImage)); + + JSlider result = new JSlider(0, 1); + + result.setLabelTable(dictionary); + result.setPaintLabels(true); + result.setEnabled(enabled); + + return result; + } + + private static JLabel createLabel(String enabledImage, String disabledImage) { + ImageIcon enabledIcon = enabledImage == null ? null : + new ImageIcon(bug4987336.class.getResource(enabledImage)); + + ImageIcon disabledIcon = disabledImage == null ? null : + new ImageIcon(bug4987336.class.getResource(disabledImage)); + + JLabel result = new JLabel(enabledImage == null && disabledImage == null ? "No image" : "Image", + enabledIcon, SwingConstants.LEFT); + + result.setDisabledIcon(disabledIcon); + + return result; + } + + private class LafRadioButton extends JRadioButton { + public LafRadioButton(final UIManager.LookAndFeelInfo lafInfo) { + super(lafInfo.getName(), lafInfo.getName().equals(UIManager.getLookAndFeel().getName())); + + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + UIManager.setLookAndFeel(lafInfo.getClassName()); + + SwingUtilities.updateComponentTreeUI(bug4987336.this); + } catch (Exception ex) { + // Ignore such errors + System.out.println("Cannot set LAF " + lafInfo.getName()); + } + } + }); + } + } +} diff --git a/jdk/test/javax/swing/JSlider/4987336/cupanim.gif b/jdk/test/javax/swing/JSlider/4987336/cupanim.gif new file mode 100644 index 0000000000000000000000000000000000000000..934d093c580e5690a29612b5fc15ee46e5696058 GIT binary patch literal 5856 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 literal 0 HcmV?d00001