1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1185 System.out.println("In JMenu.menuSelectionChanged to " + isIncluded);
1186 }
1187 setSelected(isIncluded);
1188 }
1189
1190 /**
1191 * Returns an array of <code>MenuElement</code>s containing the submenu
1192 * for this menu component. If popup menu is <code>null</code> returns
1193 * an empty array. This method is required to conform to the
1194 * <code>MenuElement</code> interface. Note that since
1195 * <code>JSeparator</code>s do not conform to the <code>MenuElement</code>
1196 * interface, this array will only contain <code>JMenuItem</code>s.
1197 *
1198 * @return an array of <code>MenuElement</code> objects
1199 */
1200 @BeanProperty(bound = false)
1201 public MenuElement[] getSubElements() {
1202 if(popupMenu == null)
1203 return new MenuElement[0];
1204 else {
1205 MenuElement result[] = new MenuElement[1];
1206 result[0] = popupMenu;
1207 return result;
1208 }
1209 }
1210
1211
1212 // implements javax.swing.MenuElement
1213 /**
1214 * Returns the <code>java.awt.Component</code> used to
1215 * paint this <code>MenuElement</code>.
1216 * The returned component is used to convert events and detect if
1217 * an event is inside a menu component.
1218 */
1219 public Component getComponent() {
1220 return this;
1221 }
1222
1223
1224 /**
1225 * Sets the <code>ComponentOrientation</code> property of this menu
1268 /**
1269 * Processes key stroke events such as mnemonics and accelerators.
1270 *
1271 * @param evt the key event to be processed
1272 */
1273 protected void processKeyEvent(KeyEvent evt) {
1274 MenuSelectionManager.defaultManager().processKeyEvent(evt);
1275 if (evt.isConsumed())
1276 return;
1277
1278 super.processKeyEvent(evt);
1279 }
1280
1281 /**
1282 * Programmatically performs a "click". This overrides the method
1283 * <code>AbstractButton.doClick</code> in order to make the menu pop up.
1284 * @param pressTime indicates the number of milliseconds the
1285 * button was pressed for
1286 */
1287 public void doClick(int pressTime) {
1288 MenuElement me[] = buildMenuElementArray(this);
1289 MenuSelectionManager.defaultManager().setSelectedPath(me);
1290 }
1291
1292 /*
1293 * Build an array of menu elements - from <code>PopupMenu</code> to
1294 * the root <code>JMenuBar</code>.
1295 * @param leaf the leaf node from which to start building up the array
1296 * @return the array of menu items
1297 */
1298 private MenuElement[] buildMenuElementArray(JMenu leaf) {
1299 Vector<MenuElement> elements = new Vector<>();
1300 Component current = leaf.getPopupMenu();
1301 JPopupMenu pop;
1302 JMenu menu;
1303 JMenuBar bar;
1304
1305 while (true) {
1306 if (current instanceof JPopupMenu) {
1307 pop = (JPopupMenu) current;
1308 elements.insertElementAt(pop, 0);
1309 current = pop.getInvoker();
1310 } else if (current instanceof JMenu) {
1311 menu = (JMenu) current;
1312 elements.insertElementAt(menu, 0);
1313 current = menu.getParent();
1314 } else if (current instanceof JMenuBar) {
1315 bar = (JMenuBar) current;
1316 elements.insertElementAt(bar, 0);
1317 break;
1318 } else {
1319 break;
1320 }
1321 }
1322 MenuElement me[] = new MenuElement[elements.size()];
1323 elements.copyInto(me);
1324 return me;
1325 }
1326
1327
1328 /**
1329 * See <code>readObject</code> and <code>writeObject</code> in
1330 * <code>JComponent</code> for more
1331 * information about serialization in Swing.
1332 */
1333 private void writeObject(ObjectOutputStream s) throws IOException {
1334 s.defaultWriteObject();
1335 if (getUIClassID().equals(uiClassID)) {
1336 byte count = JComponent.getWriteObjCounter(this);
1337 JComponent.setWriteObjCounter(this, --count);
1338 if (count == 0 && ui != null) {
1339 ui.installUI(this);
1340 }
1341 }
1342 }
1454 }
1455
1456 /**
1457 * Get the AccessibleSelection associated with this object. In the
1458 * implementation of the Java Accessibility API for this class,
1459 * return this object, which is responsible for implementing the
1460 * AccessibleSelection interface on behalf of itself.
1461 *
1462 * @return this object
1463 */
1464 public AccessibleSelection getAccessibleSelection() {
1465 return this;
1466 }
1467
1468 /**
1469 * Returns 1 if a sub-menu is currently selected in this menu.
1470 *
1471 * @return 1 if a menu is currently selected, else 0
1472 */
1473 public int getAccessibleSelectionCount() {
1474 MenuElement me[] =
1475 MenuSelectionManager.defaultManager().getSelectedPath();
1476 if (me != null) {
1477 for (int i = 0; i < me.length; i++) {
1478 if (me[i] == JMenu.this) { // this menu is selected
1479 if (i+1 < me.length) {
1480 return 1;
1481 }
1482 }
1483 }
1484 }
1485 return 0;
1486 }
1487
1488 /**
1489 * Returns the currently selected sub-menu if one is selected,
1490 * otherwise null (there can only be one selection, and it can
1491 * only be a sub-menu, as otherwise menu items don't remain
1492 * selected).
1493 */
1494 public Accessible getAccessibleSelection(int i) {
1495 // if i is a sub-menu & popped, return it
1496 if (i < 0 || i >= getItemCount()) {
1497 return null;
1498 }
1499 MenuElement me[] =
1500 MenuSelectionManager.defaultManager().getSelectedPath();
1501 if (me != null) {
1502 for (int j = 0; j < me.length; j++) {
1503 if (me[j] == JMenu.this) { // this menu is selected
1504 // so find the next JMenuItem in the MenuElement
1505 // array, and return it!
1506 while (++j < me.length) {
1507 if (me[j] instanceof JMenuItem) {
1508 return (Accessible) me[j];
1509 }
1510 }
1511 }
1512 }
1513 }
1514 return null;
1515 }
1516
1517 /**
1518 * Returns true if the current child of this object is selected
1519 * (that is, if this child is a popped-up submenu).
1520 *
1521 * @param i the zero-based index of the child in this Accessible
1522 * object.
1523 * @see AccessibleContext#getAccessibleChild
1524 */
1525 public boolean isAccessibleChildSelected(int i) {
1526 // if i is a sub-menu and is pop-ed up, return true, else false
1527 MenuElement me[] =
1528 MenuSelectionManager.defaultManager().getSelectedPath();
1529 if (me != null) {
1530 JMenuItem mi = JMenu.this.getItem(i);
1531 for (int j = 0; j < me.length; j++) {
1532 if (me[j] == mi) {
1533 return true;
1534 }
1535 }
1536 }
1537 return false;
1538 }
1539
1540
1541 /**
1542 * Selects the <code>i</code>th menu in the menu.
1543 * If that item is a submenu,
1544 * it will pop up in response. If a different item is already
1545 * popped up, this will force it to close. If this is a sub-menu
1546 * that is already popped up (selected), this method has no
1547 * effect.
1548 *
1549 * @param i the index of the item to be selected
1550 * @see #getAccessibleStateSet
1551 */
1552 public void addAccessibleSelection(int i) {
1553 if (i < 0 || i >= getItemCount()) {
1554 return;
1555 }
1556 JMenuItem mi = getItem(i);
1557 if (mi != null) {
1558 if (mi instanceof JMenu) {
1559 MenuElement me[] = buildMenuElementArray((JMenu) mi);
1560 MenuSelectionManager.defaultManager().setSelectedPath(me);
1561 } else {
1562 MenuSelectionManager.defaultManager().setSelectedPath(null);
1563 }
1564 }
1565 }
1566
1567 /**
1568 * Removes the nth item from the selection. In general, menus
1569 * can only have one item within them selected at a time
1570 * (e.g. one sub-menu popped open).
1571 *
1572 * @param i the zero-based index of the selected item
1573 */
1574 public void removeAccessibleSelection(int i) {
1575 if (i < 0 || i >= getItemCount()) {
1576 return;
1577 }
1578 JMenuItem mi = getItem(i);
1579 if (mi != null && mi instanceof JMenu) {
1580 if (mi.isSelected()) {
1581 MenuElement old[] =
1582 MenuSelectionManager.defaultManager().getSelectedPath();
1583 MenuElement me[] = new MenuElement[old.length-2];
1584 for (int j = 0; j < old.length -2; j++) {
1585 me[j] = old[j];
1586 }
1587 MenuSelectionManager.defaultManager().setSelectedPath(me);
1588 }
1589 }
1590 }
1591
1592 /**
1593 * Clears the selection in the object, so that nothing in the
1594 * object is selected. This will close any open sub-menu.
1595 */
1596 public void clearAccessibleSelection() {
1597 // if this menu is selected, reset selection to only go
1598 // to this menu; else do nothing
1599 MenuElement old[] =
1600 MenuSelectionManager.defaultManager().getSelectedPath();
1601 if (old != null) {
1602 for (int j = 0; j < old.length; j++) {
1603 if (old[j] == JMenu.this) { // menu is in the selection!
1604 MenuElement me[] = new MenuElement[j+1];
1605 System.arraycopy(old, 0, me, 0, j);
1606 me[j] = JMenu.this.getPopupMenu();
1607 MenuSelectionManager.defaultManager().setSelectedPath(me);
1608 }
1609 }
1610 }
1611 }
1612
1613 /**
1614 * Normally causes every selected item in the object to be selected
1615 * if the object supports multiple selections. This method
1616 * makes no sense in a menu bar, and so does nothing.
1617 */
1618 public void selectAllAccessibleSelection() {
1619 }
1620 } // inner class AccessibleJMenu
1621
1622 }
|
1 /*
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1185 System.out.println("In JMenu.menuSelectionChanged to " + isIncluded);
1186 }
1187 setSelected(isIncluded);
1188 }
1189
1190 /**
1191 * Returns an array of <code>MenuElement</code>s containing the submenu
1192 * for this menu component. If popup menu is <code>null</code> returns
1193 * an empty array. This method is required to conform to the
1194 * <code>MenuElement</code> interface. Note that since
1195 * <code>JSeparator</code>s do not conform to the <code>MenuElement</code>
1196 * interface, this array will only contain <code>JMenuItem</code>s.
1197 *
1198 * @return an array of <code>MenuElement</code> objects
1199 */
1200 @BeanProperty(bound = false)
1201 public MenuElement[] getSubElements() {
1202 if(popupMenu == null)
1203 return new MenuElement[0];
1204 else {
1205 MenuElement[] result = new MenuElement[1];
1206 result[0] = popupMenu;
1207 return result;
1208 }
1209 }
1210
1211
1212 // implements javax.swing.MenuElement
1213 /**
1214 * Returns the <code>java.awt.Component</code> used to
1215 * paint this <code>MenuElement</code>.
1216 * The returned component is used to convert events and detect if
1217 * an event is inside a menu component.
1218 */
1219 public Component getComponent() {
1220 return this;
1221 }
1222
1223
1224 /**
1225 * Sets the <code>ComponentOrientation</code> property of this menu
1268 /**
1269 * Processes key stroke events such as mnemonics and accelerators.
1270 *
1271 * @param evt the key event to be processed
1272 */
1273 protected void processKeyEvent(KeyEvent evt) {
1274 MenuSelectionManager.defaultManager().processKeyEvent(evt);
1275 if (evt.isConsumed())
1276 return;
1277
1278 super.processKeyEvent(evt);
1279 }
1280
1281 /**
1282 * Programmatically performs a "click". This overrides the method
1283 * <code>AbstractButton.doClick</code> in order to make the menu pop up.
1284 * @param pressTime indicates the number of milliseconds the
1285 * button was pressed for
1286 */
1287 public void doClick(int pressTime) {
1288 MenuElement[] me = buildMenuElementArray(this);
1289 MenuSelectionManager.defaultManager().setSelectedPath(me);
1290 }
1291
1292 /*
1293 * Build an array of menu elements - from <code>PopupMenu</code> to
1294 * the root <code>JMenuBar</code>.
1295 * @param leaf the leaf node from which to start building up the array
1296 * @return the array of menu items
1297 */
1298 private MenuElement[] buildMenuElementArray(JMenu leaf) {
1299 Vector<MenuElement> elements = new Vector<>();
1300 Component current = leaf.getPopupMenu();
1301 JPopupMenu pop;
1302 JMenu menu;
1303 JMenuBar bar;
1304
1305 while (true) {
1306 if (current instanceof JPopupMenu) {
1307 pop = (JPopupMenu) current;
1308 elements.insertElementAt(pop, 0);
1309 current = pop.getInvoker();
1310 } else if (current instanceof JMenu) {
1311 menu = (JMenu) current;
1312 elements.insertElementAt(menu, 0);
1313 current = menu.getParent();
1314 } else if (current instanceof JMenuBar) {
1315 bar = (JMenuBar) current;
1316 elements.insertElementAt(bar, 0);
1317 break;
1318 } else {
1319 break;
1320 }
1321 }
1322 MenuElement[] me = new MenuElement[elements.size()];
1323 elements.copyInto(me);
1324 return me;
1325 }
1326
1327
1328 /**
1329 * See <code>readObject</code> and <code>writeObject</code> in
1330 * <code>JComponent</code> for more
1331 * information about serialization in Swing.
1332 */
1333 private void writeObject(ObjectOutputStream s) throws IOException {
1334 s.defaultWriteObject();
1335 if (getUIClassID().equals(uiClassID)) {
1336 byte count = JComponent.getWriteObjCounter(this);
1337 JComponent.setWriteObjCounter(this, --count);
1338 if (count == 0 && ui != null) {
1339 ui.installUI(this);
1340 }
1341 }
1342 }
1454 }
1455
1456 /**
1457 * Get the AccessibleSelection associated with this object. In the
1458 * implementation of the Java Accessibility API for this class,
1459 * return this object, which is responsible for implementing the
1460 * AccessibleSelection interface on behalf of itself.
1461 *
1462 * @return this object
1463 */
1464 public AccessibleSelection getAccessibleSelection() {
1465 return this;
1466 }
1467
1468 /**
1469 * Returns 1 if a sub-menu is currently selected in this menu.
1470 *
1471 * @return 1 if a menu is currently selected, else 0
1472 */
1473 public int getAccessibleSelectionCount() {
1474 MenuElement[] me =
1475 MenuSelectionManager.defaultManager().getSelectedPath();
1476 if (me != null) {
1477 for (int i = 0; i < me.length; i++) {
1478 if (me[i] == JMenu.this) { // this menu is selected
1479 if (i+1 < me.length) {
1480 return 1;
1481 }
1482 }
1483 }
1484 }
1485 return 0;
1486 }
1487
1488 /**
1489 * Returns the currently selected sub-menu if one is selected,
1490 * otherwise null (there can only be one selection, and it can
1491 * only be a sub-menu, as otherwise menu items don't remain
1492 * selected).
1493 */
1494 public Accessible getAccessibleSelection(int i) {
1495 // if i is a sub-menu & popped, return it
1496 if (i < 0 || i >= getItemCount()) {
1497 return null;
1498 }
1499 MenuElement[] me =
1500 MenuSelectionManager.defaultManager().getSelectedPath();
1501 if (me != null) {
1502 for (int j = 0; j < me.length; j++) {
1503 if (me[j] == JMenu.this) { // this menu is selected
1504 // so find the next JMenuItem in the MenuElement
1505 // array, and return it!
1506 while (++j < me.length) {
1507 if (me[j] instanceof JMenuItem) {
1508 return (Accessible) me[j];
1509 }
1510 }
1511 }
1512 }
1513 }
1514 return null;
1515 }
1516
1517 /**
1518 * Returns true if the current child of this object is selected
1519 * (that is, if this child is a popped-up submenu).
1520 *
1521 * @param i the zero-based index of the child in this Accessible
1522 * object.
1523 * @see AccessibleContext#getAccessibleChild
1524 */
1525 public boolean isAccessibleChildSelected(int i) {
1526 // if i is a sub-menu and is pop-ed up, return true, else false
1527 MenuElement[] me =
1528 MenuSelectionManager.defaultManager().getSelectedPath();
1529 if (me != null) {
1530 JMenuItem mi = JMenu.this.getItem(i);
1531 for (int j = 0; j < me.length; j++) {
1532 if (me[j] == mi) {
1533 return true;
1534 }
1535 }
1536 }
1537 return false;
1538 }
1539
1540
1541 /**
1542 * Selects the <code>i</code>th menu in the menu.
1543 * If that item is a submenu,
1544 * it will pop up in response. If a different item is already
1545 * popped up, this will force it to close. If this is a sub-menu
1546 * that is already popped up (selected), this method has no
1547 * effect.
1548 *
1549 * @param i the index of the item to be selected
1550 * @see #getAccessibleStateSet
1551 */
1552 public void addAccessibleSelection(int i) {
1553 if (i < 0 || i >= getItemCount()) {
1554 return;
1555 }
1556 JMenuItem mi = getItem(i);
1557 if (mi != null) {
1558 if (mi instanceof JMenu) {
1559 MenuElement[] me = buildMenuElementArray((JMenu) mi);
1560 MenuSelectionManager.defaultManager().setSelectedPath(me);
1561 } else {
1562 MenuSelectionManager.defaultManager().setSelectedPath(null);
1563 }
1564 }
1565 }
1566
1567 /**
1568 * Removes the nth item from the selection. In general, menus
1569 * can only have one item within them selected at a time
1570 * (e.g. one sub-menu popped open).
1571 *
1572 * @param i the zero-based index of the selected item
1573 */
1574 public void removeAccessibleSelection(int i) {
1575 if (i < 0 || i >= getItemCount()) {
1576 return;
1577 }
1578 JMenuItem mi = getItem(i);
1579 if (mi != null && mi instanceof JMenu) {
1580 if (mi.isSelected()) {
1581 MenuElement[] old =
1582 MenuSelectionManager.defaultManager().getSelectedPath();
1583 MenuElement[] me = new MenuElement[old.length-2];
1584 for (int j = 0; j < old.length -2; j++) {
1585 me[j] = old[j];
1586 }
1587 MenuSelectionManager.defaultManager().setSelectedPath(me);
1588 }
1589 }
1590 }
1591
1592 /**
1593 * Clears the selection in the object, so that nothing in the
1594 * object is selected. This will close any open sub-menu.
1595 */
1596 public void clearAccessibleSelection() {
1597 // if this menu is selected, reset selection to only go
1598 // to this menu; else do nothing
1599 MenuElement[] old =
1600 MenuSelectionManager.defaultManager().getSelectedPath();
1601 if (old != null) {
1602 for (int j = 0; j < old.length; j++) {
1603 if (old[j] == JMenu.this) { // menu is in the selection!
1604 MenuElement[] me = new MenuElement[j+1];
1605 System.arraycopy(old, 0, me, 0, j);
1606 me[j] = JMenu.this.getPopupMenu();
1607 MenuSelectionManager.defaultManager().setSelectedPath(me);
1608 }
1609 }
1610 }
1611 }
1612
1613 /**
1614 * Normally causes every selected item in the object to be selected
1615 * if the object supports multiple selections. This method
1616 * makes no sense in a menu bar, and so does nothing.
1617 */
1618 public void selectAllAccessibleSelection() {
1619 }
1620 } // inner class AccessibleJMenu
1621
1622 }
|