JTextArea won't read in text properly - java

I can not seem to get this to work. My assignment will only let us use JTextAreas.
The issue with my code is that I can not read it text in the TextArea. The goal is to run the logic after the user types in ENTER after they type in their input.
When I run the code I can only type in one character.. and the the GUI presents the character after a zero for reasons I can not figure out. Ex: [0b ] will be in the TextArea. Please help I can't figure this out.
public class ArabicToRomanGUI extends JFrame
{
private static final long serialVersionUID = 1L;
private JTextArea enterRomanNumber = new JTextArea();
JLabel label = new JLabel();
JPanel panel = new JPanel();
JFrame frame = new JFrame();
//TestArea contructor adds jtextArea to jframe
public ArabicToRomanGUI()
{
super("Convert a Roman Numeral");
setLayout(new FlowLayout());
//Text field to enter a roman numeral
enterRomanNumber = new JTextArea(1,25);
enterRomanNumber.setText("Delete this text and Enter a Roman Numerial Here!");
//enterRomanNumber.setAlignmentX(0);
//enterRomanNumber.setAlignmentY(0);
add(enterRomanNumber);
HandlerForTextArea handler = new HandlerForTextArea();
enterRomanNumber.addKeyListener(handler);
}
private class HandlerForTextArea implements KeyListener
{
//used to process text field events
#Override
public void keyTyped(KeyEvent e)
{
String userInput = "";
userInput = enterRomanNumber.getText();
userInput = userInput.toUpperCase();
ConversionLogic.ConvertFromRomanToArabic(userInput); //converts user string of Roman numerals to an int in arabic
String arabicNumberAsString = ConversionLogic.getConvertedRomanNumeral();
enterRomanNumber.setText(arabicNumberAsString);
//user pressed enter in JTextField enterNumberField
if(e.getKeyCode() == KeyEvent.VK_ENTER)
{
//enterRomanNumber.setText(arabicNumberAsString);
if (ConversionLogic.getCheckFail() == true)
{
JOptionPane.showMessageDialog(frame, "The Roman Numeral entered is Invalid", "Error", JOptionPane.ERROR_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(frame, "The arabic equivalent is " + arabicNumberAsString + "." , "Conversion Successful", JOptionPane.PLAIN_MESSAGE);
}
}
}
#Override
public void keyPressed(KeyEvent e) {
//not used
}
#Override
public void keyReleased(KeyEvent e) {
//not used
}
}//end inner class TextFieldHandler
}//end class ArabicToRomainGUI

As you'll read time and time again on this site -- don't use a KeyListener with a text component such as a JTextArea as this can mess up the functioning of the text component. Instead use a DocumentListener for when you wish to detect changes to the state of the JTextArea after it happens, or a DocumentFilter if you wish to detect (and possibly change) changes to the text component before it is posted to the text component.
I see that you're using a JTextArea(1, 25), or a single-line JTextArea, which makes me ask: why not use a JTextField? If you do this and want to trap the ENTER key press, then you can simply add an ActionListener to the JTextField.

Related

Use KeyListener in a loop

I don't have a lot of experience with KeyListeners but I used one in my application and it works fine except I need to wait for input before my program can continue. For this I made a while loop that loops until the String temp is not null (which would mean there would be input).
The problem is there is no way to type in the JTextField (called input). Below is code from my two methods that are supposed to work together so that the text in my JTextField (input) can be returned (as temp). I'm not sure why this doesn't work or how to fix it.
The keyPressed method for my KeyListener:
public void keyPressed(KeyEvent e)
{
//only sends text if the enter key is pressed
if (e.getKeyCode()==KeyEvent.VK_ENTER)
{
//if there really is text
if (!input.getText().equals(""))
{
//String temp is changed from null to input
temp=input.getText();
//text sent to another JTextField
output.append(temp+"\n");
//input no longer has text
input.setText("");
}
}
}
The method thats trying to get text, also in my KeyListener class
public String getTemp()
{
booleans isNull=temp==null;
//loops until temp is not null
while (isNull)
{
//unnecessary line of code, only used so the loop not empty
isNull=checkTemp();
}
return temp;
}
public boolean checkTemp()
{
return temp==null;
}
Your while loop is a common console program construct, but understand that you're not creating a console program here but rather an event-driven GUI, and in this situation, the while loop fights against the Swing GUI library, and you need to get rid of it. Instead of a while loop with continual polling you now want to respond to events, and if you're listening for user input into a JTextField do not use a KeyListener as this low-level listener can cause unwanted side effects. Instead add a DocumentListener to the JTextField's Document.
Edit: You're listening for the enter key, and so the solution is even easier: add an ActionListener to the JTextField!
e.g.,
input.addActionListener(e -> {
String text = input.getText().trim();
if (text.isEmpty()) {
return;
}
output.append(text + "\n");
input.setText("");
});
More complete example:
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ChatBox extends JPanel {
private static final int COLS = 40;
private JTextField input = new JTextField(COLS);
private JTextArea output = new JTextArea(20, COLS);
private JButton submitButton = new JButton("Submit");
public ChatBox() {
output.setFocusable(false); // user can't get into output
JScrollPane scrollPane = new JScrollPane(output);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
ActionListener inputListener = e -> {
String text = input.getText().trim();
if (text.isEmpty()) {
return;
}
output.append(text + "\n");
input.setText("");
input.requestFocusInWindow();
};
input.addActionListener(inputListener);
submitButton.addActionListener(inputListener);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
bottomPanel.add(input);
bottomPanel.add(submitButton);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
ChatBox mainPanel = new ChatBox();
JFrame frame = new JFrame("Chat Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

How to enter a specific word in a textfield

what do I have to add to the code below so that the user has to enter a specific word i.e. "London" to open the JOptionPane input dialog box.
JFrame frame = new JFrame("JTextField");
JTextField textfield = new JTextField(30);
frame.add(textfield);
At the moment I can type in anything in the text field and the dialog box will appear. I only want it to open if the user enters a specific word.
I'm using the action event with action listener and action performed to open the JOptionPane Dialog box.
public class Test9 {
public static void main(String[] args) {
JFrame frame = new JFrame("JTextField");
JTextField textfield = new JTextField(30);
frame.add(textfield);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,200);
JPanel panel = new JPanel();
frame.add(panel);
panel.add(textfield);
textfield.addActionListener(new Action4());
}
}
You can do something like this.
if(museum_name.equals("London")){
JOptionPane.showMessageDialog(null, " You are attending the " + museum_name);
} else{
// show the error message
}
Its encouraged to use equals() method for String comparison. Please note, equals() is used to compare two strings for equality, while operator == compares the reference of an object in java.
Update
To show an error message if the input is not "London", you can do something like this.
static class Action4 implements ActionListener {
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
String museum_name = ((JTextField) e.getSource()).getText();
if (museum_name.equals("London")) {
JOptionPane.showMessageDialog(null, "You are attending the " + museum_name);
} else {
JOptionPane.showMessageDialog(null, "Wrong input!");
}
}
}

How can i get my program to reply with an answer

I'm working on a program that you can have a conversation with so I could ask it hello and it would reply.
But when typing in the text field I can't seem to get it to display the answer in the other text field.
here is my code so far any help is useful
public class Gui extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField input, output;
private String answer;
private JPanel contentpanel;
boolean opchosen = false;
public Gui() {
super("Vixen");
input = new JTextField(null, 20);
output = new JTextField(null, 20);
question q = new question();
input.addActionListener(q);
contentpanel = new JPanel();
contentpanel.setBackground(Color.lightGray);
contentpanel.setLayout(new FlowLayout());
contentpanel.add(input, BorderLayout.NORTH);
input.setEditable(true);
contentpanel.add(output, BorderLayout.SOUTH);
output.setEditable(false);
this.setContentPane(contentpanel);
}
private class question implements ActionListener {
public void actionPerformed(ActionEvent Event) {
JTextField input = (JTextField) Event.getSource();
if (input.equals("whats you name")) {
if (opchosen == false) {
if (answer == null) {
answer = "My name is Vixen!";
}
}
}
if (opchosen == false) {
output.setText(answer);
}
}
}
}
}
Okay that problem is fixed but when i try to ask another question my output box wont display the new answer its just stuck on My name is Vixen
Use your JTextField for input only. In the text field's actionPerformed() implementation, append() the input text and the response to an adjacent JTextArea. This example illustrated the basic approach. In the example, responses come from another socket; yours will come from code that handles canned responses.

