当mouseListener/Adapter检测到事件时,组件whenever /Adapter就会被禁用。在下面的代码中,componentMoved()方法覆盖完美地工作,直到mouseClicked()方法覆盖在MouseAdapter()中被触发。有什么办法解决这个问题吗?
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);
}我还用一个AlertScroller()更新了else if构造函数方法,以便在完成时正确地隐藏窗口:
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)放置在其他任何地方会使窗口再次可见。
发布于 2014-03-07 01:02:21
while loop是危险的,Thread.sleep是危险的,处理是非常可怕的.
您违反了Swing和阻塞事件分派线程的单线程规则。
有关更多细节,请参见在Swing中并发
dispose可能正在处理与窗口相关联的本地对等程序,从而导致问题的无休止.
有关更多详细信息,请参阅JWindow#dispose。
假设您试图在屏幕上/从屏幕上滑动窗口,您应该使用Swing Timer,当触发它时,它将更新窗口的位置,直到它到达目标点,而此时您只需更改窗口的可见性。这假设您希望重用窗口的实例。
有关更多详细信息,请参阅如何使用摆动计时器。
https://stackoverflow.com/questions/22238567
复制相似问题