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.
Related
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.");
}
}
}
});
This is a really simple code where when I click a button, the text on the button becomes "..." which is a string variable called move.
What I'm trying to figure out is if it is possible to check the text of a button in the if (e.getSource()==) command.
JButton [] button;
String move="...";
button =new JButton[25];
for (int a=0;a<25;a++)
{
button[a]=new JButton();
p1.add(button[a]);
button[a].addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
for (int a=0; a<25;a++)
{
if (e.getSource()==button[a])
{
button[a].setText(move);
}
}
}
So after the code above, a button will have the text "..." on it. Now what I want for the next if (e.getSource()==) command is: if the button I click has the text (move), run the code.
I tried hundreds of random codes to see if they'll work but no luck:
sort of like this:
if (e.getSource()==button[a].text(move))
OR
if (e.getSource()==button[a].getText.equals(move))
if (The button i click has the text (move) it will run this code)
{
button[a].setBackground(Color.GREEN);
}
I'm fairly new to programming and I need this for my Checkers game.
Is it possible to do what I am asking for?
String comparison in Java should be done with .equals() not ==.
Maybe you mean like this:
if (e.getSource() == button[a]) {
if (button[a].getText().equals(move)) {
// do some logic here
button[a].setBackground(Color.GREEN);
}
}
The examples you have checking the source against the button text doesn't make a lot of sense. You're adding an action listener on the button not a field of the button. Additionally, getSource returns an Object so if you need to get to any of its member values you'll need to cast it to the type it should be. In your case you're returned an Object with an actual type JButton.
JButton button = new JButton("Hello");
button.addActionListener((e) -> System.out.println(
e.getSource() instanceof JButton
));
button.doClick();
true
So, given a button you can get the text like so:
JButton button = new JButton("Hello");
button.addActionListener((e) -> System.out.println(
((JButton)e.getSource()).getText()
));
button.doClick();
Hello
So, to check move against it would be like so:
String move = "Howdy";
JButton button = new JButton("Hello");
button.addActionListener((e) -> System.out.println(
((JButton) e.getSource()).getText().equals(move)
));
button.doClick();
false
Another thing to note is when you get an instance of a button through getSource you don't need to find that instance in the array before using it; it's returned to you via the action listener. For example, run this code:
JButton[] buttons = new JButton[10];
Random r = new Random(System.currentTimeMillis());
String newText = "New";
for (int i = 0; i < buttons.length; ++i) {
buttons[i] = new JButton(String.valueOf(r.nextInt()));
buttons[i].addActionListener((e) -> ((JButton)e.getSource()).setText(newText + " " + r.nextInt()));
}
Arrays.stream(buttons).forEach(b -> {
System.out.println(b.getText());
b.doClick();
System.out.println(b.getText());
});
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.
Ok, I'm new to listeners (still learning the language), and this is my first full-scale attempt to implement them (ie more than just a practice problem in a textbook).
So far, everything is working fine except one big bug: the checkboxes don't stay checked. The ItemListener I assign them runs perfectly (I have a JOptionPane set up to trigger to let me know if it's working or not), but the box itself doesn't stay checked.
I went even further and added conditional logic for if it's state is checked versus unchecked, and found that when I click the box BOTH states get triggered. So I get both JOptionPane popups, the one with the message for if the box is checked and the one for if the box isn't checked.
I'm including my code here. What am I doing wrong?
PS. You'll notice that the code has conditional logic to either add a radio button or a checkbox. When the program finally runs, this component is generated in multiple locations in both formats. The radio button works fine, it's the checkbox ones that I'm having the above issue with.
CODE THAT CREATES THE CHECKBOXES AND ASSIGNS THE LISTENERS:
public OtherField(int voteFor){
this.voteFor = voteFor;
otherPanel = new JPanel();
otherPanel.setLayout(new GridLayout(1, 3));
otherField = new JTextField(10);
otherField.setHorizontalAlignment(SwingConstants.CENTER);
JLabel otherLabel;
otherLabel = new JLabel("Other", SwingConstants.CENTER);
otherRadio = new JRadioButton("", false);
otherRadio.setHorizontalAlignment(SwingConstants.CENTER);
otherRadio.addActionListener(new OtherFieldRadioListener());
otherCheckBox = new JCheckBox("");
otherCheckBox.setHorizontalAlignment(SwingConstants.CENTER);
otherCheckBox.addItemListener(new OtherFieldCheckBoxListener());
otherPanel.add(otherLabel);
otherPanel.add(otherField);
if(voteFor == 1){
otherPanel.add(otherRadio);
}else{
otherPanel.add(otherCheckBox);
}
}
LISTENER CODE (it's a private class in the same class as the code above):
private class OtherFieldCheckBoxListener implements ItemListener{
public void itemStateChanged(ItemEvent e){
String name = otherField.getText();
if(e.getStateChange() == ItemEvent.SELECTED){
JOptionPane.showMessageDialog(null, name);
}else{
JOptionPane.showMessageDialog(null, "Not Selected");
}
}
}
First thing I would try is to set the checkbox either to true or false when you initialize it, i.e
otherCheckBox.setSelected(false)
If this does not work I would check whether OtherField gets called from somewhere else everytime the checkbox is selected and thus the components are redrawn/ the selection is reset (use the debugger and set a breakpoint at the beginning of OtherFields)
i have four JRatioButtons inside a ButtonGroup in Java. The two first are enabled and the other two are disabled. If one specific JRatioButton is selected i need to enable the two disabled JRatioButtons.
Im trying this to find the state of the buttons and enable the disabled ones, apparently i found the ones with the disable state but doesnt change that state.
private void activateButtons() {
Enumeration<AbstractButton> elements = myButtonGroup.getElements();
while (elements.hasMoreElements()) {
AbstractButton button = (AbstractButton)elements.nextElement();
if (button.isEnabled()) {
System.out.println("This button is disabled! The text of the button is: '" + button.getText() + "'");
button.setEnabled(true);
}
}
}
Im getting the text of the disabled buttons, but i cant disable them.
Any help? Thanks!
I don't know if you any problems in finding the reference of the radio buttons in the second group or you just cannot disable the radio buttons.
For the first question, it is simple, you just keep the reference of the radio buttons in the second group.
For the second question, you need to subclass a JRadioButton because I found you can not simply call disable for an object of radio button.
The code sample of the sub class would be like this.
this.editable = editable;
if (editable) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
super.enableEvents(Event.MOUSE_DOWN | Event.MOUSE_UP);
} else {
this.setCursor(CursorFactory.createUnavailableCursor());
super.disableEvents(Event.MOUSE_DOWN | Event.MOUSE_UP);
}
Try this, it works.
AbstractButton button = ...
button.getModel().setEnabled(true/false)
Ya, you setEnabled(true) to an enabled RadioButton.
So here the edited, hope can help someone.
private void activateButtons()
{
Enumeration<AbstractButton> elements = myButtonGroup.getElements();
while (elements.hasMoreElements())
{
AbstractButton button = (AbstractButton)elements.nextElement();
if (button.isEnabled()) // if enabled (true)
{
System.out.println("This button is disabled! The text of the button is: '" + button.getText() + "'");
button.setEnabled(false); // set it disabled (false)
}
}
}
Thanks #Hannibal, your post saved my day.