2013-07-17 22 views
1

如何使用非字符串APIJPasswordField中的密码剪切/复制到剪贴板中。从而关闭黑客的窗口以查看密码。根据此链接https://stackoverflow.com/a/8885343/2534090 char数组与文本不同。如何剪切/复制JPasswordField中的文本为char数组?

public static void main(String[] args) { 
    Object pw = "Password"; 
    System.out.println("String: " + pw); 

    pw = "Password".toCharArray(); 
    System.out.println("Array: " + pw); 
} 

打印:

String: Password 
Array: [[email protected] 

什么,我想在剪贴板为[[email protected]但不Password

我试着用StringSelection的内容复制到剪贴板,但它的构造函数接受一个String这是不可变的,不安全。

+1

在阅读您的问题时,我感到非常困惑。你想获得一个JPasswordField的char-Array,并且已经找到了这个方法。你到底想要用密码做什么? – snrlx

+0

这可能会给你一些头:http://stackoverflow.com/questions/17706393/how-do-enable-cut-copy-in-jpasswordfield –

+0

看到当你打印字符数组,你会得到不同的输出,当你打印getText()得到文本(即密码)。现在我的问题是如何获得不同的输出到剪贴板! – user12458

回答

1

您可以使用自定义TransferHandler来执行此操作。

根据Swing教程Using and Creating a Data Flavor中的部分,您应该可以使用char []作为写入剪贴板的对象。

但是,我无法得到它的工作,并最终写了一个StringBuilder到剪贴板。我注释了代码是我试图使用char [],也许别人可以找出我做错了什么。

import java.awt.*; 
import java.awt.datatransfer.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 
import java.io.*; 

public class PasswordHandler extends TransferHandler 
{ 
// public final static DataFlavor CHAR_ARRAY_FLAVOR = new DataFlavor(char[].class, "Char Array"); 
    public final static DataFlavor CHAR_ARRAY_FLAVOR = new DataFlavor(StringBuilder.class, "StringBuilder"); 

    @Override 
    public int getSourceActions(JComponent c) 
    { 
     return COPY; 
    } 

    @Override 
    public Transferable createTransferable(final JComponent c) 
    { 
     return new Transferable() 
     { 
      @Override 
      public Object getTransferData(DataFlavor flavor) 
      { 
       JPasswordField textField = (JPasswordField)c; 
//    return textField.getPassword(); 
       return new StringBuilder(textField.getText()); 
      } 

      @Override 
      public DataFlavor[] getTransferDataFlavors() 
      { 
       DataFlavor[] flavors = new DataFlavor[1]; 
       flavors[0] = CHAR_ARRAY_FLAVOR; 
       return flavors; 
      } 

      @Override 
      public boolean isDataFlavorSupported(DataFlavor flavor) 
      { 
       return flavor.equals(CHAR_ARRAY_FLAVOR); 
      } 
     }; 
    } 

    @Override 
    public boolean canImport(TransferSupport support) 
    { 
     boolean canImport = support.isDataFlavorSupported(CHAR_ARRAY_FLAVOR); 
     return canImport; 
    } 

    @Override 
    public boolean importData(TransferSupport support) 
    { 
//  char[] password; 
     StringBuilder password; 

     try 
     { 
//   password = (char[])support.getTransferable().getTransferData(CHAR_ARRAY_FLAVOR); 
      password = (StringBuilder)support.getTransferable().getTransferData(CHAR_ARRAY_FLAVOR); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      return false; 
     } 

     JPasswordField textField = (JPasswordField)support.getComponent(); 
     textField.setText(password.toString()); 
     return true; 
    } 

    private static void createAndShowUI() 
    { 
     JPasswordField tf1 = new JPasswordField(10); 
     JPasswordField tf2 = new JPasswordField(10); 

     TransferHandler handler = new PasswordHandler(); 
     tf1.setTransferHandler(handler); 
     tf2.setTransferHandler(handler); 
     tf1.putClientProperty("JPasswordField.cutCopyAllowed",true); 
     tf2.putClientProperty("JPasswordField.cutCopyAllowed",true); 

     JFrame frame = new JFrame("Password Copy"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(tf1, BorderLayout.WEST); 
     frame.add(tf2, BorderLayout.EAST); 
     frame.add(new JTextField(), BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

该代码从密码字段中获取整个文本。如果您只想要选定的字符,那么您将需要修改getTransferData()方法以仅将选定的字符添加到StringBuilder。

相关问题