Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将JWindow用于浮动工具窗口会导致所有者窗口;闪烁“;在浮动窗口中单击时 背景资料_Java_Swing_Focus_Flicker_Jwindow - Fatal编程技术网

Java 将JWindow用于浮动工具窗口会导致所有者窗口;闪烁“;在浮动窗口中单击时 背景资料

Java 将JWindow用于浮动工具窗口会导致所有者窗口;闪烁“;在浮动窗口中单击时 背景资料,java,swing,focus,flicker,jwindow,Java,Swing,Focus,Flicker,Jwindow,我想在Swing中使用JavaVersion1.6.0\u26构建一个工具/调色板窗口(也称为“浮动”窗口)。我认为JWindow是最好的选择,Swing文档也指出了使用JWindow来达到这种目的(浮动窗口,它有一个所有者框架,没有装饰,也没有windows任务栏条目) 我的浮动工具窗口的内容由其他几个组件组成,如JButtons和JTextFields 问题 当我点击浮动工具窗口时,所有者窗口(JFrame,我的“主应用程序窗口”)偶尔“闪烁”。“闪烁”看起来像是所有者窗口在几毫秒内失去了焦

我想在Swing中使用JavaVersion1.6.0\u26构建一个工具/调色板窗口(也称为“浮动”窗口)。我认为JWindow是最好的选择,Swing文档也指出了使用JWindow来达到这种目的(浮动窗口,它有一个所有者框架,没有装饰,也没有windows任务栏条目)

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

问题 当我点击浮动工具窗口时,所有者窗口(JFrame,我的“主应用程序窗口”)偶尔“闪烁”。“闪烁”看起来像是所有者窗口在几毫秒内失去了焦点,然后又恢复了焦点,导致窗口的快速禁用/启用(请注意,没有触发任何窗口事件,如焦点丢失或窗口停用)

我已经在Windows7 64位和WindowsXP下对此进行了测试

视频和示例代码 为了澄清问题(解释起来有点困难),我拍摄了一段视频,在那里,当我反复点击浮动工具窗口时,你可以看到所有者窗口的“闪烁”:

  • (.MOV视频格式,我想您需要Quicktime来播放)
我还编写了一个简单的示例代码来重现问题(视频中使用了此代码):

迄今取得的进展 我还尝试将浮动工具窗口的“Window.setFocusableWindowsState”设置为false。如果为假,则没有“闪烁”,问题消失。该方法的JavaDoc指出:

将窗口的可聚焦状态设置为false是应用程序向AWT标识窗口的标准机制,该窗口将用作浮动调色板或工具栏,因此应为非可聚焦窗口。”

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

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

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


我非常感谢您的帮助,非常感谢!

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

我想这可能与我们的错误有关

无论如何,这里有一个修复程序似乎可以为我消除闪烁(Windows XP上的Java 1.6):


诀窍似乎是让窗口在显示时不可聚焦。

您考虑过使用非模态JDialog吗?感谢您的提示,我将尝试使用非模态JDialog。JWindow和非模态JDialog之间有显著区别吗?好的,我将JWindow切换为非模态JDialog。区别在于JDialog获得窗口焦点,使“主应用程序窗口”被禁用。我想到的是创建一个非装饰浮动工具窗口,指向主窗口(拥有窗口)始终保持窗口焦点。当用户单击未装饰的浮动工具窗口并且主应用程序窗口被停用时,它看起来很奇怪:/n没有解决方案,只是观察:我可以很容易地-只需单击几下-在vista和XP上用jdk6验证闪烁(不同的更新版本),但vistaThanks上的jdk7不支持此评论;我将尝试jdk7 myelf,看看Win 7下的效果如何。是的,当我运行代码时,我看到了相同的闪烁。请注意,有时,您必须单击很多次才能看到闪烁。在视频中,我单击了~3x秒来演示闪烁(但我认为速度并不重要,只是点击次数,闪烁具有随机性)。请验证:请快速点击,并在绿色窗口中至少点击20次。我的机器上的所有者窗口确实闪烁(我们的测试人员确认,闪烁也发生在他们的机器上).只是想检查一下:你在我上面录制的视频中看到问题了吗?肯定有问题,我慢慢地相信这是一种Java错误,有趣的是你没有看到它-可能是一个依赖操作系统的错误,你在Linux机器上,afair?@kleopatra没有,Windows 7。但是,也许是我疲惫的老眼睛,或者是我没有烦恼的事实d重新运行代码并单击20次。嘿,这不是
机器人的作用吗?!谢谢你的提示。看起来越来越像一个bug。我想我很快会去创建一个bug报告。
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 );
        }
    }
}
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();
        }
    }
}
window = new JWindow(parentFrame);
window.setFocusableWindowState(false);
window.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentShown(ComponentEvent e) {
        window.setFocusableWindowState(true);
        // Putting the focus on the content pane means that the first
        // visible component isn't focused, but if the user tabs, they
        // will get to it.
        window.getContentPane().requestFocus();
    }
    @Override
    public void componentHidden(ComponentEvent e) {
        window.setFocusableWindowState(false);
    }
});