Skip to main content

Java 6u23b01 breaks Synth compatibility

5 replies [Last post]
wzberger
Offline
Joined: 2004-08-31
Points: 0

The menu item modifications break compatibility with Synthetica (a Synth based look and feel). It looks like in Java 6u23 GraphicUtils#layoutText(...) isn't any longer used to layout menu items and "Menu.textIconGap" is no longer respected. We install our own GraphicUtils class and override #paintText and #layoutText to make menu items more customizable. The issue also occurs on JDK7 and I've already filed related bug reports but unfortunately until now no official entry has been created from your side (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6961223).

In the test case below the topLevel menu item should be indented and the #paintText and #layoutText methods should be called. Please respect that the issue will affect millions of users if leaving unchanged. You should seriously consider to revoke the changes.

<br />
package test.synth;</p>
<p>import java.awt.Dimension;<br />
import java.awt.EventQueue;<br />
import java.awt.FontMetrics;<br />
import java.awt.Graphics;<br />
import java.awt.Rectangle;<br />
import java.io.ByteArrayInputStream;<br />
import java.io.InputStream;</p>
<p>import javax.swing.Icon;<br />
import javax.swing.JFrame;<br />
import javax.swing.JMenu;<br />
import javax.swing.JMenuBar;<br />
import javax.swing.JMenuItem;<br />
import javax.swing.UIManager;<br />
import javax.swing.plaf.synth.SynthContext;<br />
import javax.swing.plaf.synth.SynthGraphicsUtils;<br />
import javax.swing.plaf.synth.SynthLookAndFeel;</p>
<p>public class SynthMenuTest extends JFrame<br />
{<br />
  // Note: Modify gfxUtils class declaration if package is not test.synth !<br />
  private static String synthXml = "" +<br />
  "    " +<br />
  "      " +<br />
  "      " +<br />
  "      " +<br />
  "    " +<br />
  "    " +<br />
  "    " +<br />
  "      " +<br />
  "      " +<br />
  "    " +<br />
  "    " +<br />
  "";</p>
<p>  public static void main(String[] args)<br />
  {<br />
    EventQueue.invokeLater(new Runnable(){<br />
      public void run()<br />
      {<br />
        try<br />
        {<br />
          new SynthMenuTest();<br />
        }<br />
        catch (Exception e)<br />
        {<br />
          e.printStackTrace();<br />
        }<br />
      }<br />
    });<br />
  }</p>
<p>  public SynthMenuTest() throws Exception<br />
  {<br />
    InputStream is = new ByteArrayInputStream(synthXml.getBytes("UTF8"));<br />
    SynthLookAndFeel laf = new SynthLookAndFeel();<br />
    laf.load(is, SynthMenuTest.class);<br />
    UIManager.setLookAndFeel(laf);    </p>
<p>    JMenuBar menuBar = new JMenuBar();<br />
    setJMenuBar(menuBar);</p>
<p>    JMenu m = new JMenu("Menu");<br />
    m.add(new JMenuItem("Item 1"));<br />
    m.add(new JMenuItem("Item 2"));<br />
    m.add(new JMenuItem("Item 3"));<br />
    menuBar.add(m);        </p>
<p>    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
    setSize(new Dimension(400, 300));<br />
    setLocationRelativeTo(null);<br />
    setVisible(true);<br />
  }</p>
<p>  public static class GraphicUtils extends SynthGraphicsUtils<br />
  {<br />
    @Override<br />
    public void paintText(SynthContext sc, Graphics g, String text, int x, int y, int mnemonicIndex)<br />
    {<br />
      if (sc.getComponent() instanceof JMenuItem)<br />
        System.err.println("Paint: " + ((JMenuItem)sc.getComponent()).getText());<br />
      super.paintText(sc, g, text, x, y, mnemonicIndex);<br />
    }</p>
<p>    @Override<br />
    public String layoutText(SynthContext sc, FontMetrics fm, String text, Icon icon, int align, int align2, int textPosition, int textPosition2,<br />
        Rectangle viewR, Rectangle iconR, Rectangle textR, int iconTextGap)<br />
    {<br />
      if (sc.getComponent() instanceof JMenuItem)<br />
        System.err.println("Layout: " + ((JMenuItem)sc.getComponent()).getText());<br />
      return super.layoutText(sc, fm, text, icon, align, align2, textPosition, textPosition2, viewR, iconR, textR, iconTextGap);<br />
    }<br />
  }<br />
}<br />

Please execute the test case and compare the result with previous Java releases. You can also download the evaluation copy of our product for testing at http://www.jyloo.com/synthetica/download. Additional themes and simple Webstart demos (for testing) are available at http://www.jyloo.com/synthetica/themes.

Thanks,
Wolfgang
Jyloo Software

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
wzberger
Offline
Joined: 2004-08-31
Points: 0

Because of the MenuLayoutHelper - setting a custom SynthMenuLayoutHelper by a new UI-property through UIManager would be even better. So we can add any changes to the core lib and leave synth xml files unchanged.

Thanks,
Wolfgang

alexfromsun
Offline
Joined: 2005-09-05
Points: 0

Hello Wolfgang

We rewrote the menu code in JDK 7 and recently back ported it to JDK 6,
the changes were quite big and I am sorry they broke Synthetica

Could you give me more details about how Synthetica uses that custom GraphicUtils class?
Do you change it in the boot class path?

How exactly does it work?

Thanks
alexp

wzberger
Offline
Joined: 2004-08-31
Points: 0

As you can see in the test case the class is declared in the synth.xml file so Synth creates and makes use of an instance of the given GraphicUtils class.
[code]
"

" [/code] We hook into the mentioned methods to do some additional things like text shadow painting and menu item indention by modifying parameters before the super method is called. The changes of u23 can break each Synth based look and feel which makes use of a custom GraphicUtils class. I also wonder why you consider to do such big changes in a maintenance release.
alexfromsun
Offline
Joined: 2005-09-05
Points: 0

Hello Wolfgang

Indeed, it was a big change, but we had to fix it JDK 6

I need your help with this issue, in 6u23 we use some new static methods in SynthGraphicsUtils
to layout menu items, like getPreferredMenuItemSize()

Do you think the good fix would be to introduce new public non-static
methods in SynthGraphicsUtils that do the same?

Will it make possible to decorate the menu like you do in Syntetica?

Any other comments are welcome

Thanks
alexp

wzberger
Offline
Joined: 2004-08-31
Points: 0

Hi Alex,

it would be definitely helpful if the visibility of all related methods is at leased protected and of course non-static.

But I fear this is not enough - we have to hook into the layout routine to keep compatibility with existing look and feel themes. I've roughly checked the sources and I think a customized SynthMenuLayoutHelper could be a possible solution. The declaration/installation of a custom LayoutHelper could be similar to GraphicsUtils installation - SynthMenuLayoutHelper has to be public.

For detailed testing we need another EA release which provides the mentioned changes.

Please note that "Menu.textIconGap" is no longer applied to top level menus - is this another bug or intended?

Thanks,
Wolfgang