java - 在 FoxPro 应用程序中粘贴后,从 JTextArea 复制的文本编码已损坏

标签 java windows swing visual-foxpro

我在使用 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 时,我看到以下内容:

ClipboardViewer
(来源:itpro.cz)

System.StringUnicodeText 显示正确,但 Text 已损坏。我假设 FoxPro 应用程序正在使用此 DataFlavor。

ClipboardViewer
(来源:itpro.cz)

当我将文本粘贴到记事本中时,按 CTRL+A 和 CTRL+C,剪贴板的内容会发生变化,如下图所示。

ClipboardViewer
(来源: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/

相关文章:

regex - 在字符串中查找日期和时间并在 Windows 或 cmd 中使用 sed 重新格式化删除空格

java - 我怎样才能设置这个GUI的大小?

java - java中对String[]数组列表进行排序

java - PPC G3 与 MacOS 10.3.9 的交叉编译

java - 为什么 java 多播接收器无法在 Windows XP 上接收数据包?

java - 如何使 JSliders 仅显示四肢

java - 在 JTable 中使用空列作为分隔符

java - 一段时间没有输入后如何执行

java - 将 Mockito 增强类(class)与常规类(class)进行比较

c++ - Windows 编辑启动应用程序/C++