JDK-8096685 : Polytonic displays incorrectly when typed in (via TextField)
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: 8u20
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-11-20
  • Updated: 2015-10-29
  • Resolved: 2015-04-22
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.
JDK 8
8u60Fixed
Related Reports
Blocks :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
When editing a tableview if i try to add tonic in word it appears like this :  kalim'era while the proper is the tonic to go above e 

Interesting is that i don't have that issue in textfield ....
Providing a test :

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
//import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import javafx.util.Callback;


/**
 * FXML Controller class
 *
 * @author balz
 */
public class UploadTemplateController extends Application {

    @Override public void start(Stage primaryStage) throws Exception {
        init(primaryStage);
        primaryStage.show();
    }
    public static void main(String[] args) { launch(args); }

    private void init(Stage primaryStage) {
        Group root = new Group();
        primaryStage.setScene(new Scene(root));
        MasterUploadParameter objMasterUploadParameter=new MasterUploadParameter();
        MasterUploadParameter objMasterUploadParameter1=new MasterUploadParameter();
        MasterUploadParameter objMasterUploadParameter2=new MasterUploadParameter();

        final ObservableList<MasterUploadParameter> tableContent =
            FXCollections.observableArrayList
            (
                objMasterUploadParameter,
                objMasterUploadParameter1,
                objMasterUploadParameter2
            );

        Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
            public TableCell call(TableColumn p) {
                return new EditingCell();
            }
        };

        TableColumn ColumnID = new TableColumn();
        ColumnID.setText("columnId");
        ColumnID.setCellValueFactory(new PropertyValueFactory("columnId"));
        ColumnID.setCellFactory(cellFactory);
        ColumnID.setOnEditCommit(new EventHandler<CellEditEvent<MasterUploadParameter, String>>() {
            @Override
            public void handle(CellEditEvent<MasterUploadParameter, String> evt) {
                try {
                    evt.getTableView().getItems().get(evt.getTablePosition().getRow())
                            .columnId.set(Integer.parseInt(evt.getNewValue()));
                } catch (NumberFormatException numberFormatException) {
                    //do whatever if a non int is entered
                }
            }
        });

        TableColumn columnDesc = new TableColumn("Desc");
        columnDesc.setCellValueFactory(new PropertyValueFactory("desc"));
        columnDesc.setCellFactory(cellFactory);
        columnDesc.setOnEditCommit(new EventHandler<CellEditEvent<MasterUploadParameter, String>>() {
            @Override
            public void handle(CellEditEvent<MasterUploadParameter, String> evt) {
                evt.getTableView().getItems().get(evt.getTablePosition().getRow())
                        .desc.set(evt.getNewValue());
            }
        });

        TableView tableView = new TableView();
        tableView.setItems(tableContent);
        //Enabling editing
        tableView.setEditable(true);
        tableView.getColumns().addAll(ColumnID, columnDesc);
        root.getChildren().add(tableView); 
    }

    public static class MasterUploadParameter {
        private SimpleIntegerProperty columnId;
        public SimpleIntegerProperty columnIdProperty() {return columnId;}

        private StringProperty desc;
        public StringProperty descProperty() {return desc;}

        public MasterUploadParameter() {
            this.columnId=new SimpleIntegerProperty(0);
            this.desc = new SimpleStringProperty("hi");
        }
    }
    // EditingCell - for editing capability in a TableCell
    public static class EditingCell extends TableCell{
        private TextField textField;

        @Override public void startEdit() {
            if (!isEmpty()) {
                super.startEdit();
                createTextField();
                setText(null);
                setGraphic(textField);
                textField.selectAll();
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        textField.requestFocus();
                    }
                });
            }
        }

        @Override public void cancelEdit() {
            super.cancelEdit();

            try {
                setText(getItem().toString());
            } catch (Exception e) {
            }
            setGraphic(null);
        }

        @Override public void updateItem(Object item, boolean empty) {
            System.out.println("find value of update: "+empty+item);
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(getString());
                    setGraphic(null);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            textField.setOnKeyReleased(new EventHandler<KeyEvent>() {                
                @Override public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(textField.getText());
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }

    } 


}
Comments
This fix should be in 8u60-b13.
22-04-2015

