AccessibleJMenu 中的 AccessibleSelection 在鼠标更改 JMenu 后返回
The AccessibleSelection in a AccessibleJMenu is returning after the mouse changes JMenu
问题底部的代码为我需要单击 JMenu
的相当具体的情况提供了解决方案,它应该像 JButton
一样工作,同时保持几乎所有JMenu
的格式。 ActionMenu
和 JMenu
之间的格式差异应该是在单击后,它应该 return 到其正常状态(见图)。
使用当前代码,它可以做到这一点。然而;如果您要将鼠标移到不同的菜单上,或者如果您将鼠标 down/up 移出菜单然后将鼠标悬停在它上面,菜单将进入其选定状态(见图)。这不应该发生。
我的问题是为什么在 AccessibleSelection
被清除并且 PopupMenu
被设置为不可见之后会发生这种情况?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
public class Main extends JFrame {
private static final long serialVersionUID = 3206847208968227199L;
private Main() {
setSize(600, 600);
setJMenuBar(new MenuBar());
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Main();
}
private class MenuBar extends JMenuBar {
private static final long serialVersionUID = -2055260049565317972L;
MenuBar() {
add(new ActionMenu("Menu"));
add(new JMenu("Another Menu"));
}
}
private class ActionMenu extends JMenu {
private static final long serialVersionUID = -6885806048559452542L;
public ActionMenu(String name) {
setText(name);
menuItem();
}
JButton butInvis;
private void menuItem() {
butInvis = new JButton();
butInvis.addActionListener(new MenuActionListener());
addMouseListener(new MenuMouseListener());
}
private class MenuMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
clcikComponent(butInvis);
}
private void clcikComponent(JButton comp) {
comp.doClick();
}
}
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
AccessibleJMenu aJ = (AccessibleJMenu) getAccessibleContext();
aJ.clearAccessibleSelection();
getPopupMenu().setVisible(false);
}
}
}
}
编辑
我忘了说原来我是在 JMenu
上用 setSelected(false)
做的(见下面的代码);但是,当您将鼠标悬停在另一个 JMenu
.
上时,这会导致完全相同的问题
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
setSelected(false);
}
}
要解决此问题,您需要使用 JMenuBar
的 AccessibleContext
而不是 JMenu
。这可以用代码行完成
getParent().getAccessibleContext().getAccessibleSelection().clearAccessibleSelection();
在这个例子中,代码将放在 MenuActionListener
中,它看起来像下面的代码。
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
getParent().getAccessibleContext().getAccessibleSelection().clearAccessibleSelection();
}
}
如 Andrew Thompson, this should not be done because of the Principle of Least Astonishment 所述,除非您要更改组件的格式(本例中为 Action Menu
),使其看起来不像另一个组件。
问题底部的代码为我需要单击 JMenu
的相当具体的情况提供了解决方案,它应该像 JButton
一样工作,同时保持几乎所有JMenu
的格式。 ActionMenu
和 JMenu
之间的格式差异应该是在单击后,它应该 return 到其正常状态(见图)。
使用当前代码,它可以做到这一点。然而;如果您要将鼠标移到不同的菜单上,或者如果您将鼠标 down/up 移出菜单然后将鼠标悬停在它上面,菜单将进入其选定状态(见图)。这不应该发生。
我的问题是为什么在 AccessibleSelection
被清除并且 PopupMenu
被设置为不可见之后会发生这种情况?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
public class Main extends JFrame {
private static final long serialVersionUID = 3206847208968227199L;
private Main() {
setSize(600, 600);
setJMenuBar(new MenuBar());
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Main();
}
private class MenuBar extends JMenuBar {
private static final long serialVersionUID = -2055260049565317972L;
MenuBar() {
add(new ActionMenu("Menu"));
add(new JMenu("Another Menu"));
}
}
private class ActionMenu extends JMenu {
private static final long serialVersionUID = -6885806048559452542L;
public ActionMenu(String name) {
setText(name);
menuItem();
}
JButton butInvis;
private void menuItem() {
butInvis = new JButton();
butInvis.addActionListener(new MenuActionListener());
addMouseListener(new MenuMouseListener());
}
private class MenuMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
clcikComponent(butInvis);
}
private void clcikComponent(JButton comp) {
comp.doClick();
}
}
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
AccessibleJMenu aJ = (AccessibleJMenu) getAccessibleContext();
aJ.clearAccessibleSelection();
getPopupMenu().setVisible(false);
}
}
}
}
编辑
我忘了说原来我是在 JMenu
上用 setSelected(false)
做的(见下面的代码);但是,当您将鼠标悬停在另一个 JMenu
.
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
setSelected(false);
}
}
要解决此问题,您需要使用 JMenuBar
的 AccessibleContext
而不是 JMenu
。这可以用代码行完成
getParent().getAccessibleContext().getAccessibleSelection().clearAccessibleSelection();
在这个例子中,代码将放在 MenuActionListener
中,它看起来像下面的代码。
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
getParent().getAccessibleContext().getAccessibleSelection().clearAccessibleSelection();
}
}
如 Andrew Thompson, this should not be done because of the Principle of Least Astonishment 所述,除非您要更改组件的格式(本例中为 Action Menu
),使其看起来不像另一个组件。