【发布时间】:2014-03-06 23:42:11
【问题描述】:
我遇到了一个不寻常的问题,即每当 mouseListener/Adapter 检测到事件时,componentListener/Adapter 就会被禁用。在下面的代码中,componentMoved() 方法覆盖可以完美运行,直到在MouseAdapter() 中触发了mouseClicked() 方法覆盖。任何想法如何解决这个问题?
public AlertScroller(String msg,Color col) {
addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
setShape(new Rectangle2D.Double(0, 0, getWidth(), newHeight));
if(!isVisible())
setVisible(true);
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent click) {
if(SwingUtilities.isLeftMouseButton(click)) {
autoClear = false;
scrollOff();
}
}
});
setAlwaysOnTop(true);
JPanel panel = new JPanel();
panel.setBorder(compound);
panel.setBackground(col);
JLabel imgLbl = new JLabel(msg);
imgLbl.setFont(new Font("Arial",Font.BOLD,30));
panel.add(imgLbl);
setContentPane(panel);
pack();
}
这个方法所在的类扩展了JWindow。
编辑:添加了scrollOff() 方法的代码。
public void scrollOff() {
Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
int taskBar = scnMax.bottom;
int x = screenSize.width - getWidth();
int yEnd = screenSize.height - taskBar;
int yStart = this.getBounds().y;
setLocation(x,yStart);
int current = yStart;
newHeight = this.getBounds().height;
while(current < yEnd) {
current+=2;
newHeight = yEnd - current;
setLocation(x,current);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
dispose();
Main.alertControl.setAlertActive(false);
}
这基本上与 scrollOn() 方法完全相反,只要它是通过Listener 以外的任何方式触发的,它就可以正常工作。
编辑 2:感谢 MadProgrammer 的建议,修复了以下代码
public void scrollOff() {
x = screenSize.width - getWidth();
yEnd = screenSize.height - taskBar;
yStart = this.getBounds().y;
setLocation(x,yStart);
current = yStart;
newHeight = this.getBounds().height;
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
if(current < yEnd) {
current+=2;
newHeight = yEnd - current;
setLocation(x,current);
} else {
timer.stop();
}
}
};
timer = new Timer(30, action);
timer.setInitialDelay(0);
timer.start();
Main.alertControl.setAlertActive(false);
}
我还用else if 更新了AlertScroller() 构造方法,以便在完成后正确隐藏窗口:
addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
setShape(new Rectangle2D.Double(0, 0, getWidth(), newHeight));
if(!isVisible())
setVisible(true);
else if(getBounds().y == screenSize.height - taskBar)
setVisible(false);
}
});
将setVisible(false) 放在其他任何地方都会导致窗口再次可见。
【问题讨论】:
-
方法
scrollOff()的代码是什么? -
添加了
scrollOff()代码。但请注意;当由其他侦听器以外的任何东西触发时,此方法可以正常工作 -
while循环很危险,Thread.sleep很危险,dispose很可怕……你违反了 Swing 的单线程规则。dispose可能正在处理与窗口关联的本机对等方,导致问题无止境... -
@MadProgrammer:想解释一下我如何正确地做到这一点?我还在学习 Java,所以我不确定这样做的“正确”方法。
-
假设,您正试图在屏幕上/关闭窗口滑动,您应该使用 Swing
Timer,当触发时,它将更新窗口的位置,直到它到达它的目标点并且什么时候你会简单地改变窗口的可见性。这假设您要重用窗口的实例...
标签: java swing mouselistener jwindow componentlistener