[英]Focus issues with java7 modal dialogs on mac osx
我一直在驗證在mac osx的applet上運行的swing應用程序。
在此驗證期間,我發現模式對話框存在以下問題:
所以我創建了一個小程序來顯示問題。 你能幫我理解這里有什么問題嗎?
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文件。 你會看到一個灰色背景和一個按鈕的小程序。 然后嘗試:
那么,我在這里做錯了什么? 有人用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用戶,但這是關於Focus
和JDialog
常見問題,
在運行時創建JDialog
的情況下還有另一個問題,
Focus
是基於Native OS
屬性而異步的
只創建一次JDialog
然后re_use
此container
進行另一個操作
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時,它有一個焦點。
希望能幫助到你。 順便說一下,來自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.