Changesets: http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/60b1a3fa522c http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/a7d0901e22c1
22-04-2015

+1 from me.
22-04-2015

@Leif Samuelsson Pressing Shift-ALT followed by ' and then a can get tone correctly ( i suppose that answers your question for ALTGR) using jdk8_40 I guess you can go on with the fix , and i can do an extensive test when it will be in jdk8u60 ea
22-04-2015

Do we have consensus among the reviewers to let this go ahead?
22-04-2015

Thanks, that's interesting. Do the AltGr dead keys also work in 8u20? Such as Shift-AltGr-/ followed by �� to get ���?
22-04-2015

@Leif Samuelsson I can confirm that is is working in versions before u20
22-04-2015

@Leif Samuelsson Using 8u11 I can type �� (; followed by ��), �� (Shift+; followed by ��) and �� (Shift+w followed by ��)
22-04-2015

I have created an updated webrev: http://cr.openjdk.java.net/~leifs/rt39464/webrev.02/ The only change is that I realized we already had a retrieved language id, so I'm using that to identify Greek. - if ((wParam >= 0x0370 && wParam < 0x0400)) { - // Greek alphabet + if (LOBYTE(m_idLang) == LANG_GREEK) {
22-04-2015

It occurred to me that the fix for RT-35261 (that caused the regression) was dealing with dead keys based on AltGr, but it actually fixed (non-Greek) dead keys based on Shift too. George, can you confirm that typing Shift-; followed by �� (iota) to get �� (iota with dialytika) wasn't working before 8u20 either? If this is true, then my proposed fix will actually be an improvement over the situation before the regression.
21-04-2015

I'm good with the proposed fix given that we don't have the complete setup and testing expertise for this bug. This will allow George to do the extensive testing next week. Dave and Kevin. what is your take?
21-04-2015

Yes. It will take a couple of weeks to end up in the 8u60 ea build after the fix is approved. I will update here with the specific build number too look for.
21-04-2015

Will the patch be available in any newer jdk8u60 betas so i can do an extensive test?
21-04-2015

Thanks. I'm hoping that this fix is good enough for common usage, i.e. that most Greek users can live without the AltGr dead keys for the time being. We will fix the AltGr issue also, probably for 9 if it's not too urgent. It will mean that we must either continue down the current path and figure out why the keyboard state is only partially reset after the dead key is handled, or go back and find a way to use the system handler for both this and the French AltGr issues. Both of these approaches require resources and are probably a bit too risky to attempt for 8u60.
21-04-2015

I can verify that this proposed fix works for the key strokes I know (for simple testing) but I don't know Greek to know this is a good enough fix. I agree this fix is not an acceptable solution in the long run; it is hard to review without an understanding of the context.
21-04-2015

I will review and test this proposed fix later in the day or evening when I have the right HW.
20-04-2015

Here are some overviews of typing on a Greek keyboard. I used these for reference to find characters to decompose. http://www.ellopos.net/elpenor/greek-texts/gr-pol-keys/greek-keyboard.asp http://download.microsoft.com/download/2/5/4/2543a817-a8c4-4c63-a46a-f04a82bf623e/The%20Greek%20Polytonic%20System.doc
20-04-2015

Yes, the sets do overlap. Some dead keys generate different combining characters depending on the keyboard, or maybe depending on the following key typed. I'm not sure which way the native library handles it, but I only have the following key to look at when deciding. This is why we can't make the decision on whether to pass the dead key to the default system handler, since when the typed key comes in, we have already reset the keyboard state explicitly.
20-04-2015

cant say I know much about dead keys, but questions did pop up. Is there a reason to segregate the greek set ? Do these sets overlap ?
20-04-2015

It's just the OpenJFX bits that you would need to build, not the whole JDK. If you are able to do this, the instructions for building OpenJFX are here: https://wiki.openjdk.java.net/display/OpenJFX/Building+OpenJFX This still requires compilers on Windows, so may not be a good option for you. If you can't test it, then that's OK. We will look for another way to test it internally.
20-04-2015

hmm it is possible to provide me a compiled jdk with the fix to test? I am not aware how to build the whole jdk yet ;/
20-04-2015

I have tested this on Windows 7 with a US keyboard set to "Greek Polytonic" layout. It would be helpful if someone with a real Greek keyboard (and better knowledge) could compile and test the fix.
20-04-2015

