Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8188026: TextFieldXXCell: NPE on calling startEdit #569

Closed
wants to merge 10 commits into from

Conversation

Maran23
Copy link
Member

@Maran23 Maran23 commented Jul 7, 2021

This PR sets an unified logic to every startEdit() method of all Cell implementations.
So startEdit() is always doing the same now:

super.startEdit();
if (!isEditing()) { return; }

This will prevent a NPE while also being cleaner (no more double checks)
The commits are splitted into 4 base commits:

  • First commit changes the startEdit() for TableCell implementations (8 files)
  • Second commit changes the startEdit() for TreeTableCell implementations (7 files)
  • Third commit changes the startEdit() for ListCell implementations (7 files)
  • Fourth commit changes the startEdit() for TreeCell implementations (7 files)

While writing tests, I found out that the CheckBoxListCell and the CheckBoxTreeCell don't disable their CheckBox, which is wrong.
In CheckBoxTableCell and CheckBoxTreeTableCell the CheckBox is disabled, but they don't check their dependencies e.g. TableColumn for null, leading to a NPE if not set.

I wrote a follow-up and assigned it to myself: https://bugs.openjdk.java.net/browse/JDK-8270042
The aim of this should be, that all 4 CheckBox...Cells have a proper CheckBox disablement while also being nullsafe.

Note 1: I removed the tests in TableCellTest added in #529 in favor of the new parameterized TableCellStartEditTest
Note 2: This also fixes https://bugs.openjdk.java.net/browse/JDK-8268295


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issues

  • JDK-8188026: TextFieldXXCell: NPE on calling startEdit
  • JDK-8268295: Tree- and TableCell sub implementations should respect the row editability

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jfx pull/569/head:pull/569
$ git checkout pull/569

Update a local copy of the PR:
$ git checkout pull/569
$ git pull https://git.openjdk.java.net/jfx pull/569/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 569

View PR using the GUI difftool:
$ git pr show -t 569

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jfx/pull/569.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 7, 2021

👋 Welcome back mhanl! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Ready for review label Jul 7, 2021
@mlbridge
Copy link

mlbridge bot commented Jul 7, 2021

Webrevs

@kevinrushforth
Copy link
Member

/reviewers 2

@openjdk
Copy link

openjdk bot commented Jul 7, 2021

@kevinrushforth
The number of required reviews for this PR is now set to 2 (with at least 1 of role reviewers).

@kevinrushforth
Copy link
Member

Note 2: This also fixes https://bugs.openjdk.java.net/browse/JDK-8268295

In that case, you can add that issue to this PR using the Skara /issue add command.

@kleopatra
Copy link
Collaborator

not a review, just some initial comments :)

It has a fat scope : cross-product of

  • editing life-cycle methods (all xxEdit have the same issue with strengthening the precondition, not only startEdit)
  • base cell type (for each virtualized)
  • editing component on cell (textField, comboBox ..)

There might be particular problems for each in separation and additional when combined - pretty sure that there was a reason for implementing the inheritance constraint violation - we must be certain to understand that in each case and fix it correctly (might turn out to be very similar, though)

We probably should limit the scope somehow: f.i. solve

  • for all edit methods
  • for the most used editable cell (TextField)
  • in the most used editable control (TableView)

With the lessons learned, we can swarm out, either on the cell-type or editing-component axis. Probably should create an umbrella task to collect this and all follow-up issues.

Note 1: I removed the tests in TableCellTest added in #529 in favor of the new parameterized TableCellStartEditTest

  • don't know what the convention here is: but I would prefer not remove tests that are added for another issue (except they are testing the wrong thingy, as are the old tests expecting the NPE
  • don't mix :) here we are concerned about the NPE, nothing else (except that editing is still working, which should be covered by the old tests)

@Maran23
Copy link
Member Author

Maran23 commented Jul 8, 2021

not a review, just some initial comments :)

It has a fat scope : cross-product of

  • editing life-cycle methods (all xxEdit have the same issue with strengthening the precondition, not only startEdit)
  • base cell type (for each virtualized)
  • editing component on cell (textField, comboBox ..)

There might be particular problems for each in separation and additional when combined - pretty sure that there was a reason for implementing the inheritance constraint violation - we must be certain to understand that in each case and fix it correctly (might turn out to be very similar, though)

We probably should limit the scope somehow: f.i. solve

  • for all edit methods
  • for the most used editable cell (TextField)
  • in the most used editable control (TableView)

