gpt4 book ai didi

java - 当 JTabbedPane 不再可见时,如何确保 JTabbedPane 的内容收到 ComponentEvent (componentHidden)

转载 作者:行者123 更新时间:2023-12-01 14:48:57 29 4
gpt4 key购买 nike

我有一个使用 JTabbedPane 来显示多个不同选项卡的应用程序。这些选项卡之一有一个正在运行的线程来显示其内容。我已经实现了一个 ComponentListener 来在选项卡不可见时停止线程。我可以看到线程在选择选项卡时变得活跃,并在变得不可见时停止,正如预期的那样。

如果我在未选择带有线程的选项卡时关闭应用程序,则一切都会顺利并且应用程序将关闭。如果我在带有线程的选项卡可见时关闭应用程序,则选项卡不会收到 ComponentEvent,因此线程保持 Activity 状态,我需要手动终止应用程序(使用 Eclipse 控制台上的“终止”按钮)。

我不喜欢使用 System.exit() 方法来关闭我的应用程序,而是停止所有线程并处置所有窗口。这就像一个魅力,除了这个带有线程的选项卡。

在处置我的窗口或removeAll()之前,我已经尝试将 JTabbedPane 设置为不可见。两者都没有达到预期的结果。 removeAll() 甚至有相反的结果。如果选项卡未处于 Activity 状态,它将收到一个 ComponentEvent 来指示该选项卡已变得可见(componentShown)(实际上,所有选项卡都会依次收到该事件,但没有一个选项卡会收到 componentHidden)。

显然,当我通过文件菜单关闭窗口(我对此有一些控制权并且我已经测试了removeAll和setVisible(false)方法)以及窗口被处置时,线程都应该停止,因为用户单击窗口角的十字。

更新

我找到了一种方法,可以使似乎导致问题的线程按照建议作为守护线程运行。然而,这导致了一个意想不到的问题。启动有问题线程的类是我正在使用的 JUNG 软件包中的 VisRunner 类。它包含一个方法“relax”,在该方法中启动线程。

  @Override
public void relax() {
// in case its running
stop();
stop = false;
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}

我已经创建了 MyVisRunner 类:

import edu.uci.ics.jung.algorithms.layout.util.VisRunner;
import edu.uci.ics.jung.algorithms.util.IterativeContext;

public class MyVisRunner extends VisRunner {

public MyVisRunner(final IterativeContext process) {
super(process);
}

@Override
public void relax() {
// in case it's running
Log.d("Relaxing");
stop();
stop = false;
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
thread.setDaemon(true);
thread.start();
}
}

我这样加载松弛器:

  visModel = new DefaultVisualizationModel<>(layout);
visModel.setRelaxer(new MyVisRunner(layout));

我本来希望这能解决问题,但它只会加剧问题。当我现在启动我的软件时,它不会停止,即使有问题的选项卡甚至不可见(选项卡已构建,但不可见)。在这种情况下,MyVisRunner 中的relax 方法甚至还没有被调用;该线程未在 VisRunner 类中的其他任何地方初始化。注释掉 setRelaxer 行将解决这个额外的问题(显然保留了原始问题)。

更新2

我终于解决了这个问题。我没有意识到当我设置自己的放松器时,已经有一个放松器在运行。我已将代码调整为:

  visModel = new DefaultVisualizationModel<>(layout);
visModel.getRelaxer().stop();
visModel.setRelaxer(new MyVisRunner(layout));

这解决了额外的问题以及我原来的问题。

最佳答案

您应该将线程设置为守护线程:

myThread.setDaemon(true);

如果不再有正在运行的非守护进程线程,虚拟机将终止。

<小时/>

顺便说一句,您可以在 JFrame 上为 windowClosing 事件添加 WindowListener

关于java - 当 JTabbedPane 不再可见时,如何确保 JTabbedPane 的内容收到 ComponentEvent (componentHidden),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15084387/

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