Webrev for review: http://cr.openjdk.java.net/~leifs/rt39464/webrev.01/ The fix for RT-35261 means that we must handle all dead keys ourselves. As pointed out above, if the call to HandleViewDeadKeyEvent() is commented out, the handling is done by the OS instead. However, when the dead key arrives, we can't decide whether to use our own handling or not, so we are now forced to have our own translating tables for all keyboard layouts. This fix adds explicit dead key translation for Greek keyboard layout. This is not an acceptable situation in the long run, so we should revisit the basic decision made for RT-35261 as soon as possible. I've noted that AWT seems to let the OS handle this, so there must something there that we can learn from. The Greek composing sequences were derived by running FoldString() with MAP_COMPOSITE, and then hard-coding the sequences into this fix. The list is not complete, as dead keys typed with AltGr are generating illegal values. This may need fixing later with a separate JIRA issue.
20-04-2015

No progress on fixing that bug yet? I am forced to use jdk 1.8.0_11 for all my javafx project till now ;/
17-04-2015

It's over two months , u40 is already out , u60 betas are already out , but still no fix for that . Note that this is a major fix that probably affects all gr based javafx programs . Any change we see it on any of upcoming u60 betas sometime soon?
18-03-2015

There is no fix yet, so we don't currently have an estimate.
12-01-2015

any estimation when that bug will be include in a early access build?
12-01-2015

This is a Glass bug, I'm reassigning it to Dave.
05-01-2015

Disabling deadchar processing fixes the regression but this will undo the fix to RT-35261. diff --git a/modules/graphics/src/main/native-glass/win/GlassWindow.cpp b/modules/graphics/src/main/native-glass/win/GlassWindow.cpp --- a/modules/graphics/src/main/native-glass/win/GlassWindow.cpp +++ b/modules/graphics/src/main/native-glass/win/GlassWindow.cpp @@ -459,7 +459,7 @@ } break; case WM_DEADCHAR: - if (IsEnabled()) HandleViewDeadKeyEvent(GetHWND(), msg, wParam, lParam); + if (false && IsEnabled()) HandleViewDeadKeyEvent(GetHWND(), msg, wParam, lParam); break; case WM_CHAR: case WM_IME_CHAR:
05-01-2015

The problem was introduced by the following changeset: changeset: 6779:e5fcb65c3c26 user: Anthony Petrov <anthony.petrov@oracle.com> date: Wed Apr 16 15:28:11 2014 +0400 summary: RT-35261: [Glass, French Keyboard] cannot type backquote in TextArea & TextField
25-12-2014

Sorry for the duplicate. I searched for similar issues, but I didn't see this one. @George Moralis. If you are set on using one of the latest versions and not the 8u11, you could try something like this: https://gist.github.com/Apo-/4a237f2151e57b1dcc4a As the gist title suggests, this is not an ideal workaround and I haven't tested it that much(just wrote the code 15 minutes ago).
23-12-2014

This might be a glass bug instead of a scene graph bug. See RT-39716 for a duplicate issue that was just filed. It has the following observation: "Any time, I type <��> the keyCode at com.sun.glass.ui.View#notifyKey is always 0. I think the keyCode should be 59 the first time."
22-12-2014

i have tested it on windows7 as well
09-12-2014

That's correct. My test was done on Windows 8.1
09-12-2014

This was with Windows 8, right?
09-12-2014