How to print a string on the same window I typed and not in a popup in Java

So, this is my code:
import java.awt.*;
import javax.swing.*:
public class NewClass extends JFrame{
private JTextField item1;
private JTextField item3;
private JTextField item4;
public NewClass(){
super("The title");
setLayout(new FlowLayout());
item3 = new JTextField("Agrega el nombre del evento y da Enter", 22);
item3.setEditable(false);
add(item3);
item1 = new JTextField(22);
add(item1);
thehandler handler = new thehandler();
item1.addActionListener(handler);
item3.addActionListener(handler);
item4.addActionListener(handler);
}
private class thehandler implements ActionListener{
public void actionPerformed(ActionEvent event){
String string = "";
if(event.getSource()==item1)
string=String.format("Process ready: %s", event.getActionCommand());
else if(event.getSource()==item3)
string=String.format("field 3:%s", event.getActionCommand());
JOptionPane.showMessageDialog(null, string);
}
}
}
And this is my main:
import javax.swing.JFrame;
public class ProyectoSOD {
public static void main(String[] args) {
NewClass odioSOD = new NewClass();
odioSOD.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
odioSOD.setSize(300, 350);
odioSOD.setVisible(true);
}
}
What I want to do, is to have the text in the TextField(from item3) saved unto another TextField with .setEditable(false) in the same window so I can write a text line(on item3), press enter, and have it saved in the same window, then rewrite the line, press enter, and have it shown with the previous text. I wanna be able to stack all this text everytime I press enter.
My current program has the message shown in a popup window, but I need to stack multiple lines.
Thanks :)
I'm not sure what you're looking to do. If you want to keep track of everything entered into the textfield, like a history of input, you could do what Eric Jablow said and use a JTextArea. So when the user enters input into the textfield and hits enter, it'll append the text from the textfield into the textarea.
http://docs.oracle.com/javase/tutorial/uiswing/components/textarea.html
That might be a good place to start.

