Creating a class that extends keyListener - java

In my java project, I want to check the input in each JTextField in a few different classes (with the exact same code)..
Right now I have the same code copied over and over and I was suggested with 2 options:
Create a method and call the method instead.
Create a new class that extends from another class (I don't know which yet) that has the method needed.
The code I'm using now is:
totalAmount.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent arg0) {
//do something
}
});
And the new class is:
public class Listener extends KeyAdapter {
public void keyTyped(KeyEvent arg0){
//do something
}
}
The problem is that I don't know if I'm extending the right class, and how to use the new class I've written...
Thanks in advance!

To do what you are wanting with your key adapter you would use
totalAmount.addKeyListener(new Listener());
and your code of your key adapter is correct.
public class Listener extends KeyAdapter {
public void keyTyped(KeyEvent arg0){
//do something
}
}
To get the text from a JTextField you could either use this code inside your keyAdapter
System.out.println(totalAmount);
or, preferably you could use a document listener. This would be done by
public class documentListener implements DocumentListener //This is a listener
{
public void changedUpdate(DocumentEvent e){
}
public void removeUpdate(DocumentEvent e){
int lengthMe = e.getDocument().getLength();
System.out.println(e.getDocument().getText(0,lengthMe));
}
public void insertUpdate(DocumentEvent e){
int lengthMe = e.getDocument().getLength();
System.out.println(e.getDocument().getText(0,lengthMe));
}
}
and it would be added to the JTextField with
totalAmount.getDocument().addDocumentListener(new documentListener());

Related

Problem with creating a new KeyListener inside a class

I'm having serious issues with adding a keylistener to my Java program.
I would like to avoid the addKeyListener() method, so I tried the following solutions:
public class game implements KeyListener{
#Override
public void keyTyped(KeyEvent e) {
return;
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("test");
return;
}
#Override
public void keyReleased(KeyEvent e) {
return;
}
}
And:
public class game{
KeyListener listener = new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
return;
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("test");
return;
}
#Override
public void keyReleased(KeyEvent e) {
return;
}
}
}
None of them worked for me.
Do I really have to use the addKeyListener() in a graphics class? I'm trying to avoid that.
Thanks in advance.
Is there a particular reason you want to avoid using addKeyListener()?
It's an essential part of KeyListener so you won't be able to avoid using it.
Should be relatively easy to implement though. If you're using JFrame, the following code within your constructor should work:
public class Game implements KeyListener{
public Game(){
JFrame jframe = new JFrame();
jframe.addKeyListener(this);
}
//implement other KeyListener methods
}
This way, the Game class itself acts as the listener and can implement all of the necessary methods.
Hope this helps!

Java - MouseListener in another class?

