我有一个基本的基于文本的Java应用程序。我希望用户能够在一个文本编辑会话中输入敏感信息(密码),而这个会话只为这个目的而存在。
有点像使用git,你在vi(或其他设置编辑器)中得到一个临时会话文件来编辑评论和保存quit - 然后git进程恢复并消耗该文件。该文件(可能)被删除或至少被遗忘。
不需要任何高级编辑器的功能,只需要基本的打字、退格等。
I 想要 用户能够看到他们正在输入的内容,但一旦他们输入了密码,它就会 必须 从屏幕上抹去。因此,普通的STDIN将无法工作,因为输入的内容仍在屏幕上。
我如何在Java或其他语言中做到这一点呢?我已经研究了Scanner(基本上是STDIN)和Console.readPassword(用户不能看到他们输入的内容)。
也许一个涉及STDIN和立即擦除输入行的解决方案可以被接受。但模拟gitvi的交互方式更有吸引力,因为它可以说更标准一些。
EDIT: 我已经实现了一些类似的功能--创建临时文件并在该文件上运行notepad.exe,让用户保存和关闭记事本,从临时文件中读取并删除它。很简单,但它依赖于一个外部工具,需要调整以在linux上运行。我希望能有更完美的行为。仿真 在java应用本身
Swing是相当稳定可用的,这里有一个方法的例子,它打开一个窗口,等到窗口关闭,然后返回文本。
import javax.swing.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.awt.EventQueue;
import java.awt.event.*;
public class EditMe{
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>(1);
public void showEditor(){
JFrame frame = new JFrame("edit text");
JEditorPane pane = new JEditorPane("txt", "");
frame.add(pane);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener( new WindowAdapter(){
@Override
public void windowClosed(WindowEvent evt){
try{
queue.put(pane.getText());
} catch(InterruptedException e){
//not really possible, but just incase.
throw new RuntimeException(e);
}
}
} );
frame.setSize( 640, 480 );
frame.setVisible(true);
}
public static String getText() throws InterruptedException{
EditMe me = new EditMe();
EventQueue.invokeLater( ()-> me.showEditor() );
return me.queue.take();
}
public static void main(String[] args) throws Exception{
System.out.println("waiting for response");
String s = getText();
System.out.println("response received: \n" + s);
}
}
这大约相当于记事本的解决方案,但它使用的是标准jdk自带的swing。有一些无头的jdk不包含swing)。