粘贴到 FoxPro 应用程序后,从 JTextArea 复制的文本已损坏编码 [英] Text copied from JTextArea have broken encoding after paste in FoxPro application

查看:31
本文介绍了粘贴到 FoxPro 应用程序后,从 JTextArea 复制的文本已损坏编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 Java 剪贴板时遇到了一个非常奇怪的问题.我的 JTextArea 文本包含重音符号(例如Žluťoučký kůň").当我选择文本并按 CTRL+C 并将其粘贴到记事本或 Microsoft Word 时,一切正常.

但是当我将它粘贴到一些用 VisualFoxPro 制作的第三方应用程序中时(我知道它很古老,但我们的用户需要这个应用程序),由于编码问题,所有重音字母都被破坏了.Java 应用程序使用 UTF-8,FoxPro 应用程序使用 Windows-1250.

当我使用剪贴板查看器时 (
(来源:
(来源:
(来源: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() {@覆盖public void keyPressed(KeyEvent e) {if (e.getKeyCode() == KeyEvent.VK_C && (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) {Toolkit 工具包 = Toolkit.getDefaultToolkit();剪贴板剪贴板 = toolkit.getSystemClipboard();CliboardString text = new CliboardString(textArea.getSelectedText(),"cp1250","Windows-1250");clipboard.setContents(text, null);e.consum();}}});

ClipboardString 的实现如下所示:

public class CliboardString 实现 Transferable, ClipboardOwner {私人最终 DataFlavor 风味;私有最终字符串数据;私有最终字符串 javaEncoding;public CliboardString(String data,String flavorEncoding,String javaEncoding) {this.data = 数据;this.javaEncoding = javaEncoding;flavor = new DataFlavor("text/plain;charset="+flavorEncoding, "TEXT");}@覆盖公共 DataFlavor[] getTransferDataFlavors() {返回新的 DataFlavor[] {flavor};}@覆盖public boolean isDataFlavorSupported(DataFlavor flavor) {返回味道!=null &&风味.equals(this.flavor);}@覆盖public Object getTransferData(DataFlavor flavor) 抛出 UnsupportedFlavorException, IOException {如果(isDataFlavorSupported(风味)){返回新的 ByteArrayInputStream(data.getBytes(javaEncoding));}抛出新的 UnsupportedFlavorException(flavor);}@覆盖public void lostOwnership(剪贴板剪贴板,可转让内容){}}

I have encountered one very strange problem with Java clipboard. I have JTextArea with text containing accents (e.g. "Žluťoučký kůň"). When I select the text and press CTRL+C and paste it into Notepad or Microsoft Word everything is OK.

But when I paste it into some third party application made in VisualFoxPro (I know it is ancient, but our user needs this application) all accents letters are broken due to encoding problem. Java app uses UTF-8 and FoxPro application uses Windows-1250.

When I use Clipboard viewer (https://code.google.com/p/clipboardviewer/) to view all DataFlavors created in clipboard after pressing CTRL+C in JTextArea I see following:


(source: itpro.cz)

System.String and UnicodeText are displayed correctly, but Text is broken. I assume that FoxPro application is using this DataFlavor.


(source: itpro.cz)

When I paste text into Notepad, press CTRL+A and CTRL+C, contents of clipboard changes as you can see on next image.


(source: itpro.cz)

My question(s): Is it bug in Java? Is it possible to control this behaviour globally (with some command line -D switch or other approach) or it is required to catch CTRL+C keystroke in every JTextArea and JTextField and create DataTransfer with custom DataFlavor manually? (no need to suggest code for this, I am able to do that, but it would be painful to register it for each JTextComponent in application)

解决方案

I have found 3 possible solutions:

1) Modify jre\lib\flavormap.properties file. Line starting with TEXT can be modified to:

TEXT=text/plain;charset=cp1250;eoln="\r\n";terminators=1

Where cp1250 is requested destination encoding. This works perfectly, but I believe that this file is overwrited with each Java update, so this is not usable for production use.

2) Start JVM with -Dfile.encoding=cp1250, this option also modifies clipboard functionality, but it also might change some behaviour of your app if you are relying on constructors like new InputStreamReader without specifing Charset.

3) Is to catch CTRL+C on each JTextComponent with this:

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();
        }
    }
});

Implementation of ClipboardString looks like this:

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) {
}

}

这篇关于粘贴到 FoxPro 应用程序后,从 JTextArea 复制的文本已损坏编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