Bor*_*oro 13 java swing listener
我试图抓住屏幕上显示组件的第一时刻,而不使用"脏"解决方案,就像使用计时器一样.基本上,我想知道我可以安全地开始getLocationOnScreen()在组件上使用方法的那一刻.
我认为组件监听器可以帮助但在这里没有运气.我现在卡住了,不知道哪个听众可以使用.有什么建议?
下面是一些示例代码,显示组件侦听器失败.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CompListenerTest
{
static ComponentListener cL = new ComponentAdapter()
{
@Override
public void componentShown(ComponentEvent e)
{
super.componentShown(e);
System.out.println("componentShown");
}
};
static MouseListener mL = new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
super.mousePressed(e);
JComponent c = (JComponent) e.getSource();
System.out.println("mousePressed c="+c.isShowing());
}
};
public static void main(String[] args)
{
JPanel p = new JPanel();
p.setPreferredSize(new Dimension(300, 400));
p.setBackground(Color.GREEN);
p.addComponentListener(cL);
p.addMouseListener(mL);
System.out.println("initial test p="+p.isShowing());
JPanel contentPane = new JPanel();
contentPane.setBackground(Color.RED);
contentPane.add(p);
JFrame f = new JFrame();
f.setContentPane(contentPane);
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
kle*_*tra 15
ComponentListener不起作用的原因是它报告对visible属性的更改 - 默认情况下也是如此,即使不是组件层次结构的一部分也是如此.
要可靠地通知,请使用HierarchyListener
第一:主题中提出的问题不一定与实际问题有关(如下面Boro评论的那样 - 任何链接到评论的方式?):没有必要保留某种本地标志来决定它是否存在将getLocationOnScreen发送到组件是安全的,只需询问组件本身.为自己学习项目1 :-)
第二:问的问题非常有趣.五位专家(包括我自己,自称),五个不同的答案.这引发了我的一些挖掘.
我的假设:ComponentEvents对于(first-)显示的通知没有用.我知道componentShown是无用的,因为它是一种propertyChange通知组件的可见属性(很少改变).但是,对于移动/调整大小的建议用途感到困惑.
构建用例:在示例中完全准备框架并为以后显示做好准备,这是提高感知性能的典型方法.我的预测 - 基于我的假设:在准备时调整大小/移动,在显示时没有任何东西(注意:isShowing是我们所追求的,也就是后者).在OP的示例中添加的片段:
final JFrame f = new JFrame();
f.setContentPane(contentPane);
f.setSize(800, 600);
// f.pack();
JFrame controller = new JFrame("opener");
controller.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Action open = new AbstractAction("open/hide second") {
@Override
public void actionPerformed(ActionEvent e) {
f.setVisible(!f.isVisible());
}
};
controller.add(new JButton(open));
controller.pack();
controller.setVisible(true);
Run Code Online (Sandbox Code Playgroud)
失望:在准备时没有通知,在展会时间通知,只是在需要时,我的假设似乎错了;-)最后一次机会:交换setSize一包......瞧,准备时通知,没有通知演出时间,再次开心我.播放更多:如果一个组件是可显示的,看起来会触发ComponentEvents,这在某些情况下可能有用,也可能没有用,但如果显示的是我们所处的状态则不会.该
新的帝国规则(草案):
不要使用ComponentListener来通知"显示".这是从AWT时代遗留下来的.
请使用AncestorListener.这似乎是Swing替换,有点误导的"添加"通知实际上意味着"显示"
只有在真正对细粒度状态变化感兴趣时才使用HierarchyListener