8

Mac osx のアプレットで実行されるスイング アプリケーションを検証してきました。

この検証中に、モーダル ダイアログで次の問題が見つかりました。

  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. ボタンをクリックしてダイアログを開きます。その後、ダイアログのテキストフィールドをクリックして、何かを書き込もうとします。テキストダイアログはフォーカスを受けません。

それで、私はここで何が間違っていますか?Macコンピュータを持っている人がこれをテストできますか?

ありがとう

仕様:

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

browser        firefox 15

注: これは、アプレットがブラウザで実行され、Mac OSX でのみ実行される場合にのみ発生することに注意してください。

4

9 に答える 9

6

別の回避策を見つけました。ウィンドウが開いたら、オプション ペインを数ミリ秒間表示して閉じます。オプションペインにフォーカスを与えてからダイアログに戻ることで、バグを無視できます。

このコード スニペットをダイアログ コンストラクターに追加すると、動作するはずです。

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);
}
于 2012-12-13T14:12:40.487 に答える
1

確認しました。OSXのJDK7で実行されている古いアプレットにも同じバグがあります。ポスターに記載されているように、バグはブラウザ(ff)で実行されているアプレットでのみ発生し、appletviewerでは発生しません。

于 2012-09-25T13:20:23.473 に答える
1

Safari と Firefox を使用した Java 7 update 9 の Mac でも同じ問題が発生しました。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短すぎる可能性があります。

于 2012-10-24T10:05:25.363 に答える
1

ModalDialog に「所有者」ウィンドウを配置する必要があります。これを行うには、ModalDialog コンストラクターで super(owner) を呼び出す必要があり、コンポーネントの親ウィンドウを で取得できparentますSwingUtilities.getWindowAncestor(parent)

于 2012-09-05T09:56:47.753 に答える
1
  • Mac/OSX ユーザーではありませんが、これは と に関する一般的な問題FocusですJDialog

  • JDialogランタイムで作成されたケースには別の問題があります。

  • Focusからのプロパティに基づいて非同期ですNative OS

  • JDialogこれを一度だけ作成し、re_useこれcontainerを別のアクション用に作成します

  • JDialog#setVisibleinvokeLater()あまりにもラップする必要があります

  • にラップすることを強制することが可能FocusですJTextField#setText(JTextField#getText())invokeLater()

  • @camickrによる優れた回避策の1つであるDialog Focusがあります

于 2012-09-05T11:06:07.073 に答える
1

これが、Safari 6 上の Java 1.7 Update 7+ および Mountain Lion で実行されている Firefox の問題であることを確認できます。不思議なことに、Lion で動作する以前のバージョンの Safari では問題になりませんが、古い OS の Firefox では問題になります。多くのアプレット ユーザーが Mac を使用しているため、この問題の修正がどうしても必要です。私が見つけた 1 つの回避策 (これでは決して十分ではありません) は、ウィンドウを縮小してから再度開くことです。その後、テキストフィールド/テキストエリアが編集可能になります。願わくば、この煩わしい要件を回避するより良い解決策を見つけられることを願っています。

于 2012-10-18T23:18:10.683 に答える
0

上記の回避策(ダイアログからダイアログを開く)を使用したいのですが、ダイアログを表示しません。表示されないダイアログのコードを次に示します。

final JDialog dialog = new JDialog();
dialog.setUndecorated(true);
dialog.setSize(0, 0);
dialog.setModal(true);
dialog.pack();
于 2013-01-14T09:27:08.187 に答える
0

もう1つの回避策を見つけました。JDialog が JavaScript から呼び出されると、フォーカスがあります。

  1. ダイアログを表示するアプレットのメソッドを作成します
  2. JavaScript からこのメソッドを呼び出します。

それが役に立てば幸い。ところで、Java チュートリアルの Web Start サンプルには同じ問題があります http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html

于 2012-10-25T03:57:08.527 に答える