首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >componentListener致残

componentListener致残
EN

Stack Overflow用户
提问于 2014-03-06 23:42:11
回答 1查看 87关注 0票数 1

当mouseListener/Adapter检测到事件时,组件whenever /Adapter就会被禁用。在下面的代码中,componentMoved()方法覆盖完美地工作,直到mouseClicked()方法覆盖在MouseAdapter()中被触发。有什么办法解决这个问题吗?

代码语言:javascript
复制
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()方法的代码。

代码语言:javascript
复制
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的建议

代码语言:javascript
复制
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构造函数方法,以便在完成时正确地隐藏窗口:

代码语言:javascript
复制
    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)放置在其他任何地方会使窗口再次可见。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-07 01:02:21

while loop是危险的,Thread.sleep是危险的,处理是非常可怕的.

您违反了Swing和阻塞事件分派线程的单线程规则。

有关更多细节,请参见在Swing中并发

dispose可能正在处理与窗口相关联的本地对等程序,从而导致问题的无休止.

有关更多详细信息,请参阅JWindow#dispose

假设您试图在屏幕上/从屏幕上滑动窗口,您应该使用Swing Timer,当触发它时,它将更新窗口的位置,直到它到达目标点,而此时您只需更改窗口的可见性。这假设您希望重用窗口的实例。

有关更多详细信息,请参阅如何使用摆动计时器

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22238567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档