请教怎么获得 容器或组件 区域外的鼠标事件? 本帖最后由 houguojun 于 2011-12-14 19:54:53 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用 getParent() 获得所有 Container,加上 addMouseListener() 多数地方是可以,但是不是JComboBox那个效果。比如JFame的工具栏,不是Parent树上的,在那些地方就处理不了。跪求高手! addFocusListener(new FocusAdapter(){ public void focusLost(FocusEvent e){ hidePopup();}}); addAncestorListener(new AncestorListener(){ public void ancestorAdded(AncestorEvent event){ hidePopup();} public void ancestorMoved(AncestorEvent event){ if (event.getSource() != popup) hidePopup();} public void ancestorRemoved(AncestorEvent event){hidePopup();}}); 多谢楼上2位,2位的一起加上,也只能处理焦点丢失\祖先移动等情况.还是没有JComboBox的效果.仍然无法处理区域外鼠标点击\或鼠标滚轮滚动的事件 swing设计的监听模型应该是基于面向对象的理念监听有一个监听对象,监听对象发生了xx事件,比如发生在监听对象UI范围内或或监听对象相关的事件才能被监听到它的监听模型就是这样建立的,在此模型下,除此以外无法直接监控。除非去监听区域外事件发生的相关对象,非swing组件的话,要牵涉到底层系统的事件监听,这个没试过,有兴趣可以研究一下。 钩子没有移植性这2天看了很多Java底层文档,比如快捷键,系统有一个对象监听,可惜没有看到鼠标的。JComboBox的弹出部分是JPopupMenu,这个源代码看100次也没有收获,但是,事实是它就处理了它本身之外的鼠标事件。JPopupMenu鼠标移出本身区域,没有隐藏,即不是监听了鼠标移出事件。继续跪求高手点解! 为什么要考虑Java的可移植性?你的软件有多大的几率在Linux下跑?考虑80%的市场行为就行了。不要为了跨平台而跨平台。 Swing的我不熟悉,SWT的不用hook也能实现,因为有个全局处理消息的Display类,能得到所有的系统消息,在上面加一个filter就OK了。 都是为了好看,唉!其实现在就是弹出一个JDialog还不是一样用。我是想,人家swing的JPopup都做了,学习下长点见识也不错嘛。不想一脚踏进了个深渊,悲剧! 我觉得纯java是肯定可以实现的,你应该对swing的事件处理机制还没掌握透彻。我自己就用swt实现了一套自定义的Toolbar, Menubar,PopupMenu.http://feeling.sf.net/images/1.jpg 你看过Popup这个类的实现没?我觉得很简单啊。 在看,没有发现我说的问题。我在想,是不是还是做的一个FocusLost。 不过这个类是 HeavyWeightWindow ,依赖于底层系统的实现,有些东西没有暴露出来。 实际上不需要你知道鼠标发生什么事件,这个popup比较特殊,它知道什么时候需要自动关闭,实际上这个是操作系统来控制的,这是个重量级的控件。 还有你会debug吗?在 JPopupMenu 里面 设置一些断点,你能看到非常有用的事件信息。JPopupMenu应该给你提供了足够有用的东西。 Popup.hide()里设置了断点,什么也没有发生,555 BasicPopupMenuUI static class MouseGrabber implements ChangeListener, AWTEventListener, ComponentListener, WindowListener stateChangedcancelPopupMenu line 828MouseGrabber.cancelPopupMenu line 855要下班了,记个笔记。 我的天,饶了天大一个弯,弹一个JPopupMenu,效果就出来了,只是布局还有些问题。有希望了! 可以参考swing hacks这本书第十个Hack 10. Building a Drop-Down Menu Button 终于搞定了,核心就是重写JPopupMenu的setVisible。我把代码贴出来,大家给我指点指点。代码还有一个事情没有处理,就是在区域里面滚动鼠标hide popup,休息休息加上去。 public class Box extends JLabel implements MouseListener { private boolean msIsIn = false; private final JComponent owner = this; private final JPanel panel = new JPanel(); private PopupMenu pm = new PopupMenu(); public Box() { this.setBackground(Color.white); this.setBorder(new LineBorder(new Color(153, 180, 209), 1, true)); this.setText("text"); this.addMouseListener(this); panel.setBorder(new LineBorder(new Color(153, 180, 209), 1, true)); panel.setBackground(Color.white); panel.addMouseListener(this); } @Override public void mouseClicked(MouseEvent e) { Object o = e.getSource(); if (o == this) { if (!pm.isVisible()) { pm.setVisible(true); } else { msIsIn = false; pm.setVisible(false); } msIsIn = true; } } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { Object o = e.getSource(); if (o == this || o == panel) { msIsIn = true; } } @Override public void mouseExited(MouseEvent e) { Object o = e.getSource(); if (o == this || o == panel) { msIsIn = false; } } class Popup { JWindow window = null; Popup() { Window parent = SwingUtilities.getWindowAncestor(owner); window = new JWindow(parent); window.getContentPane().setBackground(Color.white); window.getContentPane().setLayout(new BorderLayout()); Point p = owner.getLocationOnScreen(); p.y += owner.getSize().height; window.setLocation(p); window.setSize(300, 400); window.getContentPane().add(panel, BorderLayout.CENTER); } void show() { window.setVisible(true); } void hide() { window.setVisible(false); window.dispose(); } } class PopupMenu extends JPopupMenu { transient Popup popup; PopupMenu() { super(null); setInvoker(owner); } public void setVisible(boolean b) { // Is it a no-op? if (b == isVisible()) return; System.out.printf("setVisible: [%s,%s]\n", b, msIsIn); // if closing, first close all Submenus if (b == false && !msIsIn) { Boolean doCanceled = (Boolean) getClientProperty("JPopupMenu.firePopupMenuCanceled"); if (doCanceled != null && doCanceled == Boolean.TRUE) { putClientProperty("JPopupMenu.firePopupMenuCanceled", Boolean.FALSE); firePopupMenuCanceled(); } getSelectionModel().clearSelection(); } else { // 这里使得mouse在区域外发送了setVisible(false); if (isPopupMenu()) { MenuElement me[] = new MenuElement[1]; me[0] = (MenuElement) this; MenuSelectionManager.defaultManager().setSelectedPath(me); } } if (b) { firePopupMenuWillBecomeVisible(); popup = getPopup(); firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE); } else if (popup != null && !msIsIn) { firePopupMenuWillBecomeInvisible(); popup.hide(); popup = null; firePropertyChange("visible", Boolean.TRUE, Boolean.FALSE); if (isPopupMenu()) { MenuSelectionManager.defaultManager().clearSelectedPath(); } } } private Popup getPopup() { Popup oldPopup = popup; if (oldPopup != null) { oldPopup.hide(); } Popup newPopup = new Popup(); newPopup.show(); return newPopup; } public boolean isVisible() { return popup != null; } private boolean isPopupMenu() { Component invoker = super.getInvoker(); return ((invoker != null) && !(invoker instanceof JMenu)); } }} 求jacorb的使用和作用 求介绍一本JAVA入门书籍 【高手指教】不同引用指向同一对象该怎样理解(举个例子吧)? 总结了一些日期时间常用的方法,做为自己的工具类很适用. 使用ArrayList时遇到问题, 有人问我这个问题我解释错了,请大家帮忙解释一下 可以在jb2005中使用最新的J2SE5.0吗? tomcat配置的迷茫 java操作word jacob 怎么输出艺术字 求指导 jsp 小问! 上传时候,如何判断图片宽高 问个线程结束的问题高人们解答下吧
加上 addMouseListener() 多数地方是可以,但是不是JComboBox那个效果。
比如JFame的工具栏,不是Parent树上的,在那些地方就处理不了。跪求高手!
public void ancestorAdded(AncestorEvent event){ hidePopup();}
public void ancestorMoved(AncestorEvent event){ if (event.getSource() != popup) hidePopup();}
public void ancestorRemoved(AncestorEvent event){hidePopup();}
});
监听有一个监听对象,监听对象发生了xx事件,比如发生在监听对象UI范围内或或监听对象相关的事件才能被监听到
它的监听模型就是这样建立的,在此模型下,除此以外无法直接监控。除非去监听区域外事件发生的相关对象,非swing组件的话,要牵涉到底层系统的事件监听,这个没试过,有兴趣可以研究一下。
这2天看了很多Java底层文档,比如快捷键,系统有一个对象监听,可惜没有看到鼠标的。JComboBox的弹出部分是JPopupMenu,这个源代码看100次也没有收获,但是,事实是它就处理了它本身之外的鼠标事件。
JPopupMenu鼠标移出本身区域,没有隐藏,即不是监听了鼠标移出事件。继续跪求高手点解!
其实现在就是弹出一个JDialog还不是一样用。
我是想,人家swing的JPopup都做了,学习下长点见识也不错嘛。
不想一脚踏进了个深渊,悲剧!
static class MouseGrabber implements ChangeListener,
AWTEventListener, ComponentListener, WindowListener
stateChanged
cancelPopupMenu line 828
MouseGrabber.cancelPopupMenu line 855
要下班了,记个笔记。
我的天,饶了天大一个弯,弹一个JPopupMenu,效果就出来了,只是布局还有些问题。有希望了!
我把代码贴出来,大家给我指点指点。
代码还有一个事情没有处理,就是在区域里面滚动鼠标hide popup,休息休息加上去。
public class Box extends JLabel implements MouseListener {
private boolean msIsIn = false; private final JComponent owner = this;
private final JPanel panel = new JPanel();
private PopupMenu pm = new PopupMenu(); public Box() {
this.setBackground(Color.white);
this.setBorder(new LineBorder(new Color(153, 180, 209), 1, true));
this.setText("text");
this.addMouseListener(this); panel.setBorder(new LineBorder(new Color(153, 180, 209), 1, true));
panel.setBackground(Color.white);
panel.addMouseListener(this);
} @Override
public void mouseClicked(MouseEvent e) {
Object o = e.getSource();
if (o == this) {
if (!pm.isVisible()) {
pm.setVisible(true);
} else {
msIsIn = false;
pm.setVisible(false);
}
msIsIn = true;
}
} @Override
public void mousePressed(MouseEvent e) {
} @Override
public void mouseReleased(MouseEvent e) {
} @Override
public void mouseEntered(MouseEvent e) {
Object o = e.getSource();
if (o == this || o == panel) {
msIsIn = true;
}
} @Override
public void mouseExited(MouseEvent e) {
Object o = e.getSource();
if (o == this || o == panel) {
msIsIn = false;
}
} class Popup {
JWindow window = null; Popup() {
Window parent = SwingUtilities.getWindowAncestor(owner);
window = new JWindow(parent);
window.getContentPane().setBackground(Color.white);
window.getContentPane().setLayout(new BorderLayout());
Point p = owner.getLocationOnScreen();
p.y += owner.getSize().height;
window.setLocation(p);
window.setSize(300, 400);
window.getContentPane().add(panel, BorderLayout.CENTER);
} void show() {
window.setVisible(true);
} void hide() {
window.setVisible(false);
window.dispose();
}
} class PopupMenu extends JPopupMenu {
transient Popup popup; PopupMenu() {
super(null);
setInvoker(owner);
}
public void setVisible(boolean b) {
// Is it a no-op?
if (b == isVisible())
return;
System.out.printf("setVisible: [%s,%s]\n", b, msIsIn); // if closing, first close all Submenus
if (b == false && !msIsIn) {
Boolean doCanceled = (Boolean) getClientProperty("JPopupMenu.firePopupMenuCanceled");
if (doCanceled != null && doCanceled == Boolean.TRUE) {
putClientProperty("JPopupMenu.firePopupMenuCanceled", Boolean.FALSE);
firePopupMenuCanceled();
}
getSelectionModel().clearSelection(); } else {
// 这里使得mouse在区域外发送了setVisible(false);
if (isPopupMenu()) {
MenuElement me[] = new MenuElement[1];
me[0] = (MenuElement) this;
MenuSelectionManager.defaultManager().setSelectedPath(me);
}
}
if (b) {
firePopupMenuWillBecomeVisible();
popup = getPopup();
firePropertyChange("visible", Boolean.FALSE, Boolean.TRUE);
} else if (popup != null && !msIsIn) {
firePopupMenuWillBecomeInvisible();
popup.hide();
popup = null;
firePropertyChange("visible", Boolean.TRUE, Boolean.FALSE);
if (isPopupMenu()) {
MenuSelectionManager.defaultManager().clearSelectedPath();
}
}
} private Popup getPopup() {
Popup oldPopup = popup;
if (oldPopup != null) {
oldPopup.hide();
}
Popup newPopup = new Popup();
newPopup.show();
return newPopup;
} public boolean isVisible() {
return popup != null;
} private boolean isPopupMenu() {
Component invoker = super.getInvoker();
return ((invoker != null) && !(invoker instanceof JMenu));
} }}