I realize this is a repeat question, but my circumstances are a little bit different. I need to have a MouseListener in another class that can altar the background color of the object that calls it. Please help me.
public class LeftListPanel extends JPanel {
public LeftListPanel() {
setBackground(Settings.BACKGROUND_COLOR);
setLayout(null);
addPersonalStatsTab();
}
private void addPersonalStatsTab() {
JPanel personalStatsPanel = new JPanel();
personalStatsPanel.addMouseListener(new CustomMouseListener());
JLabel personalStatsText = new JLabel("Text");
personalStatsPanel.add(personalStatsText);
add(personalStatsPanel);
}
Then I have an inner-nested class for the MouseListener because this is the only place this MouseListener will be called.
class CustomMouseListener implements MouseListener {
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
setBackground(Settings.BACKGROUND_COLOR.brighter());
}
#Override
public void mouseExited(MouseEvent e) {
setBackground(Settings.BACKGROUND_COLOR);
}
}
The setBackground(COLOR) lines are those who don't work... this.setBack and super.setBack ARE NOT working in this case.. I'M DESPERATE FOR HELP!
The reason you don't see the background changes is that when you call setBackground, you are de-referring (implicitly) the this object, i.e. the instance of LeftListPanel. So, you are actually changing its background, but you don't see it because inside the LeftListPanel instance there is another JPanel (instantiated at the addPersonalStatsTab method) which occupies the whole visible space (or even it is not visible at all, because of that weird null layout; I don't know exactly).
Fist of all, I recommend to you not to set null as a layout. Chose a proper layout, or let it be defaulted - do not call setLayout(null).
Then, set personalStatsPanel as a private member of LeftListPanel. And when calling to setBackground, use it as the scope reference:
LeftListPanel.this.personalStatsPanel.setBackground(...);
This works, I instead just created a private method where I pass in the panel I want to apply it too.
private void CustomMouseListener(JPanel panel) {
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR.brighter());
}
#Override
public void mouseExited(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR);
}
});
}
Thank you all for your time and suggestions :)
You could...
Pass a reference of the component you want changed to the CustomMouseListener
class CustomMouseListener implements MouseListener {
private JPanel panel;
public CustomMouseListener(JPanel panel) {
this.panel = panel;
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR.brighter());
}
#Override
public void mouseExited(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR);
}
}
This is okay if you want to use the listener on a limited number of components, but if you want to use the same listener on a number of components...
You could...
Use the source property of the MouseEvent to get which component triggered the event
#Override
public void mouseEntered(MouseEvent e) {
if (!(e.getSource() instanceof JPanel)) {
return;
}
JPanel panel = (JPanel)e.getSource();
panel.setBackground(Settings.BACKGROUND_COLOR.brighter());
}
or, a better solution would be to do something more like...
#Override
public void mouseEntered(MouseEvent e) {
e.getComponent().setBackground(Settings.BACKGROUND_COLOR.brighter());
}
since the information is already provided to you (just not, this returns an instance of Component, so if you need to access the Swing specific properties, you'd still need to cast it).
Why is this approach better?
CustomMouseListener listener = new CustomMouseListener();
panel1.addMouseListener(listener);
panel2.addMouseListener(listener);
panel3.addMouseListener(listener);
panel4.addMouseListener(listener);
panel5.addMouseListener(listener);
panel6.addMouseListener(listener);
panel7.addMouseListener(listener);
because it's agnostic, meaning you can create a single instance of the listener and re-use on multiple components

Running a "this" Method inside actionPerformed - JButton?

I have a JButton which I added a actionPerformed, and I tried to write a "this" method and it won't allow it. How can I do this? This is example of what I want to do:
public void methodName(String results) {
this.results = results;
}
Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
this.methodName(asdf);
}
Because it's an anonymous class, using this will refer to the anonymous class instance, not your overall class. To get around this, denote that you want to reference your outer class specifically:
Something some = new Something() {
public void overridden() {
YourClass.this.methodName("test");
}
};
Your class in anonymous, so in anonymous context, this does not make any sense. What do you mean by this? If you mean the button, your answer is event.getSource()
In your code, this refers to your ActionListener when you call the method.
If you want to call methodName() from the enclosing class, you have two choices :
remove this:
Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
methodName(asdf);
}
store a reference to the enclosing class and use it:
final MyClass enclosingClass = this;
Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
enclosingClass.methodName(asdf);
}
You can not use "this" keyword inside inner class to access outer class method. if we use this then it will refer to the inner class.Instead of that just use the method name.see the example.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class TestButton
{
String results = "";
JButton Button = new JButton();
public TestButton(){
Button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
methodName("Test");
this.show();
}
public void show(){
System.out.println("hi");
}
});
}
public void methodName(String results)
{
this.results = results;
}
}

Class of Event handlers

