I wanted to move my image using keyboard arrow keys. when I pressed the arrow keys it moves accordingly to the direction. However, I need to click on the image before able to move it. May I know how to edit the code such that I do not need to click on the image before able to move it? I would also like to know how to make the image appear from the left once it reaches right and vice versa.
My codes are :
Collect.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent ke)
{
if(ke.getKeyCode() == KeyEvent.VK_LEFT)
{
Collect.setLocation(Collect.getX()-8,Collect.getY());
repaint();
}
if(ke.getKeyCode() == KeyEvent.VK_RIGHT)
{
Collect.setLocation(Collect.getX()+8,Collect.getY());
repaint();
}
}
});
Collect.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent me)
{
if(me.getClickCount() == 1)
{
boolean dd = Collect.isOptimizedDrawingEnabled();
boolean ff = Collect.requestFocusInWindow();
repaint();
}
}
});
You have look at KeyBindings, otherwise you have to JComponent#setFocusable() that nest the Image, example for Moving Image
Collect.requestFocusInWindow();
requestFocusInWindow()..
Requests that this Component get the input focus, if this Component's top-level ancestor is already the focused Window.
Make sure to call that only after the main window is visible and has the focus.
KeyListeners only work when the component which has the listener has focus. You are giving focus to what appears to be Collect by clicking on it. Then the listener works. You can add the listener to other things or force focus to remain on something like the outer frame by using a focus listener to regain focus whenever it is lost.
Related
I'm making something like an auto clicker.
I would like to make it so that when the left mouse button is pressed, the auto clicker should turn on. When the button is released, the auto clicker should turn off.
Is there a way to check if the left mouse click (in real life) is pressed after calling the robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK) method?
You should implement MouseListener interface in your class then override these two methods : mousePressed and mouseReleased .
public void mousePressed(MouseEvent e) {
//do the auto click code here
}
public void mouseReleased(MouseEvent e) {
//turn off the auto click here
}
read this article
I'm trying to write a program that allows a user to move a shape with arrow keys and change its color with the enter key. I wasn't taught anything about GUIs or event-based programming, so this is my first experience with any of that. I think I understand the basics of it, but I'm having trouble just finishing the syntax to make everything run. The tutorials I find online use timers, which I'm not using. Here's my current code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Lab15Panel extends JPanel
{
Color[] colors = new Color[]{Color.blue, Color.green, Color.red, Color.orange, Color.yellow};
int initialX = 90;
int initialY = 80;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(colors[0]);
g.fillRect(initialX, initialY, 100, 100);
Lab15Key listen = new Lab15Key();
}
private class Lab15Key implements KeyListener
{
#Override
public void keyTyped(KeyEvent event)
{
if (event.getKeyChar() == KeyEvent.VK_LEFT)
{
initialX++;
}
}
#Override
public void keyReleased(KeyEvent event)
{}
#Override
public void keyPressed(KeyEvent event)
{}
}
}
I make my frame in a different class. Right now I'm unsure of two things:
1. How do I use addKeyListener with the filled shape? Is there a way to refer to the filled shape?
2. Is my idea of "moving" the shape correct? That is, creating variables outside of the methods for the position of the shape and then using my KeyEvents to change those numbers? Or will the shape not be moved in this case? (Note I've only written the code for the up key event.)
Any help you can give me would be appreciated. I'm definitely a Java novice, and I'm just trying to understand these basic concepts but the resources I have aren't helping.
You need to add your KeyListener to your panel to actually make it listen for key presses. This is known as registering the listener. I would put it in the constructor:
public Lab15Panel()
{
Lab15Key listen = new Lab15Key();
this.addKeyListener(listen);
}
Without this step, you are creating the listener, but it has nobody to tell when it hears something.
If you just want your panel to get repainted each time the key gets pressed, then you could do something like this in your KeyListener:
#Override
public void keyTyped(KeyEvent event)
{
if (event.getKeyChar() == KeyEvent.VK_LEFT)
{
initialX++;
}
Lab15Panel.this.repaint(); // Calls repaint on the instance of the enclosing class
}
There are a number of issues working against you...
You've not registered the KeyListener with the component, so it will never receive key events
You don't repaint the panel when you change the state of the rectangle, remember, Swing uses a passive painting algorithm, so it only paints the UI when it thinks it needs to. You need to give Swing a nudge by calling repaint
Your component isn't focusable, meaning that even if you did the other two things, you'd probably still not get it it work.
KeyListener is a pain, it will only be triggered of the component it is attached to IS focusable AND HAS focus, generally, you are better off use Key Bindings
See How to use key bindings for more details
I have to draw a Line in Java. I click one point, then release the mouse key, move the mouse (the end of the line should be where the mouse cursor is (a dynamic preview)) then click the mouse key again to make the line.
I see various questions on here, but most deal with holding a mouse button and dragging the mouse.
My question is, how can I draw a line dynamically using the method above. I am concerned about repainting. I had code earlier and it drew all the lines as I moved the mouse. Is there a way to just have a preview.
You need need to create a application implementing both a MouseEventListener and a MouseMotionListener. Use the MouseEventListener method mouseClicked to check whether the mouse has been clicked and subsequently the MouseMotionListener method MouseMoved to update the other end of the line to your mouse's position. Finally you use the MouseEventListener again to pinpoint the end location of the line.
I hope this helps.
Take a look at:
http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html and http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html.
There's a lot of information missing in your post, so it will be difficult to offer an exact solution, but here is the general idea. Assuming that you need a transparent JComponent that receive mouse events and paint your line preview, the code would look something like this.
public class MyLinePreviewComponent extends JComponent {
Point sourcePoint;
Point destinationPoint;
pubic MyLinePreviewComponent() {
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (sourcePoint == null)
sourcePoint = e.getPoint();
else
sourcePoint = null;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (sourcePoint != null)
targetPoint = e.getPoint();
repaint();
}
});
}
public void paintComponent(Graphics g) {
if (sourcePoint != null && destinationPoint != null) {
g.setColor(Color.red);
g.drawLine(sourcePoint.x, sourcePoint.y, destinationPoint.x, destinationPoint.y);
}
}
}
Note that I did not run this code.
If the line preview feature has to be added to an existing component, then you will have to repaint the regular content in paintComponent() before paiting the line.
Is there a way to distinguish between a JComboBox's index being changed programatically using setSelectedBoundValue and by clicking on the JComboBox?
This is ugly and truly a hack, but works!
The ActionEvent contains a field modifiers which in this case is the mouse button id. So using that may help you distinguish between setSelectedIndex or setSelectedValue and mouse clicks (by the way setSelectedBoundValue is not a method on JComboBox):
box.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getModifiers() != 0) {
// ~ mouse button pressed ;)
}
}
});
setSelectedBoundValue
Never heard of that method?
Is there a way to distinguish between a JComboBox's index being changed programatically
Not really. You can remove the listener:
comboBox.removeActionListener(...);
comboBox.setSelectedItem(...);
comboBox.addActionListener(...);
You can set your own class variable.
manualSelection = true;
comboBox.setSelectedIndex(...);
manualSelection = false;
i have a Jframe application with the defaultbutton set to btnClose_ (Close Button: this button closes the window).
I have 2 textfields that must also fire an event when user clicks the Enter key on the textfields. What happens is that when I press the Enter key while the cursor is on the textfield, the event on the Close button is fired causing the window to close.
Is it possible to remove the listener of the default button if the Enter key is pressed on the textfield? Here's my code for the textfield listener
/**
* Receives the two textfield instance
*/
private void addFilterListener(JTextField txf) {
txf.addKeyListener(new KeyAdapter() {
/**
* Invoked when a key has been pressed.
*/
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
ActionListener al = btnClose_.getActionListeners()[0];
btnClose_.removeActionListener(al);
btnFilter_.doClick();
e.consume();
btnClose_.addActionListener(al);
}
}
});
}
private JButton getBtnClose(){
if(btnClose == null){
btnClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getWindow().dispose();
}
});
}
return btnClose;
}
}
Where to start?
The first thing that springs out at me is the bad variable names. txf? What's wrong with proper words? textField or field, say. Or much better, a name descriptive of its purpose, not what it is.
Secondly, the first comment is wrong (not uncommon) and the second comment is redundant (already specified in the KeyListener interface, you don't need to try and half-heartedly specify it again).
Next up, low level key listeners tend not to work so well on Swing components (JComboBox being the most notorious example - it typically is implemented with child components). In general you can use JComponent.registerKeyboardAction (the API docs says this is obsolete but not deprecated, and to use more verbose code). For text components, you often want to play with the document (typically through DocumentFilter). In this particular case, looks like you just want to add an ActionListener.
Now doClick. It's a bit of an evil method. For one thing it blocks the EDT. It is probably the easiest way to make it look as if a button is pressed. From a programming logic point of view, it's best to keep away from modifying Swing components, when you can keep everything in your abstracted code.
Removing and adding listeners from components is generally a bad idea. Your code should determine what to do with an event including whether to ignore it. Do that at an appropriate point when handling the event. Don't duplicate state unnecessarily.
A potential issue is that the code seems to assume that there is precisely one action listener. There could be others. The code is not robust under unexpected behaviour. Set your components up at initialisation time, and you shouldn't need to refer to them again.
As far as I understood your question, you want that buttonClick should not get fired if Enter is pressed .
This won't fire doClick() if enter is pressed
if (e.getKeyCode() != KeyEvent.VK_ENTER) {
btnFilter_.doClick();
}
In the ActionListener of the close button, assuming you can change its code, don't close if one of the text fields have the focus.
public void actionPerformed(ActionEvent e) {
if (field1.hasFocus() || field2.hasFocus())
return; // don't close if text field has focus
frame.dispose();
}
If you can not change the ActionListener of the close button, add a FocusListener to the text fields. If one of them gets the focus, remove the default button. If the text field lost the focus, reset the default button.
FocusAdapter listener = new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
frame.getRootPane().setDefaultButton(null);
}
#Override
public void focusLost(FocusEvent e) {
frame.getRootPane().setDefaultButton(close);
}
};
field1.addFocusListener(listener);
field2.addFocusListener(listener);
This should be better than depending on the listeners being called in the correct sequence - it is of no avail to remove the listener if it was already called...