Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6435886

Non-Editing JComponents render some bidirection text wrong

    Details

      Description

      FULL PRODUCT VERSION :
      java version "1.6.0-beta2"
      Java(TM) SE Runtime Environment (build 1.6.0-beta2-b80)
      Java HotSpot(TM) Client VM (build 1.6.0-beta2-b80, mixed mode, sharing)

      java version "1.5.0_06"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      JLabels, JButtons, and presumably other JComponents that aren't editable render text
      incorrectly when it starts with right-to-left text and ends with left-to-right text.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test program. Buttons on the left let you try the test in different Looks & Feels, but this bug doesn't depend on the look and feel.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Each column will attempt to render a different string of text. Each column will try
      to render its String using several different components. The string should get
      rendered the same by every component that renders it. So for each column, the
      same text should show in all its components.

      ACTUAL -
      When the string starts with Arabic text and ends with Roman text, it renders
      the differen blocks of text in the wrong order. (A block of text is a contiguous
      string of characters with the same directionality.) This is the case for the first
      column and for the last column. In all cases, the JTextComponent subclasses
      render the text properly. The ones that get it wrong are the JLabel and the JButton.
      (Other test cases can be written to show that a CellRenderer for a JTable or JTree
       will also get it wrong.)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package com.mm.bugs;

      /*
        Synopsis: Non-Editing JComponents render some bidirection text wrong

      Full OS Version:
      Microsoft Windows XP [Version 5.1.2600]

      Additional Configuration Information:

        Development Kit or Runtime Version:

      java version "1.6.0-beta2"
      Java(TM) SE Runtime Environment (build 1.6.0-beta2-b80)
      Java HotSpot(TM) Client VM (build 1.6.0-beta2-b80, mixed mode, sharing)

      java version "1.5.0_06"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)


        Description:
      JLabels, JButtons, and presumably other JComponents that aren't editable render text
      incorrectly when it starts with right-to-left text and ends with left-to-right text.

      Steps to reproduce:
      Run the test program.

      Expected Result:
      Each column will attempt to render a different string of text. Each column will try
      to render its String using several different components. The string should get
      rendered the same by every component that renders it. So for each column, the
      same text should show in all its components.

      Actual Result:
      When the string starts with Arabic text and ends with Roman text, it renders
      the differen blocks of text in the wrong order. (A block of text is a contiguous
      string of characters with the same directionality.) This is the case for the first
      column and for the last column. In all cases, the JTextComponent subclasses
      render the text properly. The ones that get it wrong are the JLabel and the JButton.
      (Other test cases can be written to show that a CellRenderer for a JTable or JTree
       will also get it wrong.)

      Error Message(s):

      Source Code:

      Workaround:


      */

      import java.awt.BorderLayout;
      import java.awt.GridLayout;
      import java.awt.Rectangle;
      import java.awt.Component;
      import java.awt.event.ActionEvent;
      import java.text.MessageFormat;
      import javax.swing.*;
      import javax.swing.border.EtchedBorder;
      import javax.swing.plaf.metal.OceanTheme;
      import javax.swing.plaf.metal.MetalLookAndFeel;
      import javax.swing.plaf.metal.DefaultMetalTheme;

      public class BiDirTextBug extends JPanel {
      private static JFrame sMainFrame;
      private static String biDirTextA = "\u0639\u0631\u0628\u064A Arabic";
      private static String biDirTextB = "Arabic: \u0639\u0631\u0628\u064A";
      private static String biDirTextC = "Arabic: \u0639\u0631\u0628\u064A Arabic";
      private static String biDirTextD = "\u0639\u0631\u0628\u064A Arabic \u0639\u0631\u0628\u064A";
      private static String biDirTextE = "\u0639\u0631\u0628\u064A Arabic \ufb31\u05d7\u05db\u05d0 Hebrew";

      private static String aX = "Starts with Arabic, ends with Roman.";
      private static String bX = "Starts with Roman, ends with Arabic";
      private static String cX = "Starts and ends with Roman";
      private static String dX = "Starts and ends with Arabic";
      private static String eX = "More complex, but starts with Arabic and ends with Roman";

      public static void main(String[] args) {
      makeFrame(LandF.Platform);
      }

      private static void makeFrame(LandF landf) {
      Rectangle oldBounds = null;
      if (sMainFrame != null) {
      oldBounds = sMainFrame.getBounds();
      sMainFrame.dispose();
      }
      landf.install();
      sMainFrame = new JFrame("BiDirTextBug");
      sMainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      sMainFrame.getContentPane().setLayout(new GridLayout(1, 0, 10, 10));
      sMainFrame.add(new BiDirTextBug(biDirTextA, aX));
      sMainFrame.add(new BiDirTextBug(biDirTextB, bX));
      sMainFrame.add(new BiDirTextBug(biDirTextC, cX));
      sMainFrame.add(new BiDirTextBug(biDirTextD, dX));
      sMainFrame.add(new BiDirTextBug(biDirTextE, eX));
      sMainFrame.add(makeLandFButtons(), BorderLayout.WEST);
      if (oldBounds == null)
      sMainFrame.setBounds(10, 10, 600, 325);
      else
      sMainFrame.setBounds(oldBounds);
      sMainFrame.setVisible(true);
      }

      public BiDirTextBug(String txt, String description) {
      super(new BorderLayout());
      JPanel box = new JPanel();
      box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));

      String htmlWrap = "<html>{0}</html>";
      String htmlText = MessageFormat.format(htmlWrap, description);
      addToBox(box, new JLabel(htmlText));
      addToBox(box, Box.createVerticalStrut(10));

      addToBox(box, new JLabel(txt));
      addToBox(box, new JButton(txt));
      addToBox(box, new JTextField(txt));
      JTextArea what = new JTextArea(txt, 2, 40);
      what.setLineWrap(true);

      addToBox(box, what);
      add(box, BorderLayout.NORTH);
      setBorder(new EtchedBorder());
      }

      /**
      * This prevents the BoxLayout weirdness from causing problems.
      * Each component will get the same alignment.
      */
      private void addToBox(JPanel box, Component what) {
      JPanel holder = new JPanel(new BorderLayout());
      holder.add(what, BorderLayout.CENTER);
      box.add(holder);
      }

      private static JPanel makeLandFButtons() {
      JPanel pnl = new JPanel(new GridLayout(0, 1));
      LandF[] all = LandF.values();
      for (LandF lf : all)
      pnl.add(new JButton(lf.getAction()));
      JPanel outerPanel = new JPanel();
      outerPanel.add(pnl);
      return outerPanel;
      }

      private enum LandF {
      Platform(UIManager.getSystemLookAndFeelClassName()),
      Metal(MetalLookAndFeel.class.getName()),
      Ocean(UIManager.getCrossPlatformLookAndFeelClassName()),
      Motif(com.sun.java.swing.plaf.motif.MotifLookAndFeel.class.getName()),;
      final private String mName;
      private Action mAction;

      LandF(String name) {
      mName = name;
      mAction = new LandFAction(this);
      }

      public String getLFName() { return mName; }

      public void install() {
      try {
      UIManager.setLookAndFeel(getLFName());
      extra();
      } catch (ClassNotFoundException e) {
      e.printStackTrace();
      } catch (InstantiationException e) {
      e.printStackTrace();
      } catch (IllegalAccessException e) {
      e.printStackTrace();
      } catch (UnsupportedLookAndFeelException e) {
      e.printStackTrace();
      }
      }

      public Action getAction() {
      return mAction;
      }

      private void extra() throws UnsupportedLookAndFeelException {
      if (this == Metal) {
      System.err.println("Extra!");
      MetalLookAndFeel lf = (MetalLookAndFeel) UIManager.getLookAndFeel();
      lf.setCurrentTheme(new DefaultMetalTheme());
      UIManager.setLookAndFeel(lf); // set it again
      } else if (this == Ocean) {
      MetalLookAndFeel lf = (MetalLookAndFeel) UIManager.getLookAndFeel();
      lf.setCurrentTheme(new OceanTheme());
      UIManager.setLookAndFeel(lf); // set it again
      }
      }
      }

      private static class LandFAction extends AbstractAction {
      private LandF mLookAndFeel;

      public void actionPerformed(ActionEvent e) { makeFrame(mLookAndFeel); }

      LandFAction(LandF lAndF) {
      super(lAndF.toString());
      mLookAndFeel = lAndF;
      }
      }
      }

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

        Attachments

          Activity

            People

            • Assignee:
              peterz Peter Zhelezniakov
              Reporter:
              rmandalasunw Ranjith Mandala (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Imported:
                Indexed: