gpt4 book ai didi

java - 将 JWindow 用于 float 工具窗口会导致所有者窗口在单击 float 窗口时变为 "flicker"

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:34:51 25 4
gpt4 key购买 nike

背景资料

我想在 Swing 中使用 Java 版本 1.6.0_26 构建一个工具/调色板窗口(也称为“ float ”窗口)。我认为 JWindow 是最佳选择,并且 Swing 文档指出将 JWindow 用于此类目的( float 窗口,它有一个所有者框架,没有装饰,也没有窗口任务栏条目)。

我的 float 工具窗口的内容由几个其他组件组成,例如 JButtons 和 JTextFields。

问题

当我单击 float 工具窗口时,所有者窗口(JFrame,我的“主应用程序窗口”)偶尔会“闪烁”。 “闪烁”看起来像所有者窗口在几毫秒内失去焦点,然后又重新获得焦点,从而导致非常快速地禁用/启用窗口(请注意,没有窗口事件被触发,如焦点丢失或窗口-停用)。

我已经在 Windows 7 64 位和 Windows XP 下对此进行了测试。

视频和示例代码

为了澄清问题(有点难解释),我拍了一段视频,你可以看到当我反复点击 float 工具窗口时所有者窗口的“闪烁”:

我还整理了一个简单的示例代码来重现问题(视频中使用了此代码):

import java.awt.*;
import javax.swing.*;

public class JWindowFlickerExample
{
public JWindowFlickerExample()
{
// I know swing code should be executed on the EDT,
// just wanted to keep it simple

// Create and show the "main application window"
JFrame frame = new JFrame( getClass().getSimpleName() );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setSize( 640, 480 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );

// Create and show the "floating tool window"
MyFloatingToolWindow testWindow = new MyFloatingToolWindow( frame );
testWindow.setLocation( 400, 400 );
testWindow.setVisible( true );
}

public static void main( String[] args )
{
new JWindowFlickerExample();
}

@SuppressWarnings( "serial" )
private class MyFloatingToolWindow extends JWindow
{
public MyFloatingToolWindow( Window hostWindow )
{
super( hostWindow );

// setFocusableWindowState( false );
setSize( 300, 400 );
setLayout( null );
getContentPane().setBackground( Color.LIGHT_GRAY );

JTextField textField = new JTextField();
textField.setLocation( 50, 50 );
textField.setSize( 70, 30 );

add( textField );
}
}
}

到目前为止的进展

我还尝试将 float 工具窗口的“Window.setFocusableWindowState”设置为 false。如果是假的,就没有“闪烁”,问题就没有了。该方法的 JavaDoc 指出:

Setting a Window's focusability state to false is the standard mechanism for an application to identify to the AWT a Window which will be used as a floating palette or toolbar, and thus should be a non-focusable Window."

但是我当然不能在 float 工具窗口中使用 JTextField,因为我无法聚焦它(也许 float 工具窗口中的文本字段不常见,但在我的情况下是必须的)。

我猜“闪烁”效果在某种程度上与焦点管理有关……在几分之一秒内, float 工具窗口获得焦点,将其从所有者窗口移开然后返回。但我不确定;作为旁注:如果 float 工具窗口中的文本字段具有焦点,则所有者窗口保持启用状态(这是正确的行为)。

我希望有一个简单的解决方案,这样我就可以将 JWindow 作为我的 float 工具窗口,并将文本字段作为其内容 - 因为,除了所描述的“闪烁”问题之外,一切都很好。

非常感谢任何帮助,非常感谢!

最佳答案

此代码变体是否显示相同的问题? (注意:在开始更改之前,我没有看到任何明显的闪烁。)

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class JWindowFlickerExample
{
public JWindowFlickerExample()
{
// I know swing code should be executed on the EDT,
// just wanted to keep it simple
// SOMETIMES 'KEEPING IT SIMPLE' CAN CAUSE THE PROBLEM!

SwingUtilities.invokeLater( new Runnable() {
public void run() {
// Create and show the "main application window"
JFrame frame = new JFrame( getClass().getSimpleName() );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.pack();
frame.setSize( 640, 480 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );

// Create and show the "floating tool window"
MyFloatingToolWindow testWindow = new MyFloatingToolWindow( frame );
testWindow.setLocation( 400, 400 );
testWindow.setVisible( true );
}
});
}

public static void main( String[] args )
{
new JWindowFlickerExample();
}

@SuppressWarnings( "serial" )
private class MyFloatingToolWindow extends JWindow
{
public MyFloatingToolWindow( Window hostWindow )
{
super( hostWindow );

JTextField textField = new JTextField(20);

JPanel p = new JPanel(new GridLayout());
p.setBackground( Color.GREEN );
p.setBorder(new EmptyBorder(40,40,40,40));
p.add(textField);
add( p );

pack();
}
}
}

关于java - 将 JWindow 用于 float 工具窗口会导致所有者窗口在单击 float 窗口时变为 "flicker",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9241711/

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