With the lessons learned, we can swarm out, either on the cell-type or editing-component axis. Probably should create an umbrella task to collect this and all follow-up issues.

Note 1: I removed the tests in TableCellTest added in #529 in favor of the new parameterized TableCellStartEditTest

  • don't know what the convention here is: but I would prefer not remove tests that are added for another issue (except they are testing the wrong thingy, as are the old tests expecting the NPE
  • don't mix :) here we are concerned about the NPE, nothing else (except that editing is still working, which should be covered by the old tests)

Alright, well I don't think the tests do any harm, so I also can add them back. :)

Do we wanna create follow-ups for this, so this PR won''t get any bigger? That would be at least my preference.
Right now I see:

  • !isEditing check in cancelEdit() (we can return directly)
  • isEditing check in startEdit() (we can return directly)

Is there more?

@Maran23
Copy link
Member Author

Maran23 commented Jul 8, 2021

/issue add JDK-8268295

@openjdk
Copy link

openjdk bot commented Jul 8, 2021

@Maran23
Adding additional issue to issue list: 8268295: Tree- and TableCell sub implementations should respect the row editability.

@kleopatra
Copy link
Collaborator

Do we wanna create follow-ups for this, so this PR won''t get any bigger? That would be at least my preference.
Right now I see:

* !isEditing check in cancelEdit() (we can return directly)

* isEditing check in startEdit() (we can return directly)

Is there more?

just checked my notes (there's a cell-editing branch in my fork where I'm experimenting) - astonishingly the answer is no, could not see anything :) And actually, seems like we don't even need to return immediately: would have expected some unhealthy side-effects on doing the switching into visual editing state more than once, but couldn't detect anything. You might try, though :)

@Maran23
Copy link
Member Author

Maran23 commented Jul 11, 2021

Do we wanna create follow-ups for this, so this PR won''t get any bigger? That would be at least my preference.
Right now I see:

* !isEditing check in cancelEdit() (we can return directly)

* isEditing check in startEdit() (we can return directly)

Is there more?

just checked my notes (there's a cell-editing branch in my fork where I'm experimenting) - astonishingly the answer is no, could not see anything :) And actually, seems like we don't even need to return immediately: would have expected some unhealthy side-effects on doing the switching into visual editing state more than once, but couldn't detect anything. You might try, though :)

Okay. Question is, should we guard against a double edit? There is already one in TreeTableCell#startEdit, but probably forgotten in TableCell. I think it makes sense and as there is already the check in TreeTableCell, there was at least a thought of it somewhere in the past.
If there is nothing left, should I create a ticket for startEdit and for cancelEdit (this only affects the sub classes) ? :)

@kleopatra
Copy link
Collaborator

just checked my notes (there's a cell-editing branch in my fork where I'm experimenting) - astonishingly the answer is no, could not see anything :) And actually, seems like we don't even need to return immediately: would have expected some unhealthy side-effects on doing the switching into visual editing state more than once, but couldn't detect anything. You might try, though :)

Okay. Question is, should we guard against a double edit? There is already one in TreeTableCell#startEdit, but probably forgotten in TableCell. I think it makes sense and as there is already the check in TreeTableCell, there was at least a thought of it somewhere in the past.

good question, next question ;)

  • the oversight in startEdit of the base List/TableCell is not part of this (covered and soon fixed by JDK-8188027, the concrete misbehavior is that they fire multiple edit events
  • as to the "real" editing cell types (that is those that actually have an editingComponent) - we (that is now you *grin) should try hard to find a scenario where multiple starts (== multiple configuration passes of the editingComponent) might hurt. Like when the user already typed something and for some reason startEdit is called again, the configuration would delete the input.

If there is nothing left, should I create a ticket for startEdit and for cancelEdit (this only affects the sub classes) ? :)

hmm - not sure I understand what you are asking: startEdit is covered, and cancelEdit would be similar - either you find a scenario where multiple un-configure of the cell (after cancel) would hurt or not?

@Maran23
Copy link
Member Author

Maran23 commented Jul 22, 2021

just checked my notes (there's a cell-editing branch in my fork where I'm experimenting) - astonishingly the answer is no, could not see anything :) And actually, seems like we don't even need to return immediately: would have expected some unhealthy side-effects on doing the switching into visual editing state more than once, but couldn't detect anything. You might try, though :)

Okay. Question is, should we guard against a double edit? There is already one in TreeTableCell#startEdit, but probably forgotten in TableCell. I think it makes sense and as there is already the check in TreeTableCell, there was at least a thought of it somewhere in the past.

