gpt4 book ai didi

java - Java中等待参数赋值

转载 作者:太空宇宙 更新时间:2023-11-04 11:57:15 25 4
gpt4 key购买 nike

我最近开始学习JAVA,并尝试创建一个类似shell的小程序(我不依赖系统shell来执行命令)。

我设法让基本的 I/O 工作正常工作,但我陷入了以下情况:

假设我使用命令“makeFile path/to/file”,该命令将检查文件是否存在并询问“文件已存在!您想删除它吗?Y/N”

我的问题是等待用户输入 Y、N 或其他任何内容而不锁定 shell 界面(A JTextArea)。

import java.util.StringTokenizer;

public abstract class Command {

private final String bin;
protected Shell shell;

public Command(Shell shell, final String bin) {
this.shell = shell;
this.bin = bin;
}

String getBin() {
return this.bin;
}

protected String ask(String question) {
shell.setQuestionAsked(true);
shell.setResponse("");
shell.write(question);
String response = shell.getResponse();

while(response.isEmpty()) {
response = shell.getResponse();
}

shell.setQuestionAsked(false);
return response;
}

public abstract void execute(StringTokenizer stringTokenizer);
}

我尝试在并发/线程中寻找解决方案,但找不到解决方案。

在 @Holger 注释中,这是 GUI 代码部分,您可以看到监听器已经存在。我的问题在于,当命令使用上面显示的ask方法询问用户输入时,执行将不会等待用户输入,而是继续执行或在当前的while(response.isEmpty())中导致死锁。

所以我正在寻找一种解决方案来保持ask()方法的执行,直到用户在GUI中按回车键。

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;


public class ShellPanel extends Shell {

private JTextArea shellArea;
private JPanel panel;
private JScrollPane scrollPanel;

private int bufferLength = 0;
private String oldText = "";

ShellPanel() {


shellArea.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);

switch (e.getKeyCode()) {

case KeyEvent.VK_UP:
case KeyEvent.VK_DOWN:

e.consume();

break;
case KeyEvent.VK_LEFT:

if (shellArea.getCaretPosition() <= bufferLength) {
e.consume();
}

break;

case KeyEvent.VK_BACK_SPACE:

if (shellArea.getText().length() <= bufferLength) {
e.consume();
}

break;
case KeyEvent.VK_DELETE:
break;
case KeyEvent.VK_ENTER:
read(getNewInput());
updateReferences();
e.consume();
break;
case KeyEvent.VK_HOME:
shellArea.setCaretPosition(bufferLength);
break;
}

}

});

shellArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);

switch (e.getButton()) {
case MouseEvent.BUTTON3:

String selected = shellArea.getSelectedText();
StringSelection selection = new StringSelection(selected);

if (!selected.isEmpty()) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
}

try {
String clip = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);

if (!clip.isEmpty()) {
shellArea.append(clip);
}

} catch (UnsupportedFlavorException | IOException e1) {
e1.printStackTrace();
}
break;
}
}
});
init();
updateReferences();
}

JPanel getPanel() {
return panel;
}

private void updateReferences() {
oldText = shellArea.getText();
bufferLength = oldText.length();
shellArea.setCaretPosition(bufferLength);
}

@Override
public void write(String content) {
shellArea.append(content);
updateReferences();
}

private String getNewInput() {
return this.shellArea.getText().replace(this.oldText, "");
}

@Override
public void clear() {
this.shellArea.setText("");
}
}

谢谢

最佳答案

通常,您应该避免必须等待 UI 事件的程序逻辑,而不是让适当的事件监听器触发后续操作。

等待逻辑类似于打开模式对话框,而打开方法将在对话框关闭时返回。对于JOptionPane.showInputDialog,它甚至会返回输入的值。此逻辑已在 Java 7 中抽象化,以允许任意“等待事件”场景。这是一个独立的示例:

public class WaitForInput {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame frame=new JFrame("Example");
JTextArea ta=new JTextArea(20,40);
ta.setEditable(false);
frame.setContentPane(new JScrollPane(ta));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
char result = waitForInput(ta, "Press Y or N",
ch -> Character.toUpperCase(ch)=='Y' || Character.toUpperCase(ch)=='N');
waitForInput(ta,
"You pressed "+result+", press Enter to continue", ch -> ch==10);
ta.append("Ok, I'm happy... Close window to quit");
});
}
static char waitForInput(JTextArea ta, String message, IntPredicate p) {
ta.append(message);
ta.append("\n");
SecondaryLoop loop = ta.getToolkit().getSystemEventQueue().createSecondaryLoop();
final class WaitOp extends KeyAdapter {
char actualChar;
public void keyTyped(KeyEvent e) {
if(p.test(e.getKeyChar())) {
actualChar=e.getKeyChar();
loop.exit();
}
}
}
WaitOp op = new WaitOp();
ta.addKeyListener(op);
loop.enter();
ta.removeKeyListener(op);
return op.actualChar;
}
}

但必须强调的是,与模式对话框不同,没有视觉指示器表明有一个 Action 在中间停止,等待特定的输入(除非您自己编程)。此外,UI 的其余部分不会被阻止,并且可能会产生新的操作,这些操作也可能会在中间停止,等待不同的事件,从而使程序处于不可维护的状态。

这就是为什么应该尽可能避免这种情况。但如果您将其使用限制在可维护的最低限度,它可能会非常有用。

关于java - Java中等待参数赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41261050/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com