为什么我要在 jtextfield 中追加两次?
why am i appending twice in jtextfield?
我查看了这段代码,但我不知道哪里出了问题。当我输入命令(任何输入)时,我总是得到不正确的输出。请看我代码的底部。
public class gui {
private final static javax.swing.JFrame frame = new javax.swing.JFrame();
private final static javax.swing.JPanel panel = new javax.swing.JPanel();
public final static javax.swing.JTextArea outtextArea = new javax.swing.JTextArea("");
public final static javax.swing.JTextField intextArea = new javax.swing.JTextField();
public static void main(String[] args) {
java.awt.Font font = new java.awt.Font(java.awt.Font.SANS_SERIF, java.awt.Font.PLAIN, 15);
String command;
/* Optional */
frame.setTitle("Console");
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(javax.swing.JRootPane.FRAME); // COMMENT THIS OUT WHEN COMPLETE
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); //if exit command, dispose() first
frame.setBackground(java.awt.Color.BLACK);
/* size */
frame.setMinimumSize(new java.awt.Dimension(0b001011010100,0b000110000100));
frame.setLocation(0,0);
frame.setExtendedState(javax.swing.JFrame.MAXIMIZED_BOTH);
/* Sets panel */
panel.setBackground(java.awt.Color.PINK); // if sees pink, has error
panel.setLayout(new java.awt.BorderLayout());
panel.setSize(frame.getWidth(),frame.getHeight());
/* Sets text area */
//javax.swing.JScrollPane inscrollPane = new javax.swing.JScrollPane(intextArea);
intextArea.setHorizontalAlignment(javax.swing.JTextField.LEFT);
intextArea.setFont(font);
intextArea.setBackground(java.awt.Color.BLACK);
intextArea.setForeground(java.awt.Color.GREEN);
intextArea.setFocusable(true);
javax.swing.JScrollPane outscrollPane = new javax.swing.JScrollPane(outtextArea);
outtextArea.setRows(10);
outtextArea.setLineWrap(true);
outtextArea.setFont(font);
outtextArea.setBackground(java.awt.Color.BLUE);
outtextArea.setForeground(java.awt.Color.GREEN);
outtextArea.setEditable(false);
/* Sets all necessary components */
frame.add(panel);
panel.add(outscrollPane,java.awt.BorderLayout.CENTER);
// panel.add(inscrollPane,java.awt.BorderLayout.SOUTH);
panel.add(intextArea,java.awt.BorderLayout.SOUTH);
/* Adjusts components */
frame.pack();
frame.setVisible(true);
//every time a command is entered, it is sent to handler and
//textbox should be cleared
// THIS BELOW IS WHERE THE PROBLEM LIES/////////////////////////////
boolean keepGoing=true;
while(keepGoing){
command = intextArea.getText();
String refactored;
if(entering_a_command(command) && !command.equals("exit")){
refactored=command.substring(0,command.length()-1);
outtextArea.append(refactored+"\n");
intextArea.setText("");
}
else if(!command.equals("exit")){//no need to read before submission
outtextArea.append("");
command=intextArea.getText();
}
else{
outtextArea.append("EXITING\n");
keepGoing=false;
}
}
}
/*
Method is strictly for entering user input at appropriate time
*/
private static boolean entering_a_command(String temp){
//handler.print(temp);
return temp.contains("="); //key to submit user input
}
}
我的输入:
- 12345=
- 123456=
- 这就是地狱=
- 这是你好=
我的预期输出:
- 12345
- 123456
- 这就是地狱
- 这是你好
我的实际输出:
- 12345
- 12345
- 这就是地狱
- 这就是地狱
我的问题:
当我第一次输入时,它全部检查出来。当我第二次输入比第一次输入更长的输入时,它会自动提交,就像我按下触发键 (=) 一样。
输入框就是下方的黑框。要提交输入,请按“=”
问题是您在滥用线程模型。您不应该在 UI 线程以外的线程中访问 UI 组件 - 像这样的紧密循环几乎 always 是个坏主意。您应该阅读 Swing threading model。来自该教程:
Swing event handling code runs on a special thread known as the event dispatch thread. Most code that invokes Swing methods also runs on this thread. This is necessary because most Swing object methods are not "thread safe": invoking them from multiple threads risks thread interference or memory consistency errors.
相反,您应该向文本区域添加一个事件侦听器。这里有 loads 个选项,不幸的是,其中 none 显然是理想的。添加密钥侦听器并处理 keyTyped
听起来不错 - 但您在 之前 收到事件,密钥最终出现在文本区域中,这并不理想。添加文档侦听器是一个很好的抽象,因为文本如何更改(例如以编程方式)并不重要 - 但您不能在侦听器中更改文档,因此您不能清除它。
作为起点,添加一个关键侦听器并处理 keyReleased
至少对于简单情况来说效果很好。摆脱当前循环(以及非常规命名的 entering_a_command
方法)并将它们替换为:
intextArea.addKeyListener(new java.awt.event.KeyAdapter() {
@Override public void keyReleased(java.awt.event.KeyEvent e) {
String command = intextArea.getText();
if (!command.contains("=")) {
return;
}
command = command.substring(0, command.length() - 1);
if (command.equals("exit")) {
frame.setVisible(false);
frame.dispose();
return;
}
outtextArea.append(command + "\n");
intextArea.setText("");
}
});
我查看了这段代码,但我不知道哪里出了问题。当我输入命令(任何输入)时,我总是得到不正确的输出。请看我代码的底部。
public class gui {
private final static javax.swing.JFrame frame = new javax.swing.JFrame();
private final static javax.swing.JPanel panel = new javax.swing.JPanel();
public final static javax.swing.JTextArea outtextArea = new javax.swing.JTextArea("");
public final static javax.swing.JTextField intextArea = new javax.swing.JTextField();
public static void main(String[] args) {
java.awt.Font font = new java.awt.Font(java.awt.Font.SANS_SERIF, java.awt.Font.PLAIN, 15);
String command;
/* Optional */
frame.setTitle("Console");
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(javax.swing.JRootPane.FRAME); // COMMENT THIS OUT WHEN COMPLETE
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); //if exit command, dispose() first
frame.setBackground(java.awt.Color.BLACK);
/* size */
frame.setMinimumSize(new java.awt.Dimension(0b001011010100,0b000110000100));
frame.setLocation(0,0);
frame.setExtendedState(javax.swing.JFrame.MAXIMIZED_BOTH);
/* Sets panel */
panel.setBackground(java.awt.Color.PINK); // if sees pink, has error
panel.setLayout(new java.awt.BorderLayout());
panel.setSize(frame.getWidth(),frame.getHeight());
/* Sets text area */
//javax.swing.JScrollPane inscrollPane = new javax.swing.JScrollPane(intextArea);
intextArea.setHorizontalAlignment(javax.swing.JTextField.LEFT);
intextArea.setFont(font);
intextArea.setBackground(java.awt.Color.BLACK);
intextArea.setForeground(java.awt.Color.GREEN);
intextArea.setFocusable(true);
javax.swing.JScrollPane outscrollPane = new javax.swing.JScrollPane(outtextArea);
outtextArea.setRows(10);
outtextArea.setLineWrap(true);
outtextArea.setFont(font);
outtextArea.setBackground(java.awt.Color.BLUE);
outtextArea.setForeground(java.awt.Color.GREEN);
outtextArea.setEditable(false);
/* Sets all necessary components */
frame.add(panel);
panel.add(outscrollPane,java.awt.BorderLayout.CENTER);
// panel.add(inscrollPane,java.awt.BorderLayout.SOUTH);
panel.add(intextArea,java.awt.BorderLayout.SOUTH);
/* Adjusts components */
frame.pack();
frame.setVisible(true);
//every time a command is entered, it is sent to handler and
//textbox should be cleared
// THIS BELOW IS WHERE THE PROBLEM LIES/////////////////////////////
boolean keepGoing=true;
while(keepGoing){
command = intextArea.getText();
String refactored;
if(entering_a_command(command) && !command.equals("exit")){
refactored=command.substring(0,command.length()-1);
outtextArea.append(refactored+"\n");
intextArea.setText("");
}
else if(!command.equals("exit")){//no need to read before submission
outtextArea.append("");
command=intextArea.getText();
}
else{
outtextArea.append("EXITING\n");
keepGoing=false;
}
}
}
/*
Method is strictly for entering user input at appropriate time
*/
private static boolean entering_a_command(String temp){
//handler.print(temp);
return temp.contains("="); //key to submit user input
}
}
我的输入:
- 12345=
- 123456=
- 这就是地狱=
- 这是你好=
我的预期输出:
- 12345
- 123456
- 这就是地狱
- 这是你好
我的实际输出:
- 12345
- 12345
- 这就是地狱
- 这就是地狱
我的问题: 当我第一次输入时,它全部检查出来。当我第二次输入比第一次输入更长的输入时,它会自动提交,就像我按下触发键 (=) 一样。
输入框就是下方的黑框。要提交输入,请按“=”
问题是您在滥用线程模型。您不应该在 UI 线程以外的线程中访问 UI 组件 - 像这样的紧密循环几乎 always 是个坏主意。您应该阅读 Swing threading model。来自该教程:
Swing event handling code runs on a special thread known as the event dispatch thread. Most code that invokes Swing methods also runs on this thread. This is necessary because most Swing object methods are not "thread safe": invoking them from multiple threads risks thread interference or memory consistency errors.
相反,您应该向文本区域添加一个事件侦听器。这里有 loads 个选项,不幸的是,其中 none 显然是理想的。添加密钥侦听器并处理 keyTyped
听起来不错 - 但您在 之前 收到事件,密钥最终出现在文本区域中,这并不理想。添加文档侦听器是一个很好的抽象,因为文本如何更改(例如以编程方式)并不重要 - 但您不能在侦听器中更改文档,因此您不能清除它。
作为起点,添加一个关键侦听器并处理 keyReleased
至少对于简单情况来说效果很好。摆脱当前循环(以及非常规命名的 entering_a_command
方法)并将它们替换为:
intextArea.addKeyListener(new java.awt.event.KeyAdapter() {
@Override public void keyReleased(java.awt.event.KeyEvent e) {
String command = intextArea.getText();
if (!command.contains("=")) {
return;
}
command = command.substring(0, command.length() - 1);
if (command.equals("exit")) {
frame.setVisible(false);
frame.dispose();
return;
}
outtextArea.append(command + "\n");
intextArea.setText("");
}
});