Java calculator how to make backspace - java

I started learning programming a few days ago. I tried to make a calculator but i have one problem:
i don't know how to make backspace JButton.
buusun.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
tf.setText(text.getText().length()-1);
}
});
Any ideas?

Try this:
buusun.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
tf.setText(text.getText().substring(0, text.getText().length() - 1));
}
});
It uses the string.substring(start, end) method.
Note that you might need to adjust the exact variables you are using, as I'm not sure whether you need to get the value from tf or text, but this should provide the gist of what you want.

Related

How to find the JComponent which has focus within a Swing application?

I am having problems to identify where the focus within my application goes to after activating/deactivating or opening/closing some dialogs.
Is there a way to safely get an event down handed down the component hierarchy to be informed when the focus changes and where to?
In a Smalltalk environment for instance, you could for testing reasons just re-implement #requestFocus on Window/SubPane (i.e. JComponent) level and have a debug statement where the focus went.
Can you do something like that in Java or is there a mechanism I am missing?
I'm not entirely sure what you're trying to do with this, but to answer your question you could add a FocusListener to each element. An avriable is then written using the FocusGained function.
int focus = 0;
textField1.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
focus = 1;
}
#Override
public void focusLost(FocusEvent e) {
}
});
textField2.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
focus = 2;
}
#Override
public void focusLost(FocusEvent e) {
}
});
So the appearant culprit was a debug tooltip. Removing these completely and adding Steffi's code for logging have made me sure enough that this is now solved. Thanks to all, I have learned again something new.

How to substitute a pressed char in Java

When a user presses the "dot" key on the keypad in a in a JTextField I'd like to transparently substitute it with a comma. I tried something like this:
jTextField.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.VK_DECIMAL) {
event.setKeyChar(',');
}
}
});
but it doesn't work.
Instead of trying to associate a new key with an already happened key event (this is impossible I think), you should try directly manipulating the text of the related JTextField instance via a call like yourTextField.setText(","); in the if statement of your code snippet above.
The sane way of replacing input in a TextField is to use a DocumentFilder on the TextField's Document (http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html#filter).
Thank you all for your answers.
It's true that the better choice would be to write a document filter, but I need to substitute the dot character only if is pressed on the numpad, not when it comes from the regular keyboard.
I know I could set a flag in the keylistener and than read it in the documentfilter, but it sounds a bit too convoluted.
Thank you very much.
Franco
Here is my solution:
public class MyTextField extends JTextField {
private boolean substituteDot;
public MyTextField() {
super();
addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent event) {
substituteDot = (event.getKeyCode() == KeyEvent.VK_DECIMAL);
}
#Override
public void keyTyped(KeyEvent event) {
if (substituteDot) {
event.setKeyChar(',');
}
}
});
}
}
Thank you all!
Bye
Franco

Adding ActionListeners and calling methods in other classes

I need some help, as I am quite the noob.
The program im trying to make here, used to work for my intentions, but as I tried to make my code more readable, I ran into a problem regarding ActionListener.
Before I made a new class to have all the methods in, I used button.addActionListener(this); and it worked just fine. Now that I wanted to put things in a separate class, I have absolutely no idea what to do.
So I guess my question is, how can I make ActionListener work in a situation like this, or am I just doing everything wrong here?
Here's the part of my code that I think is relevant(edited out most of it):
//Class with frame, panels, labels, buttons, etc.
class FemTreEnPlus {
FemTreEnPlus() {
//Components here!
//Then to the part where I try to add these listeners
cfg.addActionListener();
Exit.addActionListener();
New.addActionListener();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run(){
//Start the Program in the FemTreEnPlus Class
new FemTreEnPlus();
}
});
}
That was the class with the frame, here's the other class, with the methods
public class FemTreEnMethods extends FemTreEnPlus implements ActionListener {
//Perform Actions!
public void actionPerformed(ActionEvent ae){
if(ae.getSource() == cfgButton){
configureSettings();
}
if(ae.getSource() == newButton){
newProject();
}
if(ae.getSource() == exitButton){
exitProgram();
}
}
//All methods are down here
Thanks in advance for any help.
Despite the tutorials' examples show the use of listeners implemented in the way you do, IMHO is more useful use anonymous inner classes to implement listeners. For instance:
cfgButton.addActionListener(new ActionListener() {
#Override
public void actionPerfomed(ActionEvent e) {
// do the stuff related to cfgButton here
}
};
newButton.addActionListener(new ActionListener() {
#Override
public void actionPerfomed(ActionEvent e) {
// do the stuff related to newButton here
}
};
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerfomed(ActionEvent e) {
// do the stuff related to exitButton here
}
};
This approach has these advantages:
Listeners logic is well separated.
You don't need those nested if blocks asking who is the source of the event.
If you add a new button you don't have to modify your listener. Just add a new one.
Of course it depends on the case. If the behaviour will be the same for a set of components (for instance radio buttons or check boxes) then it makes sense have only one listener and use EventObject.getSource() to work with the event's source. This approach is suggested here and exemplified here. Note the examples also make use of anonymous inner classes in this way:
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// do something here
}
};