good question, next question ;)

  • the oversight in startEdit of the base List/TableCell is not part of this (covered and soon fixed by JDK-8188027, the concrete misbehavior is that they fire multiple edit events
  • as to the "real" editing cell types (that is those that actually have an editingComponent) - we (that is now you *grin) should try hard to find a scenario where multiple starts (== multiple configuration passes of the editingComponent) might hurt. Like when the user already typed something and for some reason startEdit is called again, the configuration would delete the input.

If there is nothing left, should I create a ticket for startEdit and for cancelEdit (this only affects the sub classes) ? :)

hmm - not sure I understand what you are asking: startEdit is covered, and cancelEdit would be similar - either you find a scenario where multiple un-configure of the cell (after cancel) would hurt or not?

Finally coming back to this, when firing a startEdit() while already editing e.g. a TextFieldCell, the input which was made by you gets lost and you need to start over. So this can be a potential follow-up. I didn't found anything for cancelEdit().

@kleopatra
Copy link
Collaborator

Finally coming back to this, when firing a startEdit() while already editing e.g. a TextFieldCell, the input which was made by you gets lost and you need to start over. So this can be a potential follow-up. I didn't found anything for cancelEdit().

thinking about it again: for a fully configured cell, there is no difference in behaviour before/after the fix - so the fix should be fine :) I'll start a review next week or so (after tax deadline ;) - for now will just add a suggestion for the tests.

Copy link
Collaborator

@kleopatra kleopatra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will take a closer look next week or so, for now just a starter: fix looks fine, verified test failing/passing before/after :)

As to the tests, left a couple of inline comments to ListCellStartEditTest - others should be changed in the same way.

Copy link
Collaborator

@kleopatra kleopatra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added inline comments, plus: there's an open change request in my last review:

  • not yet covered: sanity test that startEdit really installs the editing visuals - f.i. by checking that its graphic is null before/ not-null after startEdit

might be arguable (might have found the failing tests, though, .. or not :) - personally, I would prefer to only resolve if fully addressed: either after adding the change or consenting to not adding it.

Arguing in favor of testing the ui state after startEdit: this is covering an implicit fix (that is the other way round as the test added inline) for incorrect showing the editing ui if not editing (ComboBoxTree/TableCell)

@Test
public void testComboBoxTableCellEditing() {
    TableView<String> tableView = new TableView<>();
    tableView.setEditable(true);
    TableColumn<String, String> column = new TableColumn<>("test");
    ComboBoxTableCell<String, String> cell = new ComboBoxTableCell<>("one", "two");
    cell.updateTableView(tableView);
    cell.updateTableColumn(column);
    cell.startEdit();
    assertFalse(cell.isEditing());
    assertNull(cell.getGraphic());
}

Comment on lines 297 to 301
super.startEdit();
if (!isEditing()) {
return;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(darn, can't add the important lines - which is backing out if treeItem is null)

The re-ordering leads to change of behavior, here's a test that's passing/failing before/after:

/**
 * change of behavior: cell must not be editing if treeItem == null.
 * fails with fix, passes without
 */
@Test
public void testChoiceBoxTreeCellEditing() {
    TreeView<String> treeView = new TreeView<>();
    treeView.setEditable(true);
    ChoiceBoxTreeCell<String> cell = new ChoiceBoxTreeCell<>();
    cell.updateTreeView(treeView);
    cell.updateItem("TEST", false);
    
    cell.startEdit();
    assertFalse(cell.isEditing());
    assertNull(cell.getGraphic());
}

same for ComboBoxTreeCell

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm.. weird that the super class is firing an edit event even with treeItem = null. Maybe this should be investigated in a follow-up. Good catch though. :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, there are whacky aspects:

  • we can switch a cell that's not attached to its surroundings (like table, column, treeItem, off-range) into editing state - the only constraint being that it's not empty
  • the other way round: a cell that didn't switch into editing will nevertheless fire a editStart on its target

Definitely leeway for improvements ;)

Copy link
Collaborator

@kleopatra kleopatra Sep 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the other way round: a cell that didn't switch into editing will nevertheless fire a editStart on its target

actually, it's worse because it's not only firing but might switch the control into an invalid editing state (f.i. off-range editingIndex for listView) or producing a stackOverflowError (TableCell/View) when properly updating the control's editing location (that is after fix of JDK-8187474)

filed JDK-8274433 as P3 to cover this part

Comment on lines +192 to 195
super.startEdit();
if (!isEditing()) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to ChoiceBox/ComboBoxTreeCell, except that a similar test fails both before/after the fix

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm interesting enough this tree cell has no treeItem = null guard (unlike the others). TreeCells are very weird 😃

@kleopatra
Copy link
Collaborator

@Maran23 wondering why my review comments aren't addressed? Anything unclear?

@Maran23
Copy link
Member Author

Maran23 commented Sep 13, 2021

@Maran23 wondering why my review comments aren't addressed? Anything unclear?

Everything clear, I was just busy the last days. But I think I will address everything in this week. If you can't continue without it e.g. this PR is blocking your (future) work, you can also continue on this. :)

- cell is supplied in setup() method
- treeItem = null guard is done before calling startEdit()
- Added checks for the cell graphic
Copy link
Collaborator

@kleopatra kleopatra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix looks okay now :)

