簡體   English   中英

關注mac osx上java7模式對話框的問題

[英]Focus issues with java7 modal dialogs on mac osx

我一直在驗證在mac osx的applet上運行的swing應用程序。

在此驗證期間,我發現模式對話框存在以下問題:

  1. 當一個對話框打開並且是setModal(true)時,它會阻止根窗口的內容,但如果你點擊根窗口的某個地方,對話框會在它下面,但它應該保留在根窗口的頂部。
  2. 如果對話框有JTextInputField,即使單擊它也不會獲得焦點。

所以我創建了一個小程序來顯示問題。 你能幫我理解這里有什么問題嗎?

package com.macosx.tests;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class DialogExample extends JApplet{

    private static final long serialVersionUID = 1L;
    private JPanel panel;
    private JButton openDialogBtn;

    private void doStart() {
        panel = new JPanel();
        panel.setPreferredSize(new Dimension(500,500));

        openDialogBtn = new JButton("open dialog");
        openDialogBtn.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                ModalDialog dialog = new ModalDialog(panel, true);
                dialog.setVisible(true);
            }

        });
        panel.add(openDialogBtn);
        setContentPane(panel);
    }


    class ModalDialog extends JDialog {
        private static final long serialVersionUID = 1L;

        public ModalDialog(Component parent, boolean modal) {
            Dimension dimensionParentFrame = parent.getSize();
            setSize(new Dimension((parent == null) ? 300 : dimensionParentFrame.width / 2, 75));

            setModal(modal);
            setModalityType(ModalityType.APPLICATION_MODAL);

            JTextField txtField = new JTextField();
            add(txtField, BorderLayout.CENTER);
        }
    }


    @Override
    public void start() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    doStart();
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

使用上面的方法創建.jar文件(test.jar)。 完成后,創建一個包含以下內容的html文件:

<html>
<head>
<title>Dialog test Applet</title>
</head>
<body>
<applet id="DialogTestApplet" height="800" width="600"
  code="com.macosx.tests.DialogExample"
  archive="test.jar">
</applet>
</div>
</body>
</html>

完成后,運行html文件。 你會看到一個灰色背景和一個按鈕的小程序。 然后嘗試:

  1. 單擊按鈕打開對話框。 之后,單擊灰色區域的某個位置:對話框位於瀏覽器窗口下方,但它應保留在頂部,對吧?
  2. 單擊按鈕打開對話框。 之后單擊對話框的文本字段並嘗試編寫一些內容:textdialog無法獲得焦點。

那么,我在這里做錯了什么? 有人用Mac電腦測試一下嗎?

謝謝

眼鏡:

java.vendor    Oracle Corporation
java.version   1.7.0_07
os.name        Mac OS X
os.version     10.7.4

browser        firefox 15

注意:請注意,這僅在applet在瀏覽器上運行且僅在mac osx上運行時才會發生。

我發現了另一種解決方法。 打開窗口時,顯示一個選項窗格幾毫秒並關閉它。 它將焦點放在選項窗格上,然后返回到對話框,允許忽略該錯誤。

將此snipet代碼添加到對話框構造函數中,它應該工作:

addWindowListener(new WindowAdapter(){
public void windowOpened(WindowEvent e){
    JOptionPane pane = new JOptionPane();
    final JDialog dialog = pane.createDialog("Please Wait");
    Timer timer = new Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            dialog.dispose();
        }
    });
timer.setRepeats(false);
timer.start();
dialog.setVisible(true);
}

您應該在ModalDialog上放置一個“所有者”窗口。 為此,您必須在ModalDialog構造函數中調用super(owner),並且可以使用SwingUtilities.getWindowAncestor(parent)檢索組件parent的父窗口。

  • 不是Mac / OSX用戶,但這是關於FocusJDialog常見問題,

  • 在運行時創建JDialog的情況下還有另一個問題,

  • Focus是基於Native OS屬性而異步的

  • 只創建一次JDialog然后re_usecontainer進行另一個操作

  • JDialog#setVisible應該包裝到invokeLater()

  • 可以通過JTextField#setText(JTextField#getText())強制Focus JTextField#setText(JTextField#getText())包裝到invokeLater()

  • Dialog Focus是@camickr的一個很好的解決方法

我確認,我在OS X上的JDK7中運行的舊applet也有同樣的錯誤。正如海報所提到的,只有applet在瀏覽器中運行(ff)而不是appletviewer才能看到錯誤。

我可以驗證這是Safari Mountain 6上的Java 1.7 Update 7+和Mountain Lion上運行的Firefox的問題。 奇怪的是,早期版本的Safari在Lion上運行並不是問題,但在舊操作系統的Firefox中存在問題。 由於許多applet用戶都在Mac上,我非常渴望找到解決方法。 我找到的一種解決方法(通過任何方式都不夠)是縮小窗口然后重新打開它。 textfields / textareas然后變得可編輯。 希望我們能找到更好的解決方案來解決這個煩人的需求。

我在Mac上使用Safari和Firefox的Java 7更新9遇到了同樣的問題。 當我打開一個包含JTextField的JDialog時,JTextField無法訪問。

我確實找到了解決方案。 我插入了一個延遲,從用戶按下“顯示對話框按鈕”到執行顯示按鈕的代碼。

例如:

ActionListener al = new ActionListener(){
    public void actionPerformed(ActionEvent ae){
        TitleDialog dialog = new TitleDialog(main.findParentFrame()); // My JDialog which contains a JTextField.
        dialog.setVisible(true);
    }
};
javax.swing.Timer timer = new javax.swing.Timer(1000, al);
timer.setRepeats(false);
timer.start(); 

我經歷過,如果延遲時間很短,解決方案將無效。

如果使用SwingUtilities.invokeLater而不是javax.swing.Timer它將無法正常工作。 也許SwingUtilities.invokeLater的延遲太短了。

我找到了另外一個解決方法。 當從JavaScript調用JDialog時,它有一個焦點。

  1. 創建一個applet的方法,它將顯示一個對話框
  2. 從JavaScript調用此方法。

希望能幫助到你。 順便說一下,來自Java教程的Web啟動示例具有相同的問題http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html

我想使用上面的解決方法(從對話框打開對話框),但沒有顯示任何對話框。 這是一個不可見對話框的代碼。

final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setSize(0, 0);
dialog.setModal(true);
dialog.pack();

我找到了解決方案。

GetDirectory varGetDirectory = new GetDirectory(new JFrame(),true);
varGetDirectory.setVisible(true);       

GetDirectory是包含JFileChooser的JDialog。

奇怪的是,所有JDialog對象都應該使用新的JFrame()作為父級調用,否則從一個父窗口單擊將使頂級模式JDialog在zOrder中向后移動,並且不知何故它不能再設置在頂部。

我的問題和上面一樣。 當我從另一個JDialog創建JDialog時,新對話框出現在另一個之后。

為了使它成為頂部我已經設置了如上所述的所有JDialog的父級,並且它根據預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM