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

将文件扩展名与Java JRE7 Mac应用程序关联,java,macos,file-io,plist,Java,Macos,File Io,Plist,我想通过双击Mac来打开与我的应用程序关联的文件。这个问题以前被问过(很多次),例如,参见 然而,这些变化似乎是2009年(发布解决方案时)以来发生的。 该解决方案有效地基于2004年的一篇文章 依靠两块拼图: 1.Java程序应该注册文件打开事件并采取适当的行动。这是通过com.apple.eawt应用程序和应用程序适配器实现的。 2.操作系统需要熟悉扩展,这是通过使用 CbundleDocumentTypes输入包的.plist 如几次讨论中所述,2004 com.apple.eawt中使

我想通过双击Mac来打开与我的应用程序关联的文件。这个问题以前被问过(很多次),例如,参见

然而,这些变化似乎是2009年(发布解决方案时)以来发生的。 该解决方案有效地基于2004年的一篇文章 依靠两块拼图:
1.Java程序应该注册文件打开事件并采取适当的行动。这是通过com.apple.eawt应用程序和应用程序适配器实现的。 2.操作系统需要熟悉扩展,这是通过使用 CbundleDocumentTypes输入包的.plist

如几次讨论中所述,2004 com.apple.eawt中使用的结构被折旧,包括 (2月11日) 值得注意的是,OpenFileHandler取代了折旧的构造。答案中提到的API文档的链接不再起作用,因此目前还不清楚如何使用这种结构。 我发现以下参考资料解释了折旧的原因,但与文档的链接也已过时:

我无法在网上找到任何更新API的文档。苹果开发者网站还引用了我的版本(5.0.2)中没有的X代码示例

在(2012年)的讨论中 OpenFilesEvent是在从jdk6切换到jdk7 beta的过程中提到的,结论是一些错误归因于jdk7 beta

最后,也是在2012年,在OpenFileHandler的使用类似的地方提出了以下问题

这是我能找到的最近一篇文章,我想重新审视一下这里发布的问题

这个问题有两个答案:第一个建议切换到JavaWebStart,这对我来说不是一个选项。第二个答案集中在谜题的第二部分——向.plist注册正确的信息

具体而言,需要CbundleDocumentTypes和UTExportedTypeDeclarations。后者是注册自定义文件扩展名所必需的

使用appbundler并不能灵活地将这些键包含在.plist中,所以我试图在编辑.plist生成包之后将它们包含进来。 根据对原始帖子的建议,我将添加我的info.plist info.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>

CfBundledDevelopmentRegion
英语
Cbundlexecutable
JavaAppLauncher
循环流化床锅炉
myIcons.icns
CbundleIdentifier
mypackage.MainClass
CbundleDisplayName
我的计划
CbundleInfo字典版本
6
CFBundleName
程序名
CbundlePackageType
应用
CbundleShortVersionString
1
CFBundleSignature
????
循环流化床锅炉
1.
非人类可读版权
NOTICES.txt
JVM运行时
jdk1.7.0_21.jdk
JVMMainClassName
mypackage.MainClass
JVM选项
有趣的是,在某个时刻,这些图标出现了,然后就停止了。如果我右键单击该文件,我的应用程序将显示一个图像,但没有包含文件本身的图像。任何关于如何让这些图像运行的建议都将受到高度赞赏

这个问题似乎类似于 建议使用jarbundler,据我所知,它已被AppBundler取代

我还尝试刷新launchservices- 这没有帮助

总之,中描述的问题 通过使用OpenFileHandler成功解析,并且由于引入了自定义扩展,因此需要UTExportedTypeDeclaration。
多亏了威士匹德公司确认我走上了正确的道路,因为我快要放弃了。唯一未解决的问题是与文件关联的实际图像

这个答案主要关注OpenFileHandler的使用,它假设CFBundleDocumentTypes和UTExportedTypeDeclarations定义包含在Info.plist中(参见问题的文本)

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

相比之下,对于Mac,我们可以利用OpenFileHandler传递有关需要打开的文件的信息。具体用法如下:

在我的实现中,我有一个类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) );
 }
 ……………
这里我们将实现OpenFileHandler的类称为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.io.File;
导入java.util.List;
导入com.apple.eawt.AppEvent.OpenFilesEvent;
导入com.apple.eawt.Application;
导入com.apple.eawt.openfileHandler;
公共类MacFiles实现OpenFileHandler{
私人清单文件;
私人文件保存我的文件;
公共文件(文件保存归档){//
Application.getApplication().setOpenFileHandler(此);
我的归档=归档;
}
公共列表getFiles(){
归还文件;
}
@凌驾
公共void openFiles(OpenFilesEvent事件){
files=event.getFiles();
File myFile=新文件(files.get(0.getAbsolutePath());
readFile(myFile,true);
}
}

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

在您提供的Info.plist中,似乎不再支持CfBundleTypeIConfile条目。而是尝试用以下CbundleTypeIConfile条目替换它,该条目只是一个字符串值
<dict>
<key>CFBundleTypeName</key>
    <string>y program file</string>
<key>CFBundleTypeIconFile</key>
    <string>myIcons.icns</string>
<key>CFBundleTypeRole</key>
    <string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
    <array>
        <string>com.myCompany.xxx</string>
    </array>
</dict>