As i have seen many answers are too obscure for a entry level student like me.
i am following the steps by first addActionListner(this) to my JTextField.
what i am trying to do next and confuses the most is under:
public void actionperformed(Actionevent ae){
if(ae.getSource() == "Enter pressed")
{
outArea.setText(result);
}
}
which does not work because i feel like the code ae.getSource() == "Enter presses" is not working correctly and even i replaced the action i took under actionPerformed by a simple print line command like System.out.println("working"), it won't execute.
here is what i do if a button is pressed.
public void actionperformed(Actionevent ae){
if(ae.getSource() == "JButton")
{
System.out.println("JButton was pushed");
}
}
no matter how, lets say i have a GUI with a piece of given code like these:
public static void main(string[] args){
new myProg();
}
public myProg(){
....
buildTheGUI();
...}
}
//GUI Objects
...
JTextField input = new JTextField(10);
...
//method building the GUI
public void buildTheGUI(){
...
input.addActionListner(this);
...
//a method called actionPerformed
public void actionperformed(Actionevent ae){
}
i am now trying to detect the enter key by actionListner not by any other method because it's given.
Firstly, actionPerformed is triggerd by an action event, typically on most systems, this is triggered by the Enter key (with context to the JTextField)...so you don't need to check for it.
Secondly, the source of the ActionEvent is typically the control that triggered it, that would be the JTextField in this case.
Thirdly, String comparison in Java is done via the String#equals method...
if ("Enter presses".equals(someOtherString)) {...
Your actionPerformed method for the Button is wrong, try better this:
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() instanceof JButton) {
JButton button = (JButton) e.getSource();
System.out.println("This button was pushed: " + button.getText());
}
}
And your for KeyListener try this to learn how it works:
#Override
public void keyPressed(KeyEvent e) {
System.out.println(e.getKeyChar());
System.out.println(e.getKeyCode());
}
Dont forget to let your class implement ActionListener and KeyListener.
Related
I have added an action listener to the text field. When the btnReadString (Button Read String) is pressed the program should read what is on the text field and show on the JPanel. but nothing shows on the panel.
stringTextField.addActionListener(new ActionListener() {
public void stringTextField (java.awt.event.ActionEvent e) {
if(e.getSource()==btnReadString) //when the button is pressed
{
String stringParameter = stringTextField.getText(); //gets the text and puts it on this string called "stringParameter"
textPane.setText(stringParameter);//the JPanel is set to what is on the string.
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
});
The functionality for the ActionListener should go in the actionPerformed method, as nothings calling the stringTextField method...
stringTextField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==btnReadString) //when the button is pressed
{
String stringParameter = stringTextField.getText(); //gets the text and puts it on this string called "stringParameter"
textPane.setText(stringParameter);//the JPanel is set to what is on the string.
}
}
});
But, based on the code, the ActionListener should be attached to the btnReadString and not the field, as the above logic will never result in anything been executed (as the source of the event will never be btnReadString)
btnReadString.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String stringParameter = stringTextField.getText(); //gets the text and puts it on this string called "stringParameter"
textPane.setText(stringParameter);//the JPanel is set to what is on the string.
}
});
I would suggest having a closer look at How to Write an Action Listener and How to Use Buttons, Check Boxes, and Radio Buttons for more details
You have added the ActionListener to the text field. So the event source is never going to be the button and hence, the code is never going to execute. What you want is to add the ActionListener to the JButton.
Also, the actionPerformed() is there for a reason. All your 'action' code goes inside this method.
So your code should look like this:
btnReadString.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String stringParameter = stringTextField.getText();
textPane.setText(stringParameter);
}
});
Ok, so I'm doing a Java window (a JFrame, doesn't really matter what it is for) and I have a button on it. What I want to approach is when the button is clicked, it changes its text, then the app does something, and when it's finished the button gets its initial text back.
Something like this...
JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
((JButton) e.getSource()).setText("New");
//Do other things
//Do more other things
((JButton) e.getSource()).setText("Initial");
}
});
That's what I've tried so far, but I know it doesn't work as expected (all the code executes. I'm not really an expert and I'm doing this things to learn, so I have no clue if there's a way to do it or not.
I've already looked for a solution to this in the web but I've not found anything (maybe I didn't search properly), so I hope there's someone who can help me with this!
PS: Sorry if my English is not perfect, I know about it. Ask me if something isn't clear about the question. Thanks to all!
Kevin.
EDIT: The app is a sudoku solver, so it takes a while //doing other things. Thats why I'm trying to change the solve button text (so it sais it is solving and when it finished it says solved).
Your logic is not wrong! Take a look at my example below:
public class MainFrame extends JFrame {
public MainFrame() {
setMinimumSize(new Dimension(200, 100));
JButton myButton = new JButton("Initial");
add(myButton);
myButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final JButton triggerBtn = (JButton) e.getSource();
final String originalValue = triggerBtn.getText();
triggerBtn.setText("New");
JOptionPane.showMessageDialog(null, "Speak softly and carry a big stick and you will go far.");
triggerBtn.setText(originalValue);
}
});
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
});
}
}
If you run this you will see that the button is changed. If you were to change the showMessageDialog line to Thread.sleep(10*1000), you would not see a change! This is because you're running the event on the dispatcher thread and the text, even though it is changed, will not allow the change event to be triggered until your method finishes.
Consider the following alternative if the work you're doing is on the same thread:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final JButton triggerBtn = (JButton) e.getSource();
final String originalValue = triggerBtn.getText();
triggerBtn.setText("New");
SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
Thread.sleep(10*1000);
return null;
}
#Override
protected void done() {
triggerBtn.setText(originalValue);
}
};
sw.execute();
}
});
This sets the text, and launches a SwingWorker to run the job asynchronously. Once finished, the dispatcher thread will update the text without requiring the dispatcher thread to be tied up waiting for it to finish (and so events are therefore handled properly).
Let me know if that works for you!
Have you tried with:
JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myButton.setText("New");
//Do other things
//Do more other things
myButton.setText("Initial");
}
});
In your example you're missing actionPerformed and you're not accessing button directly (I can't say what's e in your example)
Just save your current text in a local variable and set it back after you've performed your other actions.
You should also make sure it's really the button that you clicked or at least check instanceof JButton before casting.
final JButton myButton = new JButton("Initial");
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == myButton) {
String initialText = myButton.getText();
myButton.setText("New");
// Do other things
// Do more other things
myButton.setText(initialText);
}
}
});
You were also missing out on your actionPerformed method, the code in the question won't compile - I guess you just wrote it in the editor.
I had 9 hunks of form-identical code such as this:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...with 9 corresponding linked hunks of code like this:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
... and a large number of similar repeated hunks of code
for FocusListener and MouseListener.
I tried to cut down the number of lines of code by assigning
the button's text to its action command and using this:
public void actionPerformed(ActionEvent e)
{
String c = e.getActionCommand();
switch (c) {
case "Clear output": btnClearOutputActionPerformed(e); break;
case "Search": btnSearchActionPerformed(e); break;
case "Exit": btnExitActionPerformed(e); break;
...
}
}
It works, but that's not a lot better. Still repetitive. Looking for elegant.
I can't believe the following method even compiles, but it doesn't work because doClick() calls the method recursively. I was naively hoping doClick() would execute the method btnPatternMouseClickedActionPerformed().
public void actionPerformed(ActionEvent e){
Component[] c ;
c = theFrame.getComponents();
JButton b;
for(Component x: c)
{
if(x instanceof JButton)
{
b = (JButton) x;
if(b.getText().equals(e.getActionCommand()))
{
b.doClick(); // want it to execute code elsewhere
return;
}
}
}
}
At first I thought the above method was close. Now I'm about to give up.
I have three questions:
(1) Is there a way to cut down on such repeated hunks of code as shown in the first two paragraphs?
(1a) Is the last method above close? Can it be easily fixed?
(2) Would a technique similar to the actionPerformed method above (the one that uses switch) to replace hunks of code for FocusListener and MouseListener be a waste of time to implement?
You could change this:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
...with 9 corresponding linked hunks of code like this:
private void btnExitActionPerformed(ActionEvent evt) {
// some code *********************
}
to this:
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// same code that was in the btnExitActionPerformed method.
}
});
But perhaps even better still would be to separate your "control" code, the code in the listeners, from your "view" code, your GUI, but how to do this will depend on your problem and current code base.
Edit
You ask:
I will blame Swing GUI builder for that (bad?) habit.
It's not so bad, and is certainly a lot better than having your GUI classes implement listener interfaces.
Why does Swing do that?? Why does Swing do a LOT of what it does!!
I'm not sure what specifically you meant here.
So about "even better": are you saying to separate the listeners into another class file? And are you suggesting that coconuts migr~~...
Yes, and yes. In fact the control -- the listener part could be composed of several classes, but they all might be used in a single master control class.
I mean, that I should abandon the last method in my question?
Yes.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class Example implements ActionListener{
JButton buttons[] = new JButton[12];
public Example(){
for(int c=0; c<buttons.length; c++){
buttons[c]=new JButton("I am button"+c);
buttons[c].addActionListener(this);
}
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == buttons[0]){}
if(e.getSource() == buttons[1]){}
if(e.getSource() == buttons[2]){}
if(e.getSource() == buttons[3]){}
if(e.getSource() == buttons[4]){}
if(e.getSource() == buttons[5]){}
if(e.getSource() == buttons[6]){}
if(e.getSource() == buttons[7]){}
//....
}
}
This is not enough elegant for you code?
Something other:
If for example you have buttons that are in the same Team, for example:
It's a good idea to have one class(java Object) and then take objects and make buttons.
public class TVButton implements ActionListener{
public TVButton(String name,String whatever){
}
#Override
public void actionPerformed(ActionEvent e){
//actionFor this button
}
}
Here is my ButtonListener class in my GUI. I have several buttons within it, that when clicked, I want to call a certain method for each one, for instance:
public class ButtonListener implements ActionListener{
public void actionPerformed( ActionEvent event ){
if (event.getSource( ) == buttonA)
If button A is selected, I want to call a method and have its return statement displayed.
(If I understand you correctly)
You could have
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonA)
{
ButtonAImpl x = new ButtonAImpl();
x.myMethod();
}
if (e.getSource() == buttonB)
{
ButtonBImpl y = new ButtonBImpl();
y.myMethod();
}
}
You may want to look at some design patterns to help in this scenaro...
MVC - http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
MVP - http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter
I think it's good practise to use a switch in this case because you've said you have several buttons.
public void actionPerformed(ActionEvent e) {
switch (e.getSource())
case buttonA:
buttonACode();
break;
case buttonB:
buttonBCode();
break;
default:
someDefaultAction();
break;
}
If you would like to display the returned result you can replace buttonACode(); with System.out.println(buttonACode());
If I understand it, you should do the following (just an example):
class X{
JButton firstButton;
JButton secondButton;
public X(){
firstButton=new JButton("first");firstButton.setActionCommand("FB");
secondButton=new JButton("second");secondButton.setActionCommand("SB");
}//constructor closing
public void method1(){}
public void method2(){}
class EventHandler extends ActionListener{
public void ActionPerformed(ActionEvent e){
String action=e.getActionCommand();
if(action.equals("FB"))method1();
else if(action.equals("SB"))method2();
}//
}//inner-class closing
}//calss closing
How do I stop the action event of Button2 and more runs after Button1.
Button1 need to do only Button1 Action Event and stop then.
Please Help me, thank you
public void actionPerformed(ActionEvent ae) {
if (ae.getSource().equals(button1)){
System.out.println("Button 1");
}
if (ae.getSource() == button2){
System.out.println("Button 2!");
}
edit:
sorry, wrong code
in main:
Button1.addActionListener(this);
jPanel1.add(Button1);
Button2.addActionListener(this);
jPanel1.add(Button2);
not in main:
public void actionPerformed(ActionEvent ae) {
Object Button1 = null;
if (!ae.getSource().equals(Button1)){
System.out.println("Oben");
}
Object Button2 = null;
if (ae.getSource() == (Button2)){
System.out.println("Links");
}
}
if i press my Button1, i get "Oben"
if i press my Button2 i get "Oben", too
why i dont get "Links"
There are two problems in your code:
You are setting Button1 and Button2 to null
Your if-statements are layed out in such a way that more than one of them can run in a single invocation of actionPerformed
Try this:
public void actionPerformed(ActionEvent ae) {
if(ae.getSource().equals(this.Button1)) {
System.out.println("Button 1");
} else if (ae.getSource().equals(this.Button2)) {
System.out.println("Button 2");
}
}
This code assumes that Button1 and Button2 are members of the class that the actionPerformed method belongs to.
Take another look at your (edited) code.
Object Button1 = null;
if (!ae.getSource().equals(Button1)){
System.out.println("Oben");
}
So what you're saying here is the following, which is going to evaluate true in both cases.
if (ae.getSource() != null)
This is why the result is always Oben.
If you are intending to compare against a different Button1, make sure to reference the correct the object. Without seeing the rest of the code it's hard to say, but you may mean to use (this.Button1);
public void actionPerformed(ActionEvent ae) {
Object Button1 = null;
if (!ae.getSource().equals(Button1)){
System.out.println("Oben");
}
Object Button2 = null;
if (ae.getSource() == (Button2)){
System.out.println("Links");
}
}
I'm afraid the above code make's little sense, and doesn't conform to usual practice. Firstly, buttons that perform different actions should have different listeners, except in special cases. This is not one of those special cases. Split up your code into:
public void actionPerformed(ActionEvent e)
{
System.out.println("Oben");
// This is the actionPerformed method for button 1.
}
public void actionPerformed(ActionEvent e)
{
System.out.println("Links");
// This is for button 2.
}
Then simply bind to the relevant buttons.