java - 将文件扩展名与 Mac 的 Java JRE7 应用程序相关联

标签 java macos file-io plist

我想通过在 Mac 上双击打开与我的应用程序关联的文件。这个问题之前已经被问过(很多)次,例如 Double click document file in Mac OS X to open Java application

但是,看起来变化发生在 2009 年(发布解决方案时)。 该解决方案实际上基于 2004 年的文章 https://today.java.net/pub/a/today/2004/01/05/swing.html 并依靠两 block 拼图:
1. Java 程序应该注册文件打开事件并采取适当的行动。这是使用 com.apple.eawt 应用程序和应用程序适配器完成的。 2.操作系统需要熟悉扩展,这是通过使用完成的 包的 .plist 中的 CFBundleDocumentTypes 键。

2004 com.apple.eawt 中使用的结构已折旧,如多个讨论中所述,包括 What's the alternative to using the now deprecated com.apple.eawt.ApplicationAdapter in Java Swing apps on the Mac? (2 月 11 日) 值得注意的是,OpenFilesHandler 取代了折旧的结构。答案中提到的 API 文档的链接不再起作用,因此目前还不清楚如何使用此构造。 我找到了以下解释折旧原因的引用资料,但文档链接也已过时: http://lists.apple.com/archives/java-dev/2012/Jan/msg00101.html

我无法在网上找到更新后的 API 的任何文档。 Apple Developer 站点还引用了 X 代码中的示例,这些示例在我的版本 (5.0.2) 中不存在

在 (2012) 的讨论中 https://stackoverflow.com/questions/8857431/java-mac-jdk-7-beta-apple-application-listener-no-longer-works 在从 jdk6 切换到 jdk7-beta 的上下文中提到了 OpenFilesEvent,结论是一些错误归因于 jdk7-beta。

最后,同样在 2012 年,在 OpenFilesHandler 的使用类似的地方提出了以下问题。