I cannot seem to .setText more than twice

I am currently making a quiz game. I have managed to set the game up as follows -
The user clicks the start button.
From here this opens a text file and retrieves each question and saves them to a string.
It then adds these strings to an Arraylist.
I then have display the first element of the array to a Label (this is the first question).
From here I have managed to make a method that checks the label text and set the text of 4 buttons to 4 different buttons.
If the user selects the correct answer it adds +1 to a score integer and then moves onto the next question(askQues2();). If the user selects the wrong answer it just moves on to the next question(askQues2();).
Once it starts the next question(askQues2();) it changes all of the values that I have told it to. i.e LabelQuestion and the 4 different answer buttons.
If the user selects the correct answer it adds +1 to a score integer and then moves onto the next question(askQues3();).
THIS IS WHERE THE PROBLEM IS
When I chose an answer during the second question, it does not run the 3rd question method.
CODE
public void askQues1 (){
String askQues1 = questions.get(0);
LabelQuestion.setText(askQues1);
ButAnsA.setText("Gillard");
ButAnsB.setText("Howard");
ButAnsC.setText("Rudd");
ButAnsD.setText("Abbott");
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
Score += 1;
askQues2();
}
});
ButAnsB.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues2();
}
});
ButAnsC.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues2();
}
});
ButAnsD.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues2();
}
});
}
public void askQues2(){
String askQues2 = questions.get(1);
LabelQuestion.setText(askQues2);
ButAnsA.setText("1999");
ButAnsB.setText("2004");
ButAnsC.setText("2007");
ButAnsD.setText("2010");
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues3();
}
});
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues3();
}
});
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues3();
}
});
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
Score += 1;
askQues3();
}
});
}
public void askQues3(){
String askQues3 = questions.get(2);
LabelQuestion.setText(askQues3);
ButAnsA.setText("Broncos");
ButAnsB.setText("Knights");
ButAnsC.setText("Storm");
ButAnsD.setText("Dragons");
}
I can tell that it does not load the 3rd method because the question label or answer buttons change.
I have tried multiple options that I have found on the internet. None of them have fixed this problem.
If you require more information. Please let me know. Like I said it is my first time posting a question so I 'm not familiar with standards.
Thanks.
You're adding actionListener to the buttons. I don't think a button can detect more than 2 actions judging by your problem.
Try setting an onClickListener() to the buttons instead.
Code:
ButAnsA.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
askQues3();
}
});
NOTE: There's a difference between adding and setting listeners. By setting a listener every time, you're only replacing the previous one. But by adding a listener you're increasing the number of listeners on the particular widget.
Your askQues2() method is adding action listeners to ButAnsA 4 times, and no new listeners to the other buttons.
You appear to be adding new listeners to the same buttons with every call, which is generally suboptimal. Since you said you are reading the questions and possible answers from a file, you'd be better off including which is the right answer in the file and having a single listener for all buttons.
pseudocode:
doAction(ActionEvent e)
int buttoncode=0
switch (e.getSource())
case ButAnsA:buttoncode=1;
case ButAnsB:buttoncode=2;
case ButAnsC:buttoncode=3;
case ButAnsD:buttoncode=4;
if (questions.get(questnum).rightAnswer == buttoncode)
score++;
questnum++
updateQuestionText()
updateButtonText()

Java Individual ActionListeners and an Overarching ActionListener

Perhaps I am going about this the wrong way. Let me know
Using Swing and AWT, I have several buttons set up on a frame and they each have an ActionListener corresponding to their specific function I.E.
JButton foo_button = new JButton("Foo-Me");
foo_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
}
})
JButton bar_button = new JButton("Bar None");
bar_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
}
})
So each of these buttons do their own thing. However, what if I want all the buttons to do a certain thing (the same exact method for each), in my case, clear a label, before they do their own thing.
Obviously I could add whatever_label.setText("") to each actionPerformed() but that entails a lot of duplication, something I'm not so much a fan of.
Oh Java and Swing gurus come to my aid.
You can subclass your own implementation of ActionListener:
private static abstract class MyListener implements ActionListener {
#Override
final public void actionPerformed(ActionEvent evt) {
theSameTask();
uniqueTask(evt);
}
private void theSameTask() {
// the identical task
}
public abstract void uniqueTask(ActionEvent evt);
}
And then, the new listeners will look like this:
JButton bar_button = new JButton("Bar None");
bar_button.addActionListener(new MyListener() {
#Override public void uniqueTask(ActionEvent evt) {
//Fancy schmancy code work
}
});
Another possibility is to use the 'Decorater' pattern, and write an ActionListener decorator for the common behavior. Your code would then be of the form
bar_button.addActionListener(new MyActionListenerDecorator( new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Fancy schmancy code work
} }) );
I think the best way to do this is to use Action. That way all the listeners always do the same thing.

Categories

Resources