2

我有一个 Java 应用程序,其基本 UI 由两个 JFrame 组成:一个客户区和一个应始终出现在客户区上方的工具面板。为了实现这一点,工具调色板设置为 alwaysOnTop(true),它在所有情况下都能很好地工作,除了 Windows 独有的一个:当弹出模式 JDialog 时,单击客户区域和/或调色板(两者都是阻塞)导致调色板落在客户区后面。关闭模态对话框后,调色板会重新出现,但它的“始终处于顶部”已经丢失:单击客户区域会遮盖调色板。

这是一个最小的单一源文件演示:

// FloatingPaletteExample.java
// 4/11/2012 sorghumking
//
// Demo of a Windows-only issue that has me puzzled: When a modal dialog is
// opened, and user clicks in blocked JFrames (sequence depends on ownership of
// modal dialog: follow the instructions in modal dialog to see the problem
// behavior), the floating tool palette loses its "always on top-ness". 

import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class FloatingPaletteExample {
    public static void main( String [] args ) {
        final JFrame clientAreaJFrame = new JFrame( "client JFrame" ); 
        clientAreaJFrame.addWindowListener( new WindowAdapter() {
            public void windowClosing( WindowEvent windowevent ) {
                clientAreaJFrame.dispose();
                System.exit( 0 );
            }
        });

        clientAreaJFrame.setSize( 800, 600 );
        clientAreaJFrame.setVisible( true );

        final JFrame floatingToolFrame = new JFrame("tool JFrame");
        final JCheckBox ownerCheckbox = new JCheckBox("Owned by tool frame (otherwise, null owner)");
        JButton popModalButton = new JButton("Open Modal Dialog");
        popModalButton.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JFrame owner = ownerCheckbox.isSelected() ? floatingToolFrame : null;
                JDialog modalDialog = new JDialog(owner, "Modal Dialog", true);
                final String labelText = ownerCheckbox.isSelected() ? "Click anywhere in the client JFrame." :
                                                                      "Click the tool JFrame, then anywhere in the client JFrame";
                modalDialog.add(new JLabel(labelText));
                modalDialog.pack();
                modalDialog.setLocation(100, 100);
                modalDialog.setVisible(true);
            }
        });
        floatingToolFrame.add(popModalButton, BorderLayout.NORTH);
        floatingToolFrame.add(ownerCheckbox, BorderLayout.SOUTH);

        floatingToolFrame.pack();
        floatingToolFrame.setLocationRelativeTo(clientAreaJFrame);
        floatingToolFrame.setAlwaysOnTop(true);
        floatingToolFrame.setVisible(true);
    }
}

我尝试了 floatingToolFrame.setFocusableWindowState(false),根据文档,它是“应用程序向 AWT 识别将用作浮动调色板或工具栏的窗口的标准机制”,但行为保持不变。

我确实找到了一种解决方法:在弹出模式对话框之前调用 floatingToolFrame.setAlwaysOnTop(false),并在关闭后调用 floatingToolFrame.setAlwaysOnTop(true)。但是,在打开模式对话框的任何时候都要求这种包装似乎很荒谬。是的,我可以将 JDialog 子类化并从所述子类派生我的所有对话框以在幕后执行此操作,但同样,为什么这是必要的?

关于如何在没有解决方法的情况下解决此问题的任何想法?我创建始终在顶部的调色板的方法是否完全被误导了?(还有一点需要注意:这似乎与此处描述的问题相反:Java 6, JFrame stand alwaysontop)。

任何想法将不胜感激!

4

1 回答 1

0

令我非常高兴的是,这个问题似乎在Java 7 SE中得到了解决!上面的示例在7u4 Build b20上运行正常。

于 2012-04-13T21:47:22.300 回答