gpt4 book ai didi

java - componentListener 被禁用

转载 作者:行者123 更新时间:2023-11-29 05:27:20 25 4
gpt4 key购买 nike

我有一个不寻常的问题,每当 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) 放在其他任何地方都会导致窗口再次可见。

最佳答案

while 循环 是危险的,Thread.sleep 是危险的,而 dispose 是非常可怕的......

您违反了 Swing 的单线程规则并阻塞了事件调度线程。

参见 Concurrency in Swing了解更多详情

dispose 可能正在处理与窗口关联的 native 对等点,导致问题无休止...

参见 JWindow#dispose了解更多详情。

假设,您正试图将窗口滑动到屏幕上/关闭屏幕,您应该使用 Swing Timer,当它被触发时,会更新窗口的位置,直到它到达它的目标点,并且哪一次您只需更改窗口的可见性。这假定您要重用窗口的实例..

参见 How to Use Swing Timers了解更多详情。

关于java - componentListener 被禁用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22238567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com