让 JOptionPane.showConfirmDialog() 在 Mac OSX 上运行
Getting JOptionPane.showConfirmDialog() to function on Mac OSX
我无法在 Mac (v10.9.5) 中正确获取消息框和某种程度的对话框 show/function。
我刚刚将 JRE 和 JDK 更新到最新版本 (8u31)。来自终端 window 的 "java -version" 表明我确实在使用 8u31。 (我之前使用的是 8u20,表现出相同的行为。)
下面的代码在 Windows 和我测试的几个不同版本的 Linux 中完美运行,没有问题。我只是在 Mac 上有问题。我将我的代码(基于 SWT,但此示例使用 Swing)简化为以下内容:
package myTest;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class EntryCode
{
public static EntryCode oEntryCode;
public EntryCode()
{
// TODO Auto-generated constructor stub
}
public static void main(String[] args)
{
oEntryCode = new EntryCode();
oEntryCode.open();
}
public void open()
{
JPanel panel = new JPanel();
panel.setMinimumSize(new Dimension(200,200));
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
}
我看到第一个系统输出行,代码挂在消息框请求上。在实际代码中,我只是使用 null 作为第一个参数。此测试代码的原始版本也使用了 null,只是我正在尝试指定一个组件。我认为这可能是问题所在。不是。
在显示SWT对话框时,有点击按钮会挂起界面的倾向。挂起介于按钮被按下和事件处理程序触发之间。事件处理程序从不触发。
我这里没有包含对话框。我认为由于我的 confirmation/message 盒子出现了解决一个问题的相同问题,所以免费获得另一个。
我在 Google 上进行了搜索以在 Mac 上显示 java 个应用程序,但没有找到任何结果。
我认为将 JRE/JDK 更新到最新版本可以解决任何 OS 相关问题。
我将代码编译成一个 jar 并使用以下命令从终端 window 运行。我按 Ctrl+C 来关闭挂起的应用程序。
java -XstartOnFirstThread -jar myTest.jar
想法?
更新:
我删除了原来的更新但留下了原来的问题,现在我对问题有了更好的理解。
真正的问题是如何启动一个适当的 Mac OSX Cocoa 限制友好的 SWT 应用程序,它使用对话框和消息框。 (据我所知,显示消息框的唯一方法是使用 JOptionPane.show*,它是 Swing 的东西,因此混合了 Swing 和 SWT。
有趣的是,问题总是与按钮有关,无论是对话框(纯 SWT 实现)还是消息框。在前者中,问题是调用事件处理程序挂起,而后者显示消息框(第一个参数为空,因为 SWT 应用程序中不存在 Swing 框架)。
问题可能是您没有在 EDT 中启动 GUI。试试这个:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
oEntryCode = new EntryCode();
oEntryCode.open();
}
});
}
更多信息:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
另一个问题是 -XstartOnFirstThread
与 Swing 一起使用。 Swing 的作用与 -XstartOnFirstThread
的作用相同,但以其自己的方式。您不应该将 -XstartOnFirstThread
与 Swing 一起使用,因为混合使用 SWT 和 Swing 不是一个好主意。
如果您添加 SwingUtilities.invokeLater()
并删除 -XstartOnFirstThread
,您的示例应该 运行 正常。
不太确定这是否是错误,因为目前我无法在 Mac 上对其进行测试。但是您永远不会将 JFrame
的可见性设置为 true。当您将框架作为参数传递给 JOptionPane
时,窗格会尝试在框架中显示窗格。
所以尝试:
public void open()
{
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
frame.setSize(300,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
另外,为什么要创建 JPanel,据我所知,该面板从未被使用过?
由于框架不可见,这可能会导致问题。只是一个猜测...
这也可以解释为什么您的应用程序看起来像 "freezing"。这是因为它正在等待您在 JOptionPane
中进行选择,但您无法进行选择,因为您看不到 JOptionPane。
我知道你写过你也尝试过将 null 作为参数传递,但我认为当没有显示其他 JFrame 时这也会导致问题。正如我所说的只是一个猜测。试试看,然后回来提供更多信息。
编辑
刚刚测试过,看起来你的代码没问题。您的错误必须在于您的 mac 或 java 设置。
编辑 2
我想我找到了你的答案。看起来 startOnFirstThread
是这里的问题。我刚刚在命令行上通过 javac 和 java 进行了测试。看看这个:
Swing stops working, because -XstartOnFirstThread implies that that
someone else (very likely the SWT) is going to come around, and start
pumping the event loop on thread 0 with CFRunLoop or the like
这可以解释为什么您的 JOptionPane 难以显示。 (摘自:here
也有点老,但描述了你的问题:
The AWT problems generally come down to which thread the jvm was started on. When using the java launcher (as pde does) on Mac, java by default starts on the second thread (which is what AWT wants) unless you specify -XstartOnFirstThread (which is what SWT wants).
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=212617)
我无法在 Mac (v10.9.5) 中正确获取消息框和某种程度的对话框 show/function。
我刚刚将 JRE 和 JDK 更新到最新版本 (8u31)。来自终端 window 的 "java -version" 表明我确实在使用 8u31。 (我之前使用的是 8u20,表现出相同的行为。)
下面的代码在 Windows 和我测试的几个不同版本的 Linux 中完美运行,没有问题。我只是在 Mac 上有问题。我将我的代码(基于 SWT,但此示例使用 Swing)简化为以下内容:
package myTest;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class EntryCode
{
public static EntryCode oEntryCode;
public EntryCode()
{
// TODO Auto-generated constructor stub
}
public static void main(String[] args)
{
oEntryCode = new EntryCode();
oEntryCode.open();
}
public void open()
{
JPanel panel = new JPanel();
panel.setMinimumSize(new Dimension(200,200));
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
}
我看到第一个系统输出行,代码挂在消息框请求上。在实际代码中,我只是使用 null 作为第一个参数。此测试代码的原始版本也使用了 null,只是我正在尝试指定一个组件。我认为这可能是问题所在。不是。
在显示SWT对话框时,有点击按钮会挂起界面的倾向。挂起介于按钮被按下和事件处理程序触发之间。事件处理程序从不触发。
我这里没有包含对话框。我认为由于我的 confirmation/message 盒子出现了解决一个问题的相同问题,所以免费获得另一个。
我在 Google 上进行了搜索以在 Mac 上显示 java 个应用程序,但没有找到任何结果。
我认为将 JRE/JDK 更新到最新版本可以解决任何 OS 相关问题。
我将代码编译成一个 jar 并使用以下命令从终端 window 运行。我按 Ctrl+C 来关闭挂起的应用程序。
java -XstartOnFirstThread -jar myTest.jar
想法?
更新:
我删除了原来的更新但留下了原来的问题,现在我对问题有了更好的理解。
真正的问题是如何启动一个适当的 Mac OSX Cocoa 限制友好的 SWT 应用程序,它使用对话框和消息框。 (据我所知,显示消息框的唯一方法是使用 JOptionPane.show*,它是 Swing 的东西,因此混合了 Swing 和 SWT。
有趣的是,问题总是与按钮有关,无论是对话框(纯 SWT 实现)还是消息框。在前者中,问题是调用事件处理程序挂起,而后者显示消息框(第一个参数为空,因为 SWT 应用程序中不存在 Swing 框架)。
问题可能是您没有在 EDT 中启动 GUI。试试这个:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
oEntryCode = new EntryCode();
oEntryCode.open();
}
});
}
更多信息:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
另一个问题是 -XstartOnFirstThread
与 Swing 一起使用。 Swing 的作用与 -XstartOnFirstThread
的作用相同,但以其自己的方式。您不应该将 -XstartOnFirstThread
与 Swing 一起使用,因为混合使用 SWT 和 Swing 不是一个好主意。
如果您添加 SwingUtilities.invokeLater()
并删除 -XstartOnFirstThread
,您的示例应该 运行 正常。
不太确定这是否是错误,因为目前我无法在 Mac 上对其进行测试。但是您永远不会将 JFrame
的可见性设置为 true。当您将框架作为参数传递给 JOptionPane
时,窗格会尝试在框架中显示窗格。
所以尝试:
public void open()
{
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
frame.setSize(300,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
另外,为什么要创建 JPanel,据我所知,该面板从未被使用过?
由于框架不可见,这可能会导致问题。只是一个猜测...
这也可以解释为什么您的应用程序看起来像 "freezing"。这是因为它正在等待您在 JOptionPane
中进行选择,但您无法进行选择,因为您看不到 JOptionPane。
我知道你写过你也尝试过将 null 作为参数传递,但我认为当没有显示其他 JFrame 时这也会导致问题。正如我所说的只是一个猜测。试试看,然后回来提供更多信息。
编辑 刚刚测试过,看起来你的代码没问题。您的错误必须在于您的 mac 或 java 设置。
编辑 2
我想我找到了你的答案。看起来 startOnFirstThread
是这里的问题。我刚刚在命令行上通过 javac 和 java 进行了测试。看看这个:
Swing stops working, because -XstartOnFirstThread implies that that
someone else (very likely the SWT) is going to come around, and start
pumping the event loop on thread 0 with CFRunLoop or the like
这可以解释为什么您的 JOptionPane 难以显示。 (摘自:here
也有点老,但描述了你的问题:
The AWT problems generally come down to which thread the jvm was started on. When using the java launcher (as pde does) on Mac, java by default starts on the second thread (which is what AWT wants) unless you specify -XstartOnFirstThread (which is what SWT wants). (https://bugs.eclipse.org/bugs/show_bug.cgi?id=212617)