I can reproduce this bug by adding Greek language and using the following key combinations: �� type ;a ��� type ]a ��� type [a
09-12-2014

This appears to be a regression introduced in 8u20. We will look at fixing this for 8u60.
01-12-2014

after some more digging , trying to figure out and due to fact that textfield appears to work on scene builder 2.0 i started to search if there is a regression between different jdk 8 versions Scene builder uses jdk1.8.0 and it's okay I used jdk1.8.0_05 and it appears my samples work okay I used 1.8.0_11 and it works okay I used jdk1.8.0_20 and problem appears Same as jdk1.8.0_25 and problem is there as well So problem lies in a change between 11 - 20 till 1.8.0_11 all my tests appears to work fine
30-11-2014

just tested latest 1.8.0_40-ea-b15 problem is there as well
30-11-2014

still no success . What can be the difference using a textfield inside a jfxpanel and using textfield on a plain javafx application? as already mentioned it work fine inside a jfxpanel
27-11-2014

ok tried with .textfiled { -fx-font-size : 12 , 11 and others } changed the padding of textfield but problem still occurs
26-11-2014

ehmm css code sample? i am kinda new to javafx and my swing experience doesn't help much ;/
25-11-2014

Yes, it may be font size related. If you can, try applying alternate CSS styling to a TextField to increase / decrease the font size, as well as the TextField size / padding.
25-11-2014

so to resume it works on scenebuilder and in a scene inside a jfxpanel but not in standalone javafx application. Any clue what can defers to have such a behaviour? maybe font ?
25-11-2014

Yes, they are all the same JavaFX TextField control.
25-11-2014

I tested in scenebuilder , in preview and in textfiled properties ( prompt text , text ) i can type correctly . I am clueless . Isn't textfield properties javafx textfields also? (the specific properties i mention)
25-11-2014

Hi George: we are focused right now on fixing the last few critical bugs for the 8u40 ZBB build and subsequent M4 milestone. We need to prioritize looking at other issues such as this after we achieve this. We appreciate receiving bug reports from the community, and will address them as a "best effort" when we can. I would not expect an answer to this for another week or so.
25-11-2014

not a clue? or a workaround? i noticed that the same happend with caspian theme as well as modena
25-11-2014

and the buggy javafx application public class Javafxtextfield2 extends Application { @Override public void start(Stage primaryStage) { TextField field = new TextField(); StackPane root = new StackPane(); root.getChildren().add(field); Scene scene = new Scene(root, 300, 250); primaryStage.setTitle("Hello bug"); primaryStage.setScene(scene); primaryStage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } Note : both are netbeans projects with utf-8 encoding. I can post the projects if that helps...
24-11-2014

ok things got more weird now. It seems textField also has the same issue, the reason why i thought it was okay is because i was using a textfield inside a jfxpanel. If i use a textfield inside a jfxpanel tonic are correct, if i use it on a standalone application it has issue (textfield and probably it's the same reason for tableview) i attach the working sample for jfxpanel . (maybe it's font issue after all???) public class Javafxtextfield { private static void initAndShowGUI() { // This method is invoked on Swing thread JFrame frame = new JFrame("FX"); final JFXPanel fxPanel = new JFXPanel(); frame.add(fxPanel); frame.setSize(200, 200); frame.setVisible(true); Platform.runLater(new Runnable() { @Override public void run() { initFX(fxPanel); } }); } private static void initFX(JFXPanel fxPanel) { // This method is invoked on JavaFX thread TextField text = new TextField(); Group root = new Group(); Scene scene = new Scene(root); root.getChildren().add(text); fxPanel.setScene(scene); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { initAndShowGUI(); } }); } }
24-11-2014

TableView uses the same font as the rest of JavaFX, so if it works for you in TextField it seems unlikely. I think the question is what do you need to change on TextField (outside of TableView) to be able to recreate the issue? I can't imagine it is a TableView-specific issue.
23-11-2014

can it be relative to font? what's the default font that tableview is using?
23-11-2014

George - expecting much of a response over the weekend is unlikely :-) Now that it is Monday all I can say is that I have nothing really to add - I have no knowledge of how to type words out like this, nor why it appears to be TableView-specific. If this is the case it seems very odd as TableView doesn't do anything with the input. My only question is whether it relates to the height of the TextField inside a cell and whether by adjusting the height (using CSS) that this might fix the issue?
23-11-2014

nothing? :(
23-11-2014

Bug priority is under control of the development team. Do not alter the priority of a bug as a way of indicating that it is important to you. This is objectively a P3 bug. In any case it is too late for such a rendering bug for 8u40. We will fix it for 9, at which time we can consider backporting it to an 8 update release (possibly 8u60). Perhaps Jonathan has an answer to your question about a workaround?
21-11-2014

jkd9 ? Can you at least suggest a workaround? My application is freezed because of that issue
21-11-2014

Note : i can paste a tonic word but i can't type it (while editing a cell). Words for test : ���������������� (how is supposed to be ) ������������������ (how it appears while typing)
20-11-2014