我在使用 Java 剪贴板时遇到了一个非常奇怪的问题。我有 JTextArea 文本包含重音符号(例如“Žluťoučký kůň”)。当我选择文本并按 CTRL+C 并将其粘贴到记事本或 Microsoft Word 时,一切正常。
但是当我将它粘贴到用 VisualFoxPro 制作的某些第三方应用程序时(我知道它很古老,但我们的用户需要这个应用程序)由于编码问题,所有重音字母都被破坏了。 Java 应用程序使用 UTF-8,FoxPro 应用程序使用 Windows-1250。
当我在 JTextArea 中按 CTRL+C 后使用剪贴板查看器 ( https://code.google.com/p/clipboardviewer/ ) 查看在剪贴板中创建的所有 DataFlavors 时,我看到以下内容:
(来源:itpro.cz)
System.String 和 UnicodeText 显示正确,但 Text 已损坏。我假设 FoxPro 应用程序正在使用此 DataFlavor。
(来源:itpro.cz)
当我将文本粘贴到记事本中时,按 CTRL+A 和 CTRL+C,剪贴板的内容会发生变化,如下图所示。
(来源:itpro.cz)
我的问题:它是 Java 中的错误吗?是否可以全局控制此行为(使用某些命令行 -D 开关或其他方法)或需要在每个 JTextArea 和 JTextField 中捕获 CTRL+C 击键并手动创建具有自定义 DataFlavor 的 DataTransfer? (不需要为此建议代码,我能够做到,但是为应用程序中的每个 JTextComponent 注册它会很痛苦)
最佳答案
我找到了 3 种可能的解决方案:
1) 修改jre\lib\flavormap.properties文件。以 TEXT 开头的行可以修改为:
TEXT=text/plain;charset=cp1250;eoln="\r\n";terminators=1
其中 cp1250 是请求的目标编码。 这非常有效,但我相信每次 Java 更新都会覆盖此文件,因此它不能用于生产。
2) 使用 -Dfile.encoding=cp1250 启动 JVM,此选项还会修改剪贴板功能,但如果您依赖 new InputStreamReader 等构造函数而不指定,它也可能会更改应用的某些行为字符集。
3) 是用这个在每个 JTextComponent 上捕获 CTRL+C:
textArea.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_C && (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolkit.getSystemClipboard();
CliboardString text = new CliboardString(textArea.getSelectedText(),"cp1250","Windows-1250");
clipboard.setContents(text, null);
e.consume();
}
}
});
ClipboardString 的实现如下所示:
public class CliboardString implements Transferable, ClipboardOwner {
private final DataFlavor flavor;
private final String data;
private final String javaEncoding;
public CliboardString(String data,String flavorEncoding,String javaEncoding) {
this.data = data;
this.javaEncoding = javaEncoding;
flavor = new DataFlavor("text/plain;charset="+flavorEncoding, "TEXT");
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] {flavor};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor!=null && flavor.equals(this.flavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (isDataFlavorSupported(flavor)) {
return new ByteArrayInputStream(data.getBytes(javaEncoding));
}
throw new UnsupportedFlavorException(flavor);
}
@Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
}
}
关于java - 在 FoxPro 应用程序中粘贴后,从 JTextArea 复制的文本编码已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29651301/