8036983: JAB:Multiselection Ctrl+CursorUp/Down and ActivateDescenderPropertyChanged event
Reviewed-by: pchelko, alexsch
Contributed-by: vivi.an@oracle.com
--- a/jdk/src/share/classes/javax/swing/JTable.java Mon Apr 14 12:59:50 2014 -0700
+++ b/jdk/src/share/classes/javax/swing/JTable.java Tue Apr 15 15:28:01 2014 -0700
@@ -6586,8 +6586,8 @@
TableColumnModelListener, CellEditorListener, PropertyChangeListener,
AccessibleExtendedTable {
- int lastSelectedRow;
- int lastSelectedCol;
+ int previousFocusedRow;
+ int previousFocusedCol;
/**
* AccessibleJTable constructor
@@ -6602,8 +6602,10 @@
tcm.addColumnModelListener(this);
tcm.getSelectionModel().addListSelectionListener(this);
JTable.this.getModel().addTableModelListener(this);
- lastSelectedRow = JTable.this.getSelectedRow();
- lastSelectedCol = JTable.this.getSelectedColumn();
+ previousFocusedRow = JTable.this.getSelectionModel().
+ getLeadSelectionIndex();
+ previousFocusedCol = JTable.this.getColumnModel().
+ getSelectionModel().getLeadSelectionIndex();
}
// Listeners to track model, etc. changes to as to re-place the other
@@ -6929,20 +6931,23 @@
*/
public void valueChanged(ListSelectionEvent e) {
firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
- Boolean.valueOf(false), Boolean.valueOf(true));
-
- int selectedRow = JTable.this.getSelectedRow();
- int selectedCol = JTable.this.getSelectedColumn();
- if (selectedRow != lastSelectedRow ||
- selectedCol != lastSelectedCol) {
- Accessible oldA = getAccessibleAt(lastSelectedRow,
- lastSelectedCol);
- Accessible newA = getAccessibleAt(selectedRow, selectedCol);
+ Boolean.valueOf(false), Boolean.valueOf(true));
+
+ // Using lead selection index to cover both cases: node selected and node
+ // is focused but not selected (Ctrl+up/down)
+ int focusedRow = JTable.this.getSelectionModel().getLeadSelectionIndex();
+ int focusedCol = JTable.this.getColumnModel().getSelectionModel().
+ getLeadSelectionIndex();
+
+ if (focusedRow != previousFocusedRow ||
+ focusedCol != previousFocusedCol) {
+ Accessible oldA = getAccessibleAt(previousFocusedRow, previousFocusedCol);
+ Accessible newA = getAccessibleAt(focusedRow, focusedCol);
firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
- oldA, newA);
- lastSelectedRow = selectedRow;
- lastSelectedCol = selectedCol;
- }
+ oldA, newA);
+ previousFocusedRow = focusedRow;
+ previousFocusedCol = focusedCol;
+ }
}
--- a/jdk/src/share/classes/javax/swing/JTree.java Mon Apr 14 12:59:50 2014 -0700
+++ b/jdk/src/share/classes/javax/swing/JTree.java Tue Apr 15 15:28:01 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1664,6 +1664,14 @@
leadPath = newPath;
firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, newPath);
+
+ // Fire the active descendant property change here since the
+ // leadPath got set, this is triggered both in case node
+ // selection changed and node focus changed
+ if (accessibleContext != null){
+ ((AccessibleJTree)accessibleContext).
+ fireActiveDescendantPropertyChange(oldValue, newPath);
+ }
}
/**
@@ -4129,26 +4137,9 @@
*
*/
public void valueChanged(TreeSelectionEvent e) {
- // Fixes 4546503 - JTree is sending incorrect active
- // descendant events
- TreePath oldLeadSelectionPath = e.getOldLeadSelectionPath();
- leadSelectionPath = e.getNewLeadSelectionPath();
-
- if (oldLeadSelectionPath != leadSelectionPath) {
- // Set parent to null so AccessibleJTreeNode computes
- // its parent.
- Accessible oldLSA = leadSelectionAccessible;
- leadSelectionAccessible = (leadSelectionPath != null)
- ? new AccessibleJTreeNode(JTree.this,
- leadSelectionPath,
- null) // parent
- : null;
- firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
- oldLSA, leadSelectionAccessible);
- }
- firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
- Boolean.valueOf(false), Boolean.valueOf(true));
- }
+ firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
+ Boolean.valueOf(false), Boolean.valueOf(true));
+ }
/**
* Fire a visible data property change notification.
@@ -4249,6 +4240,34 @@
}
}
+ /**
+ * Fire an active descendant property change notification.
+ * The active descendant is used for objects such as list,
+ * tree, and table, which may have transient children.
+ * It notifies screen readers the active child of the component
+ * has been changed so user can be notified from there.
+ *
+ * @param oldPath - lead path of previous active child
+ * @param newPath - lead path of current active child
+ *
+ */
+ void fireActiveDescendantPropertyChange(TreePath oldPath, TreePath newPath){
+ if(oldPath != newPath){
+ Accessible oldLSA = (oldPath != null)
+ ? new AccessibleJTreeNode(JTree.this,
+ oldPath,
+ null)
+ : null;
+
+ Accessible newLSA = (newPath != null)
+ ? new AccessibleJTreeNode(JTree.this,
+ newPath,
+ null)
+ : null;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
+ oldLSA, newLSA);
+ }
+ }
private AccessibleContext getCurrentAccessibleContext() {
Component c = getCurrentComponent();