Grabbing the openFileEvent on MacOSX (Can't get filename)

这是我能找到的最新帖子,我想重新审视那里发布的问题。

该线程中有两个答案:第一个建议切换到 Java Web Start,这对我来说不是一个选项。第二个答案集中在难题的第二部分 - 使用 .plist 注册正确的信息。

具体来说,需要 CFBundleDocumentTypes 和 UTExportedTypeDeclarations。后者需要注册自定义文件扩展名。

使用应用程序 bundler 无法灵活地将这些键包含在 .plist 中,因此我尝试在通过编辑 .plist 生成包后包含它们。 按照对原始帖子的建议,我包括了我的 info.plist 信息.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-  1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>JavaAppLauncher</string>
<key>CFBundleIconFile</key>
<string>myIcons.icns</string>
<key>CFBundleIdentifier</key>
<string>mypackage.MainClass</string>
<key>CFBundleDisplayName</key>
<string>MyProgram</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ProgramName</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>NOTICES.txt</string>
<key>JVMRuntime</key>
<string>jdk1.7.0_21.jdk</string>
<key>JVMMainClassName</key>
<string>mypackage.MainClass</string>
<key>JVMOptions</key>
<array/>
<key>JVMArguments</key>
<array/>
<key>UTExportedTypeDeclarations</key>
<dict>
            <key>UTTypeIdentifier</key>
    <string>com.myCompany.xxx</string>
    <key>UTTypeReferenceURL</key>
    <string>http://myCompany.com/xxx.html</string>
    <key>UTTypeDescription</key>
    <string>My program file</string>
    <key>UTTypeIconFile</key>
            <array>
    <string>myIcons.icns</string>
            </array>
    <key>UTTypeConformsTo</key>
            <array>
    <string>com.apple.package</string>
             </array>
    <key>UTTypeTagSpecification</key>
    <dict>
        <key>public.filename-extension</key>
        <string>apn</string>
    </dict>
</dict>
<key>CFBundleDocumentTypes</key>
<dict>
    <key>CFBundleTypeName</key>
    <string>y program file</string>
    <key>CFBundleTypeIconFiles</key>
            <array>
    <string>myIcons.icns</string>
             </array>
            <key>CFBundleTypeRole</key>
             <string>Editor</string>
    <key>LSHandlerRank</key>
    <string>Owner</string>
    <key>LSItemContentTypes</key>
    <string>com.myCompany.xxx</string>
</dict>
</dict>
</plist>

这个 info.plist 的作用是:文件确实与应用程序相关联,我可以通过双击打开它们。

唯一剩下的问题是文件不显示与文件关联的图标(任何大小)(无论我选择如何查看文件)。应用程序本身显示图标。我使用生成了一整套图标 带有 png 文件的文件夹中的 iconutil,如所述 https://apple.stackexchange.com/questions/59561/where-did-icon-composer-go-from-xcode 有趣的是,这些图标有时会出现,然后就停止了。如果我右键单击该文件,我的应用程序会显示一个图像,但文件本身没有图像。非常感谢任何关于如何让这些图像运行的建议。

问题似乎类似于 OSX Custom extension icon Association 那里的建议是使用 Jar Bundler,据我所知,它已被 AppBundler 取代。

我还尝试刷新启动服务 - http://www.tekrevue.com/tip/rebuild-launchservices-fix-duplicate-entries-os-xs-open-menu/ 它没有帮助。

总而言之,中描述的问题 Grabbing the openFileEvent on MacOSX (Can't get filename) 已通过使用 OpenFilesHandler 成功解决,并且由于引入了自定义扩展,因此需要 UTExportedTypeDeclarations。 感谢威士忌蜘蛛确认我走在正确的轨道上,因为我快要放弃了。唯一 Unresolved 问题是与文件关联的实际图像。

最佳答案

这个答案侧重于 OpenFilesHandler 的使用,它假定 CFBundleDocumentTypes 和 UTExportedTypeDeclarations 定义包含在 Info.plist 中(参见问题的文本)。

回想一下在 Mac 和 PC 中打开 Java 应用程序的方法之间存在基本差异是很有用的。在 PC 的情况下,依赖于要打开的文件的直接命令行规范。文件名是从命令行传递给 Java 程序的参数。因此,需要编写 Java 程序来接受这个参数并适本地处理它。 PC 包装器(例如 Inno Setup)提供了一种通过单击文件来调用带有所需参数的 Java 程序的方法。

相比之下,对于 Mac,我们可以利用 OpenFilesHandler 传递有关需要打开的文件的信息。具体用法大致如下: Grabbing the openFileEvent on MacOSX (Can't get filename)

在我的实现中,我有一个类 FileSaving,它有一个方法 readFile,该方法将类 File 的一个实例作为参数,并执行读取文件的实际工作。在程序的主要部分,我有以下相关的代码片段:

public final static boolean SYSTEMISMAC=(System.getProperty("os.name")).startsWith("M"); //   treating Mac separately
static protected FileSaving initialFiling;
........
initialFiling = new FileSaving(); // Initializing  
if(SYSTEMISMAC){
     Application a = Application.getApplication();
     a.setOpenFileHandler(new MacFiles(initialFiling) );
 }
 ……………

这里我们调用实现 OpenFilesHandler 的类 MacFiles:

import java.io.File;
import java.util.List;
import com.apple.eawt.AppEvent.OpenFilesEvent;
import com.apple.eawt.Application;
import com.apple.eawt.OpenFilesHandler;
public class MacFiles implements OpenFilesHandler{
private List<File> files;
private FileSaving myFiling;
public MacFiles(FileSaving filing) {//
    Application.getApplication().setOpenFileHandler(this);
    myFiling=filing;
}
public List<File> getFiles() {
    return files;
}
@Override
public void openFiles(OpenFilesEvent event) {
  files = event.getFiles();
  File myFile=new File(files.get(0).getAbsolutePath());
  myFiling.readFile(myFile,true);  
}
}

从某种意义上说,双击文件可以打开它,但在浏览文件时显示自定义图标的问题(如问题中所述)仍未解决。

关于java - 将文件扩展名与 Mac 的 Java JRE7 应用程序相关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22705060/

相关文章:

objective-c - NSSearchField - 显示带有结果的 NSMenu

R 将列转换为 NA 值 - 为什么?

java - Java中使用Wait()和notify()的多线程环境的自定义事件监听器

java - 如何在java中扫描屏幕上的特定颜色/图像?

Java 1.7 : Sum of Iterable<T extends Number>

java - Apache Camel : async operation and backpressure

python - 如何使用 Python 从终端使用默认 Web 浏览器打开 url?

linux - 字体不工作 - Vim Statusline

c++ - 你能帮我清除这个错误吗

java - 在项目根文件夹中找不到文件