Still a bit weary about the tests: personally, I don't like re-using and re-configuring the same instance of an object inside a longish test method (here: in the tight loop). But then, there are other tests in the code base doing it so probably okay here as well.

@openjdk
Copy link

openjdk bot commented Oct 1, 2021

@Maran23 This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8188026: TextFieldXXCell: NPE on calling startEdit
8268295: Tree- and TableCell sub implementations should respect the row editability

Reviewed-by: fastegal, aghaisas

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 71 new commits pushed to the master branch:

  • 30f5606: 8231644: TreeTableView Regression: Indentation wrong using Label as column content type
  • 55faac4: 8271474: Tree-/TableCell: inconsistent edit event firing pattern
  • 478512b: 8274107: Cherry pick GTK WebKit 2.32.4 changes
  • 4b9cb21: 8273969: Memory Leak on the Runnable provided to Platform.startup
  • 338b999: 8273946: Move clearQuad method to BaseShaderGraphics superclass
  • 5c355fa: 8090158: Wrong implementation of adjustValue in scrollBars
  • f59a057: 8090547: Allow for transparent backgrounds in WebView
  • d356340: 8172095: Let Node.managed become CSS-styleable
  • b2ecfac: 8271398: GTK3 drag view image swaps red and blue color channels
  • 7329279: 8273754: Re-introduce Automatic-Module-Name in empty jars
  • ... and 61 more: https://git.openjdk.java.net/jfx/compare/386f6d7a56d9cfb334c210fccd29e1c5da58b591...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@kleopatra, @aghaisas) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

@openjdk openjdk bot added the ready Ready to be integrated label Oct 1, 2021
@Maran23
Copy link
Member Author

Maran23 commented Oct 1, 2021

/integrate

@openjdk openjdk bot added the sponsor Ready to sponsor label Oct 1, 2021
@openjdk
Copy link

openjdk bot commented Oct 1, 2021

@Maran23
Your change (at version bf9190b) is now ready to be sponsored by a Committer.

@kleopatra
Copy link
Collaborator

/sponsor

@openjdk
Copy link

openjdk bot commented Oct 1, 2021

Going to push as commit 64aa926.
Since your change was applied there have been 72 commits pushed to the master branch:

  • f3c72b9: 8214158: Implement HostServices.showDocument on macOS without calling AWT
  • 30f5606: 8231644: TreeTableView Regression: Indentation wrong using Label as column content type
  • 55faac4: 8271474: Tree-/TableCell: inconsistent edit event firing pattern
  • 478512b: 8274107: Cherry pick GTK WebKit 2.32.4 changes
  • 4b9cb21: 8273969: Memory Leak on the Runnable provided to Platform.startup
  • 338b999: 8273946: Move clearQuad method to BaseShaderGraphics superclass
  • 5c355fa: 8090158: Wrong implementation of adjustValue in scrollBars
  • f59a057: 8090547: Allow for transparent backgrounds in WebView
  • d356340: 8172095: Let Node.managed become CSS-styleable
  • b2ecfac: 8271398: GTK3 drag view image swaps red and blue color channels
  • ... and 62 more: https://git.openjdk.java.net/jfx/compare/386f6d7a56d9cfb334c210fccd29e1c5da58b591...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot closed this Oct 1, 2021
@openjdk openjdk bot added integrated Pull request has been integrated and removed ready Ready to be integrated rfr Ready for review labels Oct 1, 2021
@openjdk
Copy link

openjdk bot commented Oct 1, 2021

@kleopatra @Maran23 Pushed as commit 64aa926.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@openjdk openjdk bot removed the sponsor Ready to sponsor label Oct 1, 2021
@Maran23 Maran23 deleted the 8188026-cell-editing-merged branch November 9, 2021 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

4 participants