JTextArea pressing enter adds unnecessary new line

I'm developing a chat application and when I press an enter button when focusing the JTextArea I want it to stop adding the unnecessary new line of text, so for example i will be able to determine when user has pressed the enter button and not typed anything inside the JTextArea. I am using a KeyListener for the means of detecting when an user has released the enter key and then sending the message. I firstly tried replacing the new line of text with an empty string message.replaceAll("[\n]", "") and also trimming the message, however it didn't work. Is there anything i'm doing wrong with my approach or would there be any other solution i could adapt?
Don't use a JTextArea for this, but instead use a JTextField.
You can then easily listen for the enter press by giving the JTextField an ActionListener.
Most Swing chat applications I've seen use two text components for this: a JTextArea to display incoming text and your sent text, and a JTextField to allow user input of the text to send.
Usually one is right on top of the other using a BorderLayout.
If you absolutely must use a JTextArea, then you will probably want to use Key Binding to capture the enter key and deal with it. Check out the How to use Key Bindings Tutorial.
For example:
Example Key Bindings Solution:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class CaptureTextAreaEnter extends JPanel {
private static final int COLS = 30;
private static final int VIEW_ROWS = 12;
private static final int ENTER_ROWS = 4;
private JTextArea chatViewArea = new JTextArea(VIEW_ROWS, COLS);
private JTextArea chatEnterArea = new JTextArea(ENTER_ROWS, COLS);
public CaptureTextAreaEnter() {
setLayout(new BorderLayout());
add(new JScrollPane(chatViewArea), BorderLayout.CENTER);
add(new JScrollPane(chatEnterArea), BorderLayout.SOUTH);
chatViewArea.setFocusable(false);
chatViewArea.setWrapStyleWord(true);
chatEnterArea.setWrapStyleWord(true);
chatViewArea.setLineWrap(true);
chatEnterArea.setLineWrap(true);
// start our set up of key bindings
// to get the correct InputMap
int condition = WHEN_FOCUSED;
// get our maps for binding from the chatEnterArea JTextArea
InputMap inputMap = chatEnterArea.getInputMap(condition);
ActionMap actionMap = chatEnterArea.getActionMap();
// the key stroke we want to capture
KeyStroke enterStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
// tell input map that we are handling the enter key
inputMap.put(enterStroke, enterStroke.toString());
// tell action map just how we want to handle the enter key
actionMap.put(enterStroke.toString(), new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
String text = chatEnterArea.getText();
chatEnterArea.setText("");
chatViewArea.append(text + "\n");
// *** you will want to send text to your
// *** PrintStream to the chat server here
}
});
}
private static void createAndShowGui() {
CaptureTextAreaEnter mainPanel = new CaptureTextAreaEnter();
JFrame frame = new JFrame("CaptureTextAreaEnter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This is the solution that functioning perfectly for my system.
AddTxtA.getDocument().putProperty("filterNewlines", Boolean.TRUE);
**When user press on the "Enter" button in the JTextArea, a blank space will be input instead of new line. Below shown the sample output for two different situations.
1) Without AddTxtA.getDocument().putProperty("filterNewlines", Boolean.TRUE);.
OUTPUT: "My name
is Adam."
2) With AddTxtA.getDocument().putProperty("filterNewlines", Boolean.TRUE);.
OUTPUT: "My name is Adam."
To replace the standard behaviour of "enter" key you should use the Input/Action maps of your text area
See the method registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition). As action listener you should take the Action from your "send" button, command is a string your choise, key-stroke is KeyStroke.getKeyStroke(KeyEvent.VK_ENTER) and condition is JComponent.WHEN_FOCUSED.

Categories