is it possible in java to have a class where it has EventHandlers for with different functions? for example button1 will log you in, while button2 will log you out, is this possible? Here's the code I made it seems to be not working.
package event.handlers;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TheHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent logInEvent) {
System.out.println("Button Login");
}
public void actionPerformed(ActionEvent cancelEvent) {
System.out.println("Cancel Login");
}
}
You either need two implementations of ActionListener, one for each button or the actionPerformed needs to determine the button by the event argument and take the appropriate action. Your code will not compile because the signatures for both methods are the same.
No. You can not have a class implement two methods with the same function signature. How would the compiler know which one to call for different events? The name you give to the arguments has no meaning to the compiler.
As an alternative, you can create multiple anonymous action listeners that simply forward the call to a method that does have a unique name if you want everything to be in the same class.
public class TheHandler {
public TheHandler() {
JButton login, cancel;
//initialize code here
login.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent logInEvent) {
loginPerformed(logInEvent);
}
});
cancel.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent cancelEvent) {
cancelPerformed(cancelEvent);
}
});
}
public void loginPerformed(ActionEvent logInEvent) {
System.out.println("Button Login");
}
public void cancelPerformed(ActionEvent cancelEvent) {
System.out.println("Cancel Login");
}
}
You may use getSource() or getActionCommand() method of ActionEvent.
#Override
public void actionPerformed(ActionEvent logInEvent) {
Object src=logInEvent.getSource();
String cmd=logInEvent.getActionCommand(); //It will return caption of button
if(src==btn1)
{
//
}
//Or
if(cmd.equals("Button1")) { ... }
}
You can not have multiple actionPerformed method in one class. Simple way is to do operation based on source of action like:
(in actionPerformed method)
if(e.getSource() == loginButtton) { // based on button variable if they are in same class and accessible in actionPerformed method
loginMethod()
} else if(e.getSource == logoutButton) {
logoutMethod()
}
or
if(e.getActionCommand().equals("loginButtton")) { // based on caption/text on button
loginMethod()
} else if(e.getActionCommand().equals("logoutButtton")) {
logoutMethod()
}
or you can have different anonymous class for different buttons like
loginButton.addActionListner(new ActionListerner(){
public void actionPerformed(ActionEvent loginEvent) {
loginMethod();
}
});
logoutButton.addActionListner(new ActionListerner(){
public void actionPerformed(ActionEvent cancelEvent) {
logoutMethod();
}
});
The problem there is that your two method signatures are identical. When Java tries to figure out which method to call, it can't tell the difference between the two.
I can think of two ways to do what you want:
Presumably, you are registering the listeners on the buttons like cancelButton.addActionListener(...). So you can either provide each button with its own anonymous inner class:
loginButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent logInEvent) {
System.out.println("Button Login");
}
}
cancelButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent cancelEvent) {
System.out.println("Cancel Login");
}
}
or you can define a single actionPerformed method that checks the source of the call:
public class TheHandler implements ActionListener {
JButton loginButton;
JButton cancelButton;
public TheHandler()
{
...
// Now, technically, this is bad form because you're leaking 'this'.
// But as long as this will only be called after this constructor finishes
// initializing, it's safe.
loginButton.addActionListener(this);
cancelButton.addActionListener(this);
...
}
...
#Override
public void actionPerformed(ActionEvent evt) {
if(evt.getSource() == loginButton)
System.out.println("Button Login");
else if(evt.getSource() == cancelButton)
System.out.println("Cancel Login");
}
}
Using anonymous inner classes can sometimes be clearer, because you see the code right next to the addListener call, but it also adds a lot of boilerplate, and if you're working on a very large progect that can take a while to load, reducing the number of classes can sometimes make it load a little faster (each anonymous inner class is another thing for the JVM to load).

Java applet - mouse and key listener

Is there a way to implement a KeyListener and MouseListener in the same applet? I already tried any ways I thought that would work and I tried Google. :\
my try:
C:\Users\Dan\Documents\DanJavaGen\tileGen.java:23: tileGen is not abstract and does not override abstract method mouseExited(java.awt.event.MouseEvent) in java.awt.event.MouseListener
public class tileGen extends JApplet implements KeyListener, MouseListener {
^
1 error
You can certainly implement both KeyListener and MouseListener in the same applet :)
You must have the following methods in the tileGen class:
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e)b{
}
public void mouseExited(MouseEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
If you already have some of these methods implemented you can leave them out.
Gentle hint: Capitalize your class name as TileGen :) Lower-case class names are — by convention — used only for generated or internal code.

Categories