I would like to know the best way to approach what I am trying to achieve, I can't figure out the logical path I should take.
I have a JTextField and a JTextButton, when input is added to the JTextField and either enter or the button is pressed, it will display on the JTextArea. Now, what I want is to choose when and what the JTextArea and Button do.
For example I want default Enter & Button to display next append text in my code. Then when a case is presented I want the JTextField to only accept either int or string and then once completed, I want it to go back to default.
I don't know if what I am trying to do is logical or best practice...
The idea behind this is, I have a story text based gui game. I want it to display text to the JTextArea and when Enter or button is pressed to display the next line of text and when in the story it requires user input, the JTextArea will look for that input.
So far I have an EventListener and ActionListener which submits what I type from JTextField to JTextArea, but that is about it.
Thanks for your assistance! I have solved my issue, not sure if this is the "Best Solution". I combined your solution with a bit of tweaking.
In this instance, buttonState is an int which can be changed throughout my code by calling a constructor "setButtonState". I could have made buttonState a static to make things easier, but thought I could keep things clean.
enterButton.addActionListener(new ActionListener()
{ //This is used so when the enter screen button is pressed, it will submit text from text field to text area.
public void actionPerformed(ActionEvent e) {
String text = inputTextField.getText();
InputTextFieldEvent event = new InputTextFieldEvent(this, text);
if (buttonState == 0) //Displays all text in JTextField to JTextArea, mostly for testing purposes.
{
if (textInputListener != null) {
textInputListener.setInputListenerOccurred(event);
}
}
if (buttonState == 1) //Only accepts string for answer
{
if (inputTextField.getText().matches("[a-zA-Z]+"))
{
textInputListener.setInputListenerOccurred(event);
}
else
{
getAppendMainTextArea("You have entered an invalid input, only letters are allowed.");
}
}
if (buttonState == 2) //Only accepts int for answer
{
if (inputTextField.getText().matches("[0-9]+"))
{
textInputListener.setInputListenerOccurred(event);
}
else
{
getAppendMainTextArea("You have entered an invalid input, only numbers are allowed.");
}
}
}
});
Related
I need the same JButton to perform a different actions once it's clicked again. Like the first time I click the button, a text will appear in the first row of my JTextField, then the second time I click it, a text will appear in the second row if text field. How should I do it?
Here is my code BTW:
private void addActionPerformed(java.awt.event.ActionEvent evt) {
String items1 =(String)list.getSelectedItem();
String qty1 = qty.getText();
String price1 = price.getText();
int qty2 = Integer.parseInt(qty1);
int price2 = Integer.parseInt(price1);
if(evt.getSource() == add){
order1.setText(Integer.toString(qty2));
order2.setText(Integer.toString(price2));
order3.setText(items1);
}
I literally have no idea what to do next.
Here is the pic for the design GUI: http://prntscr.com/pfh96z
Take a Boolean isClickedOnce and change its state upon clicking on your button
private Boolean isClickedOnce = false;
//..
private void addActionPerformed(java.awt.event.ActionEvent evt) {
if(!isClickedOnce) {
//first click
//..
} else {
//second click
//..
}
isClickedOnce = !isClickedOnce;
}
Note: it'll consider every odd number click as first click and every even number of click as second click. it will toggle through your first and second row.
If your case is different lets say you have n number of rows, above procedure won't work and you might wanna do something similar with a list.
Im creating a GUI program with multiple buttons. I'm only able to use one of the buttons at the moment. Here is my Button Listener class. I want to be able to use the "Test" button and then use the "Yes" or "No" button after. Let me know if you need to see any more of my code.
public class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==TestButton)
{
TestWord = (Text_Input.getText());
StringBuilder RevTestWord = new StringBuilder();
RevTestWord.append(TestWord);
RevTestWord = RevTestWord.reverse();
DisplayText = "Is " + RevTestWord + " a real word?";
Test_Anadrome.setText(DisplayText);
if(e.getSource()==YesButton)
{
DisplayText = "Word added to Anadrome list.";
Test_Anadrome.setText(DisplayText);
}
if(e.getSource()==NoButton)
{
DisplayText = "Type a different word and press the 'Test Word' Button.";
Test_Anadrome.setText(DisplayText);
}
}
}
}
Sorry I'm pretty new to Java.
It looks like your if/else statements for your YesButton and NoButton are inside of your if statement for TestButton, so as a result those statements are only being checked if source==TestButton. Try moving this code outside of the if statement:
if(e.getSource()==YesButton)
{
DisplayText = "Word added to Anadrome list.";
Test_Anadrome.setText(DisplayText);
}
if(e.getSource()==NoButton)
{
DisplayText = "Type a different word and press the 'Test Word' Button.";
Test_Anadrome.setText(DisplayText);
}
You need to have all your testing at the same level. The nested ifs are causing problems. And remember to use if/else. No sense in continuing to do other checks if the previous one succeeds.
You can also set the ActionCommand which is a String. For components that use the actionListener, you can do for example button.setActionCommand("mycommand").
Then in the actionPerformed(ActionEvent e) you can do
String cmd = e.getActionCommand();
That allows you do discern between buttons or other components without having direct access to their instance.
If you don't set the ActionCommand it defaults to the button's text.
Well, I decided to edit everything. So, the code goes like this:
public void actionPerformed(ActionEvent e) {
if (!uiCreator.getTextArea().getText().equalsIgnoreCase("Beggining text")) {
JOptionPane.showMessageDialog(null, "You must have main method first", "Error",
JOptionPane.ERROR_MESSAGE);
} else {
n = Integer.valueOf(JOptionPane.showInputDialog("..."));
l = Integer.valueOf(JOptionPane.showInputDialog("..."));
uiCreator.getTextArea()
.setText("Beggining text with few additions");
On the code above, I made it to check if JTextArea contains text that is needed and if it doesn't it will show an error message. If it does it will set a text with few more words.
Now. I also have more JButtons. So if one is clicked, it will also do the same thing. Check the text and if it meets all conditions, set new modified text. But, now, my problem comes here. I have this:
public void actionPerformed(ActionEvent e) {
if (!uiCreator.getTextArea().getText()
.equalsIgnoreCase("Beggining text with few additions")) {
JOptionPane.showMessageDialog(null, "Error, you don't have main or JFrame inside main", "Error",
JOptionPane.ERROR_MESSAGE);
} else {
uiCreator.getTextArea()
.setText("Beggining text with even more additions");
}
Which checks if JTextArea had "Beggining text with few additions" and if it did, change the text to Beggining text with even more additions. I have few more buttons that do the same thing. Now, I would like to know a way to let setText(some text) method be used regardless is there Beggining text with few additions or Beggining text with even more additions.
Don't use setText(...) to keep replacing all the text.
Instead you can use methods like:
replaceSelection(...);
getDocument().insertString(...);
to change part of the text or insert new text.
I have a public class JdbDateTextField extends JTextField and in the constructor I add this.setInputVerifier(new ValidDateOrEmptyVerifier());.
I use class ValidDateOrEmptyVerifier extends InputVerifier to verify the format of the input.
If the input is in the wrong format and the user looses the focus of the JdbDateTextField, I return false in the ValidDateOrEmptyVerifier and the focus is gained again to the JdbDateTextField again.
This works if the user switches from the JdbDateTextField to another textField or presses a Button. If pressing a button and the format of the input in the is wrong then no action for the button is performed and the focus is still at the JdbDateTextField.
This is exactly what I want. The user can not leave the JdbDateTextField until he enters a valid string.
The problem is that the JdbDateTextField is in a JPanel which is in a JTabbedPane so I have a GUI with several tabs.
If I have the JdbDateTextField selected, enter a invalid input and then directly click on another tab it still switches the tab. So I was able to provide a wrong input.
My Question is:
Is there a way to perform an Input Verification which does not allow to execute any other event before it is true
The best solution I can think of is to assign the JTabbedPane a custom selection model which refuses to allow changing tabs unless the current InputVerifier succeeds:
int index = tabbedPane.getSelectedIndex();
tabbedPane.setModel(new DefaultSingleSelectionModel() {
#Override
public void setSelectedIndex(int index) {
Component focusOwner =
FocusManager.getCurrentManager().getFocusOwner();
if (focusOwner instanceof JComponent) {
JComponent c = (JComponent) focusOwner;
InputVerifier verifier = c.getInputVerifier();
if (verifier != null && !verifier.shouldYieldFocus(c)) {
return;
}
}
super.setSelectedIndex(index);
}
});
tabbedPane.setSelectedIndex(index);
I hope that I can do this as an answer:
The solution above works for the JTabbedPane
But I can still select other GUI elements.
My Application is build like this:
For every Person ID I show other Birthdate values in the JTabbedPane
and I can still switch to another Person ID if the ValidDateOrEmptyVerifier returns false.
So is there a way to disallow all events in the Main Frame until the ValidDateOrEmptyVerifier returns true.
So Basically what I want is that the user can only exit the "Birthdate" JdbDateTextField if he enters a valid Date or the field is empty.
I'm trying to transfer focus from one JTextArea to another when the user hits tab.
Currently I'm using this code:
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == KeyEvent.VK_TAB){
enterTextArea.transferFocus();
}
}
This appears to work - the focus moves and you type in the next JTextArea - but actually the text stills gets appened to the first TextArea, meaning that performing a getText() on the second TextArea just returns "".
How do I make the text typed go to the second JTextArea rather than just get appended to the first?
EDIT: On further inspection this behavior was caused by a separate bug. No further help needed.
You can just transfer the text from 1 to 2 by using getText on the first one.
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == KeyEvent.VK_TAB){
enterTextArea.transferFocus();
String firstField = textField1.getText();
secondField.setText(firstField);
}
}
That way it will save from the first text area, and put it into the second one.
Hope this helps!