JDK-6961223 : Synth: Compatibility for JMenu/JMenuItem is broken
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u24,7,8
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_vista,windows_7
  • CPU: x86
  • Submitted: 2010-06-15
  • Updated: 2022-09-16
  • Resolved: 2022-09-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdResolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b84)
Java HotSpot(TM) Client VM (build 17.0-b09, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Windows

A DESCRIPTION OF THE PROBLEM :
In Java 5 and Java 6 the Text rendering for JMenu and JMenuItem is made through SynthGraphicUtils - in Java 7 the relevant layout method is no longer called. Because we are using our own GraphicUtils class (derived from SynthGraphicUtils) to customize layout and rendering this breaks compatibility.

Some of our clients have about 5Mio. user base, so this is a critical issue.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the attached test case. Some info will be printed at the error stream.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Some rendering info will be printed at the console.
ACTUAL -
No layout info appears at the console.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test.synth;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthGraphicsUtils;
import javax.swing.plaf.synth.SynthLookAndFeel;

public class SynthMenuTest extends JFrame
{
  // Note: Modify gfxUtils package if package is not test.synth !
  private static String synthXml = "<synth>" +
  "    <style id=\"all\">" +
  "      <font name=\"Dialog\" size=\"12\"/>" +
  "      <object id=\"gfxUtils\" class=\"test.synth.SynthMenuTest$GraphicUtils\"/>" +
  "      <graphicsUtils idref=\"gfxUtils\"/>" +
  "    </style>" +
  "    <bind style=\"all\" type=\"REGION\" key=\".*\"/>" +
  "    <style id=\"menu\">" +
  "      <insets top=\"3\" left=\"0\" bottom=\"3\" right=\"0\"/>" +
  "      <property key=\"Menu.textIconGap\" type=\"integer\" value=\"24\"/>" +
  "    </style>" +
  "    <bind style=\"menu\" type=\"region\" key=\"Menu\"/>" +
  "</synth>";
  
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable(){
      public void run()
      {
        try
        {
          new SynthMenuTest();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }

  public SynthMenuTest() throws Exception
  {
    InputStream is = new ByteArrayInputStream(synthXml.getBytes("UTF8"));
    SynthLookAndFeel laf = new SynthLookAndFeel();
    laf.load(is, SynthMenuTest.class);
    UIManager.setLookAndFeel(laf);

    JMenuBar menuBar = new JMenuBar();
    setJMenuBar(menuBar);

    JMenu m = new JMenu("Menu");
    m.add(new JMenuItem("Item 1"));
    m.add(new JMenuItem("Item 2"));
    m.add(new JMenuItem("Item 3"));
    menuBar.add(m);
    
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(new Dimension(400, 300));
    setLocationRelativeTo(null);
    setVisible(true);
  }
  
  public static class GraphicUtils extends SynthGraphicsUtils
  {
    @Override
    public void paintText(SynthContext sc, Graphics g, String text, int x, int y, int mnemonicIndex)
    {
      if (sc.getComponent() instanceof JMenuItem)
        System.err.println("Paint: " + ((JMenuItem)sc.getComponent()).getText());
      super.paintText(sc, g, text, x, y, mnemonicIndex);
    }
    
    @Override
    public String layoutText(SynthContext sc, FontMetrics fm, String text, Icon icon, int align, int align2, int textPosition, int textPosition2,
        Rectangle viewR, Rectangle iconR, Rectangle textR, int iconTextGap)
    {
      if (sc.getComponent() instanceof JMenuItem)
        System.err.println("Layout: " + ((JMenuItem)sc.getComponent()).getText());
      return super.layoutText(sc, fm, text, icon, align, align2, textPosition, textPosition2, viewR, iconR, textR, iconTextGap);
    }
  }
}  

---------- END SOURCE ----------

Comments
Submitter mentioned "so in the meantime we created our own UI-delegates and additionally added some new features. Because of this the issue is already fixed for us"
16-09-2022

This bug breaks the functional test: Swing_JMenu/Automated/SynthMenuTest See related issue INTJDK-7051169
18-06-2013

EVALUATION I contacted with the submitter, they already workarounded this issue so it is not stopper for them any more. Quote: "so in the meantime we created our own UI-delegates and additionally added some new features. Because of this the issue is already fixed for us." downgraded to P4 and targeted to JDK 8
13-05-2011

EVALUATION this is a regression of 6584657, please see http://forums.java.net/jive/thread.jspa?messageID=481551 for details
03-09-2010