23 * questions. 24 */ 25 26 package sun.lwawt.macosx; 27 28 import java.awt.Component; 29 import java.beans.PropertyChangeEvent; 30 import java.beans.PropertyChangeListener; 31 import java.lang.reflect.Field; 32 33 import javax.accessibility.Accessible; 34 import javax.accessibility.AccessibleContext; 35 import javax.swing.JProgressBar; 36 import javax.swing.JSlider; 37 import javax.swing.event.ChangeEvent; 38 import javax.swing.event.ChangeListener; 39 40 import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY; 41 import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY; 42 import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY; 43 import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY; 44 45 46 class CAccessible extends CFRetainedResource implements Accessible { 47 static Field getNativeAXResourceField() { 48 try { 49 final Field field = AccessibleContext.class.getDeclaredField("nativeAXResource"); 50 field.setAccessible(true); 51 return field; 52 } catch (final Exception e) { 53 e.printStackTrace(); 54 return null; 55 } 56 } 57 58 private static Field nativeAXResourceField = getNativeAXResourceField(); 59 60 public static CAccessible getCAccessible(final Accessible a) { 61 if (a == null) return null; 62 AccessibleContext context = a.getAccessibleContext(); 63 try { 64 final CAccessible cachedCAX = (CAccessible) nativeAXResourceField.get(context); 65 if (cachedCAX != null) return cachedCAX; 66 67 final CAccessible newCAX = new CAccessible(a); 68 nativeAXResourceField.set(context, newCAX); 69 return newCAX; 70 } catch (final Exception e) { 71 e.printStackTrace(); 72 return null; 73 } 74 } 75 76 private static native void unregisterFromCocoaAXSystem(long ptr); 77 private static native void valueChanged(long ptr); 78 private static native void selectedTextChanged(long ptr); 79 private static native void selectionChanged(long ptr); 80 81 private Accessible accessible; 82 83 private AccessibleContext activeDescendant; 84 85 private CAccessible(final Accessible accessible) { 86 super(0L, true); // real pointer will be poked in by native 87 88 if (accessible == null) throw new NullPointerException(); 89 this.accessible = accessible; 90 91 if (accessible instanceof Component) { 92 addNotificationListeners((Component)accessible); 93 } 94 } 95 96 @Override 97 protected synchronized void dispose() { 98 if (ptr != 0) unregisterFromCocoaAXSystem(ptr); 99 super.dispose(); 108 if (c instanceof Accessible) { 109 AccessibleContext ac = ((Accessible)c).getAccessibleContext(); 110 ac.addPropertyChangeListener(new AXChangeNotifier()); 111 } 112 if (c instanceof JProgressBar) { 113 JProgressBar pb = (JProgressBar) c; 114 pb.addChangeListener(new AXProgressChangeNotifier()); 115 } else if (c instanceof JSlider) { 116 JSlider slider = (JSlider) c; 117 slider.addChangeListener(new AXProgressChangeNotifier()); 118 } 119 } 120 121 122 private class AXChangeNotifier implements PropertyChangeListener { 123 124 @Override 125 public void propertyChange(PropertyChangeEvent e) { 126 String name = e.getPropertyName(); 127 if ( ptr != 0 ) { 128 if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) { 129 selectedTextChanged(ptr); 130 } else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) { 131 valueChanged(ptr); 132 } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) { 133 selectionChanged(ptr); 134 } else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) { 135 Object nv = e.getNewValue(); 136 if (nv instanceof AccessibleContext) { 137 activeDescendant = (AccessibleContext)nv; 138 } 139 } 140 } 141 } 142 } 143 144 private class AXProgressChangeNotifier implements ChangeListener { 145 @Override 146 public void stateChanged(ChangeEvent e) { 147 if (ptr != 0) valueChanged(ptr); 148 } 149 } 150 151 static Accessible getSwingAccessible(final Accessible a) { 152 return (a instanceof CAccessible) ? ((CAccessible)a).accessible : a; 153 } 154 155 static AccessibleContext getActiveDescendant(final Accessible a) { 156 return (a instanceof CAccessible) ? ((CAccessible)a).activeDescendant : null; 157 } | 23 * questions. 24 */ 25 26 package sun.lwawt.macosx; 27 28 import java.awt.Component; 29 import java.beans.PropertyChangeEvent; 30 import java.beans.PropertyChangeListener; 31 import java.lang.reflect.Field; 32 33 import javax.accessibility.Accessible; 34 import javax.accessibility.AccessibleContext; 35 import javax.swing.JProgressBar; 36 import javax.swing.JSlider; 37 import javax.swing.event.ChangeEvent; 38 import javax.swing.event.ChangeListener; 39 40 import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY; 41 import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY; 42 import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY; 43 import static javax.accessibility.AccessibleContext.ACCESSIBLE_STATE_PROPERTY; 44 import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY; 45 import javax.accessibility.AccessibleRole; 46 import javax.accessibility.AccessibleState; 47 48 49 class CAccessible extends CFRetainedResource implements Accessible { 50 static Field getNativeAXResourceField() { 51 try { 52 final Field field = AccessibleContext.class.getDeclaredField("nativeAXResource"); 53 field.setAccessible(true); 54 return field; 55 } catch (final Exception e) { 56 e.printStackTrace(); 57 return null; 58 } 59 } 60 61 private static Field nativeAXResourceField = getNativeAXResourceField(); 62 63 public static CAccessible getCAccessible(final Accessible a) { 64 if (a == null) return null; 65 AccessibleContext context = a.getAccessibleContext(); 66 try { 67 final CAccessible cachedCAX = (CAccessible) nativeAXResourceField.get(context); 68 if (cachedCAX != null) return cachedCAX; 69 70 final CAccessible newCAX = new CAccessible(a); 71 nativeAXResourceField.set(context, newCAX); 72 return newCAX; 73 } catch (final Exception e) { 74 e.printStackTrace(); 75 return null; 76 } 77 } 78 79 private static native void unregisterFromCocoaAXSystem(long ptr); 80 private static native void valueChanged(long ptr); 81 private static native void selectedTextChanged(long ptr); 82 private static native void selectionChanged(long ptr); 83 private static native void menuOpened(long ptr); 84 private static native void menuClosed(long ptr); 85 private static native void menuItemSelected(long ptr); 86 87 private Accessible accessible; 88 89 private AccessibleContext activeDescendant; 90 91 private CAccessible(final Accessible accessible) { 92 super(0L, true); // real pointer will be poked in by native 93 94 if (accessible == null) throw new NullPointerException(); 95 this.accessible = accessible; 96 97 if (accessible instanceof Component) { 98 addNotificationListeners((Component)accessible); 99 } 100 } 101 102 @Override 103 protected synchronized void dispose() { 104 if (ptr != 0) unregisterFromCocoaAXSystem(ptr); 105 super.dispose(); 114 if (c instanceof Accessible) { 115 AccessibleContext ac = ((Accessible)c).getAccessibleContext(); 116 ac.addPropertyChangeListener(new AXChangeNotifier()); 117 } 118 if (c instanceof JProgressBar) { 119 JProgressBar pb = (JProgressBar) c; 120 pb.addChangeListener(new AXProgressChangeNotifier()); 121 } else if (c instanceof JSlider) { 122 JSlider slider = (JSlider) c; 123 slider.addChangeListener(new AXProgressChangeNotifier()); 124 } 125 } 126 127 128 private class AXChangeNotifier implements PropertyChangeListener { 129 130 @Override 131 public void propertyChange(PropertyChangeEvent e) { 132 String name = e.getPropertyName(); 133 if ( ptr != 0 ) { 134 Object newValue = e.getNewValue(); 135 Object oldValue = e.getOldValue(); 136 if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) { 137 selectedTextChanged(ptr); 138 } else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) { 139 valueChanged(ptr); 140 } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) { 141 selectionChanged(ptr); 142 } else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) { 143 if (newValue instanceof AccessibleContext) { 144 activeDescendant = (AccessibleContext)newValue; 145 } 146 } else if (name.compareTo(ACCESSIBLE_STATE_PROPERTY) == 0) { 147 AccessibleContext thisAC = accessible.getAccessibleContext(); 148 AccessibleRole thisRole = thisAC.getAccessibleRole(); 149 Accessible parentAccessible = thisAC.getAccessibleParent(); 150 AccessibleRole parentRole = null; 151 if (parentAccessible != null) { 152 parentRole = parentAccessible.getAccessibleContext().getAccessibleRole(); 153 } 154 // At least for now don't handle combo box menu state changes. 155 // This may change when later fixing issues which currently 156 // exist for combo boxes, but for now the following is only 157 // for JPopupMenus, not for combobox menus. 158 if (parentRole != AccessibleRole.COMBO_BOX) { 159 if (thisRole == AccessibleRole.POPUP_MENU) { 160 if ( newValue != null && 161 ((AccessibleState)newValue) == AccessibleState.VISIBLE ) { 162 menuOpened(ptr); 163 } else if ( oldValue != null && 164 ((AccessibleState)oldValue) == AccessibleState.VISIBLE ) { 165 menuClosed(ptr); 166 } 167 } else if (thisRole == AccessibleRole.MENU_ITEM) { 168 if ( newValue != null && 169 ((AccessibleState)newValue) == AccessibleState.FOCUSED ) { 170 menuItemSelected(ptr); 171 } 172 } 173 } 174 } 175 } 176 } 177 } 178 179 private class AXProgressChangeNotifier implements ChangeListener { 180 @Override 181 public void stateChanged(ChangeEvent e) { 182 if (ptr != 0) valueChanged(ptr); 183 } 184 } 185 186 static Accessible getSwingAccessible(final Accessible a) { 187 return (a instanceof CAccessible) ? ((CAccessible)a).accessible : a; 188 } 189 190 static AccessibleContext getActiveDescendant(final Accessible a) { 191 return (a instanceof CAccessible) ? ((CAccessible)a).activeDescendant : null; 192 } |