This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 121585 - I18N "Internationalize..." operation does not find all hard coded strings
Summary: I18N "Internationalize..." operation does not find all hard coded strings
Status: RESOLVED FIXED
Alias: None
Product: java
Classification: Unclassified
Component: I18N (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: Marian Petras
URL:
Keywords:
: 71977 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-11-09 14:37 UTC by qb
Modified: 2009-02-12 12:50 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
pic (67.27 KB, image/png)
2009-02-12 09:50 UTC, Alexey Butenko
Details

Note You need to log in before you can comment on or make changes to this bug.
Description qb 2007-11-09 14:37:46 UTC
When using "Internationalize..." or the I18N-wizard on a netbeans form not all hard coded strings are found. For
example, some of my titledBorders' titles are found and some are not.
(In Netbeans 6 in the advanced options, the I18N options are missing, so I cannot check the regEx for strings to be
ignored or found.)
Comment 1 Marian Petras 2007-11-15 00:42:56 UTC
This has been confirmed in a comment in bug report #91799.
Comment 2 Marian Petras 2008-03-27 21:47:45 UTC
I tried the Antenna form again in a newer build (080325). The following occurrences were unexpectedly skipped:

   jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(" Position/Direction "));
   jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(" System "));
   jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Kathrein 742151" }));
   jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "X +45\u00b0" }));
   jButton5.setText("Adjust");

I noticed that although string "X +45\u00b0" was not internationalized, it was decoded to string "X +45°".
Comment 3 Marian Petras 2008-03-27 21:57:23 UTC
While trying to understand the code, I realized that there is one routine implemented twice in class FormI18nSupport -
it is the routine for iteration over form properties of a given form component. I implemented this routine as a Iterator.

Modified file:
    i18n.form/src/org/netbeans/modules/i18n/form/FormI18nSupport.java

Changeset Id:
36e6837c78d0
(http://hg.netbeans.org/main/rev/36e6837c78d0)
Comment 4 Tomas Pavek 2008-03-28 12:08:30 UTC
Note the combobox model can't be internationalized. That's a known limitation - issue 95588.
Comment 5 Marian Petras 2008-05-16 22:06:42 UTC
Combo-box elements and titles of titled borders cannot be automatically internationalized - this is a known limitation -
see issue #95588.

Texts of all buttons should be internationalized.
Comment 6 Marian Petras 2008-05-16 22:10:37 UTC
*** Issue 71977 has been marked as a duplicate of this issue. ***
Comment 7 Marian Petras 2008-05-16 22:37:14 UTC
I think I found the cause of the issue with the "Adjust" button:

The bug is in class org.netbeans.modules.form.i18n.FormI18nSupport.FormI18nFinder, in method findInForm(...). If field
'lastFoundProp' is non-null at the moment the method is called, then the following code is called in the beginning of
the method:

            if (lastFoundProp != null) {
                validProp = lastFoundProp;
                it = formProperties.tailSet(lastFoundProp).iterator();
            }

The 'it' is an iterator over form properties in the form being internationalized. The line "it = ..." sets it such that
it iterates only from the last found property. Apparently, the goal was to skip form properties that were
internationalized during previous invocations of the method (it is called once for each hard-coded string in the source
code).

Object 'lastFoundProp' has some internal value called "skip" which should prevent the last internationalized string from
being internationalized again - so it is OK to try the same property again. The problem is that if it is not the
matching property (it is not "found" during the first iteration), it is checked again during the second iteration, this
time with "skip" equal to zero. During this second iteration, the routine thus probes the same form property that was
already scheduled for I18N during the previous invocation of the method. It seems that it manifests itself only if value
if last two internationalizable strings have the same value - in the described example, the same string is "Adjust".

If you look at the code of the Antenna class, you can see the following lines in it:

        jButton2.setText(bundle.getString("Adjust")); // NOI18N
        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "X +45°" }));
        jButton5.setText(bundle.getString("Adjust")); // NOI18N

