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.
Related
I have a JPanel with many JButton components inside. Is there a way to get the panel mouse event when a button is pressed? Another point of view: How to make button transparent to panel mouse event? I specifically need to capture mousePressed() event of panel.
EDIT
Context:
I'm dragging the panel content through a JScrollPane (actually working), to accomplish that I needed to capture the point where mouse is pressed, so both panel and buttons have MouseListener and MouseMotionListener to capture the point and do other stuff.
Issue:
When I press -> drag -> release the mouse button, if the mouse is still over the button it executes whatever the button does. So I want the mouse listener of the panel to be 'independent' of the button, to remove the mouse listener from the buttons.
EDIT 2
I just realize reading my own issue... that it will make no difference removing MouseListener to the JButton. When pressing the button if the mouse it stil over it, the actionPerformed will be executed anyway...What can I do?
EDIT 3
Edited question title, according to the solution.
Kipping in mind that the event execution order in this case is: mousePressed->mouseDragged->actionPerformed->mouseReleased , I get it working at the moment, adding a boolean:
#Override
public void mousePressed(MouseEvent e) {
origin = new Point(e.getPoint());
}
//each time the user stops dragging set dragged to false
#Override
public void mouseReleased(MouseEvent arg0) {
dragged = false;
}
#Override
public void mouseDragged(MouseEvent e) {
dragged=true;
if(((Component) e.getSource()).getParent().equals(myPanel)
|| e.getSource().equals(myPanel)){
if (origin != null) {
JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, myPanel);
if (viewPort != null) {
int deltaX = origin.x - e.getX();
int deltaY = origin.y - e.getY();
Rectangle view = viewPort.getViewRect();
view.x += deltaX;
view.y += deltaY;
myPanel.scrollRectToVisible(view);
}
}
}
#Override
public void actionPerformed(ActionEvent e){
//stuff do detect the button...
//..in case there is more than one panel, if the component belong to myPanel and dragg is false
if(((Component) e.getSource()).getParent().equals(myPanel)&& dragged==false ){
//do stuff
}
}
I have a code for dragging a label width mouse.
lbl_banner.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e) {
//catching the current values for x,y coordinates on screen
x_pressed = e.getX();
y_pressed = e.getY();
}
});
lbl_banner.addMouseMotionListener(new MouseMotionAdapter(){
#Override
public void mouseDragged(MouseEvent e){
//and when the Jlabel is dragged
setLocation(e.getXOnScreen() - x_pressed, e.getYOnScreen() - y_pressed);
}
});
Now, how do I make a function: While I'm dragging this label around the Screen, If the Label by dragging touches other object (label, button,...) to do something.
if(//labelTouchesSomething){//do something}
While this is not technically a dragging but the dynamic move of a component (dragging is the transfer of contents in between components), you can compute the intersection of the current moving component against other components (this may need some navigation inside your hierarchy). May be this can help you: How do I detect the collison of components?. You can also use the methods contains of Component to determine if some coordinates are inside a component or not.
In my animation one of elements is moving oval. There are two ways to control it. The first is setting x,y position by mouse listener and the second is Key Listener. During first using animation both methods work. But after using stop (clear) button mouse listener doesn't work, but Key method is still working.
Code stop method:
void clear() {
waves.clear();
xz_list.clear();
yz_list.clear();
time_list.clear();
f_list.clear();
time=0;
timer.stop();
repaint();
}
MouseListener method:
void SourcePosition(double v, String d) {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
{
x_o = e.getX();
y_o = e.getY();
repaint();
}
}
});
}
Generally this is application showing Doppler Effect. Start button make setting data from interface, disable interface and start animation and chart. Stop button uses clear() method and enable interface.
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 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.