The middle line is skipped because the form editor is not able to internationalize property jComboBox's property "model"
having non-string value. So only the following lines are taken into account:

        jButton2.setText(bundle.getString("Adjust")); // NOI18N
        jButton5.setText(bundle.getString("Adjust")); // NOI18N

At first, jButton2's property "text" is properly internationalized. Then, the next time method "findInForm" is called,
property "text" of jButton2 should be skipped as it had been internationalized in the previous cycle. But it is not
skipped, due to the above bug. So it is checked whether its value matches to found hard-coded string ("Adjust"). It does
- so it is internationalized the second time, leaving property "text" of jButton5 unchanged (non-internationalized).
Comment 8 Marian Petras 2008-05-16 22:40:05 UTC
The suggested fix is simple - fix the code that initializes the iterator:

            if (lastFoundProp != null) {
                validProp = lastFoundProp;
                it = formProperties.tailSet(lastFoundProp).iterator();
THE FIX -->     it.next();     //skip 'lastFoundProp' in the next cycle (if any)
            }
Comment 9 Marian Petras 2008-05-19 10:16:18 UTC
I applied the fix described above.

Changeset Id:
4f4ff83121ce
(http://hg.netbeans.org/main/rev/4f4ff83121ce)
Comment 10 Quality Engineering 2008-05-20 05:09:22 UTC
Integrated into 'main-golden', available in NB_Trunk_Production #206 build
Changeset: http://hg.netbeans.org/main/rev/4f4ff83121ce
User: mpetras@netbeans.org
Log: fixed (partially) bug #121585 ("Internationalize..." operation does not find all hard coded strings)
Comment 11 Alexey Butenko 2008-12-03 13:49:48 UTC
As I see from last message it was fixed and integrated
Comment 12 arittner 2009-01-19 09:51:19 UTC
I reopen the bug.

The action "Internationalize..." never find strings with german umlauts.

Examples:

    jPB_Delete.setText("Löschen"); 
    jPB_Delete.setToolTipText("Auswahl zurücksetzen");

But it is very typical with I18N to handle international characters :-)

best regards,
  josh.
Comment 13 Alexey Butenko 2009-02-12 09:50:53 UTC
Created attachment 76901 [details]
pic
Comment 14 Alexey Butenko 2009-02-12 09:52:19 UTC
WORKSFORME, see picture
Comment 15 arittner 2009-02-12 10:02:57 UTC
Sorry, but the RESOLVED is a little bit to fast...
Currently I I18N a application with up to 1200 hardcoded strings. Many strings with german umlauts (and some without)
are ignored. 

I'll attach full sourcode from java-files if I back in office...

br, josh.

Comment 16 Marian Petras 2009-02-12 11:18:52 UTC
The whole mechanism for internationalization of UI forms is based on a weak base. It relies on order of hard-coded
strings in Java code generated by the form editor module, without having any API connection which would make this
assumption reliable. This is quite error-prone approach. If the form editor changes the Java code generator, the
Internationalization module may be severely broken. Another weak point is that if the form module's API does not allow
to internationalize strings in some UI elements (such as elements in combo-boxes) but the corresponding hard-coded
strings are generated in the Java code, these strings may confuse the Internationalization module's algorithm and cause
failures. A proper fix would probably require rewrite of a substantial part of the Internationalization module, plus
some changes in the Form module.
Comment 17 Marian Petras 2009-02-12 11:20:42 UTC
If somebody reports that something does not work in the Internationalization module, it is always worth trying it both
in a form class (defining a dialog/frame) and in a plain class.
Comment 18 Alexey Butenko 2009-02-12 12:31:20 UTC
OK, thanks for comments, in Forms it doesn't work. Reopening
Comment 19 Alexey Butenko 2009-02-12 12:50:54 UTC
changeset b21cc034336e