Drawing lines on canvas using Mouse without Swing in java - java

My Quesition is similar to this question
Drawing lines with mouse on canvas : Java awt
My problem is that When the windows is minimized and maximized , the drawn lines are gone everytime
But my working is quite different because i used only awt components and without swing.
import java.awt.*;
import java.awt.event.*;
class Drawing extends WindowAdapter implements MouseMotionListener, MouseListener, ComponentListener {
Frame f;
Canvas c;
int X=400,Y=400;
int px=-1,py=-1;
int x,y;
public Drawing() {
f=new Frame("Drawing - Canvas");
f.addWindowListener(this);
f.addComponentListener(this);
f.setSize(X,Y);
c=new Canvas();
f.add(c);
c.addMouseMotionListener(this);
c.addMouseListener(this);
f.setVisible(true);
}
public void componentResized(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {
int x,y;
x=e.getX();
y=e.getY();
Graphics g=c.getGraphics();
if(px!=-1) {
g.drawLine(px,py,x,y);
}
else {
g.drawLine(x,y,x,y);
}
px=x;
py=y;
}
public void mouseReleased(MouseEvent e) {
this.X=400; this.Y=400;
this.px=-1; this.py=-1;
}
public void windowClosing(WindowEvent e) {
f.dispose();
}
public static void main(String[] args) {
Drawing c=new Drawing();
}
}
Can someone help me out on these problems ?

getGraphics is NEVER the write way to perform custom paint.
Start by having a read through Painting in AWT and Swing and Performing Custom Painting for a better understanding how painting works and how you should work with it.
The simple answer is, you need to maintain a model of what has been painted, so that on each paint pass you can re-draw it.
For example Resize the panel without revalidation, Draw trail of circles with mouseDragged, Why is my line not drawing?

Related

JPanel key listener not working [duplicate]

This question already has answers here:
How to use Key Bindings instead of Key Listeners
(4 answers)
KeyListener not working (requestFocus not fixing it)
(3 answers)
Closed 5 years ago.
I am making a large program with multiple classes and am having issues with some code that I wrote. My Mouse listener works just fine and using the same steps, my key listener does not. My code is as follows;
main method
public static void main(String[] args) {
window._init_(panel);
}
Window init method:
public void _init_(JPanel panel){
window = new JFrame("Asteroid");
window.setPreferredSize(size);
window.setDefaultCloseOperation(closeOpp);
window.add(panel);
window.getContentPane();
window.setResizable(resizable);
window.setFocusable(focusable);
window.pack();
window.setLocationRelativeTo(location);
window.setVisible(visibility);
}
Panel init method:
public MainPanel(){
//panel initialization
System.out.println("inside constructor");
panel = new JPanel();
this.add(panel);
this.addKeyListener(this);
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.setSize(Window.size);
this.setFocusable(Window.focusable);
this.add(b);
this.setVisible(Window.visibility);
}
Panel listener methods
#Override
public void keyPressed(KeyEvent e) {
System.out.println("key pressed");
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("key released");
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("mouse clicked");
}
public void keyTyped(KeyEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
ps. The panel implements all of the used listeners, all variables are defined, and the program runs with no errors
Your setting you focus to your frame rather than the JPanel, But even changing the focus to the JPanel will provide a level of unpredictable behavior because it is really easy to lose focus of the JPanel. I suggest you use Key Binding or Change your keylistner method and other override methods to attach to the JFrame rather than the JPanel to assure focus is kept during use of application.

How to set up mouse and keyboard input

Hi I'm trying to program a game using java. This is my first time using java, I am used to C#. In C# I would call Mouse.getLocation() and create a rect using the mouses location. Then by using if(Mouse.Left().toString() == "Pressed") I would then check if the mouse rect intersected with any other objects and act accordingly.
I've noticed in java you aren't provided with methods like these. So I was wondering, is the best way to approach mouse input simply to add listeners on all my clickable objects? I understand listeners and have a good idea how to use them but I was just wanting to check if there are more efficient ways to handle input or ways geared more towards what I'm most conformable with.
let your frame implement the MouseListener interface
implement all abstract methods, but in your case it is probably the mouseClicked event
identify if the button clicked is a left click, using the SwingUtilities class
if it is a left click, then set the x and y, which is the location of your click relative to the frame, not the screen.
public class MouseListeningObject extends JFrame implements MouseListener {
int x, y;
public MouseListeningObject () {
addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)){
x = e.getX();
y = e.getY();
}
}
#Override
public void mousePressed(MouseEvent e) {
// Some codes here
}
#Override
public void mouseReleased(MouseEvent e) {
// Some codes here
}
#Override
public void mouseEntered(MouseEvent e) {
// Some codes here
}
#Override
public void mouseExited(MouseEvent e) {
// Some codes here
}
}
You want your frame to implement MouseListener then add it in the constructor.
class MyFrame extends JFrame implements MouseListener {
MyFrame() {
addMouseListener(this);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
}

I am trying to develop a game using java applet, the motion of a ball halts whole of my game?

This is just the begining of the game, where there are two squares, one can be controlled by arrow keys and other by mouse, they can fire balls on each other and simultaneously can be saved, the one getting maximum hits will win...
In this code when I fire from the second square there is a long line which goes towards the second player and whole of the game has to halt..
package raship;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.IOException;
public class raship extends Applet implements KeyListener, MouseMotionListener, MouseListener, Runnable
{
int width,flag1=0,flag2=0,height,x1,y1,x2,y2,calc1,calc2x,calc2y;
Thread t=null;
public void init()
{
//Toolkit toolkit=Toolkit.getDefaultToolkit();
t=new Thread();
width=getSize().width;
height=getSize().height;
x1=0;y1=height/2;
x2=width-10;y2=height/2;
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setBackground(Color.gray);
repaint();
}
public void keyPressed(KeyEvent e)
{
int c=e.getKeyCode();
System.out.println(c);
if(c==KeyEvent.VK_LEFT)
{
System.out.println("yeah it's on");
x1-=10;
}
else if(c==KeyEvent.VK_UP)
y1-=10;
else if(c==KeyEvent.VK_RIGHT)
x1+=10;
else if(c==KeyEvent.VK_DOWN)
y1+=10;
if(x1>=0 && y1>=0 && y1<=height-20 && x1<=3*width/4)
repaint();
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e)
{
x2=e.getX();
y2=e.getY();
if(x2>=5*width/8 && x2<=width-20)
repaint();
}
public void mouseClicked(MouseEvent e)
{
flag2=1;
calc2x=x2;
calc2y=y2;
System.out.println(calc2x);
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
public void paint(Graphics g)
{
width=getSize().width;
height=getSize().height;
g.setColor(Color.green);
g.fillRect(x1, y1, 20, 20);
g.setColor(Color.red);
g.fillRect(x2, y2, 20, 20);
if(flag2==1)
{
g.setColor(Color.yellow);
while(true)
{
calc2x-=1;
System.out.println(calc2x);
g.fillOval(calc2x,calc2y,10,10);
try {
Thread.sleep(4);
} catch (InterruptedException e) {e.printStackTrace();}
if(calc2x<10)
{
flag2=0;
break;
}
}
}
}
#SuppressWarnings("static-access")
public void run()
{
if(flag2==1)
while(true)
{
{
repaint();
System.out.println("calc2x="+calc2x);
if(calc2x<10)
{
flag2=0;
}
try
{
t.sleep(4);
} catch (InterruptedException e) {e.printStackTrace();}
calc2x-=1;
}
}
}
}
NEVER have Thread.sleep(...) in a paint method. EVER. This puts all your drawing to sleep. In fact simply calling Thread.sleep(...) in your GUI thread will be enough to put the GUI to sleep, but its worse still in a paint method, since that method must be called over and over, and needs to be blazing fast and over in the blink of an eye or less.
Instead:
Create a Swing JApplet, not an AWT Applet
Override the paintComponent method of a JPanel to do your drawing
Use a Swing Timer to do your game loop.
Edit
You state in comment:
#HovercraftFullOfEels if you can write the syntax of swing timer and swing applet it would be of great help....
You appear to be wanting me to write tutorials for you. I wish I had all the time to do that, but alas, I don't, and I feel that it would be much more efficient for both you and me for you to check out the decent tutorials with sample code that are already in existence just waiting for you to learn from. For example, please check out the following links:
The Java Tutorials, The Really Big Index
Java Applets
Using Swing Components
How to make Java Applets
How to Use Swing Timers

Java (Swing): MouseMoved not working at all

This is driving me nuts. It must be an extremely simple problem, but I can't possibly see it.
Basically mouseMoved is NEVER called. Below is the code.
public class MouseMotionThing {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame jFrame = new JFrame();
jFrame.setContentPane(new ContentPane());
jFrame.setSize(400, 400);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
}
And my panel. This implementation uses a MouseInputListener:
class ContentPane extends JPanel implements MouseInputListener {
int x = 0, y = 0;
public ContentPane() {
setOpaque(true);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, x, y);
}
#Override
public void mouseDragged(MouseEvent e) {
System.out.println("Mouse Dragged!");
}
#Override
public void mouseMoved(MouseEvent e) {
System.out.println("CALLED MOUSE MOVED");
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
whereas this alternative implementation uses only a MouseMotionListener:
class ContentPane extends JPanel implements MouseMotionListener {
int x = 0, y = 0;
public ContentPane() {
setOpaque(true);
addMouseMotionListener(this);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, x, y);
}
#Override
public void mouseDragged(MouseEvent e) {
System.out.println("Mouse Dragged!");
}
#Override
public void mouseMoved(MouseEvent e) {
System.out.println("CALLED MOUSE MOVED");
x = e.getX();
y = e.getY();
repaint();
}
}
In none of the above alternative implementations is mouseMoved EVER called. I'm adding the right listeners every single time, but it's simply not working. mouseDragged works fine though. What am I missing?
LE: I tested the code on Ubuntu 12.10 & JDK 7, worked fine. Then when I went back to my W8 machine, it started working. I did absolutely nothing more than restart my laptop. I couldn't reproduce the problem nor track it down, but I will come back if I get it again and manage to find something.
It's not clear where things may have gone awry; it may help to do a full build. For reference, I've re-factored your sscce to use a MouseAdapter and remove a leaking this from the JPanel.
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MouseMotionThing {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame jFrame = new JFrame();
jFrame.add(new MousePanel());
jFrame.pack();
jFrame.setSize(400, 400);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
private static class MousePanel extends JPanel {
Point p = new Point();
public MousePanel() {
setOpaque(true);
addMouseMotionListener(new MouseHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, p.x, p.y);
}
private class MouseHandler extends MouseAdapter {
#Override
public void mouseDragged(MouseEvent e) {
update(e);
}
#Override
public void mouseMoved(MouseEvent e) {
update(e);
}
private void update(MouseEvent e) {
System.out.println(e.paramString());
MousePanel.this.p = e.getPoint();
MousePanel.this.repaint();
}
}
}
}
I happened to come across a similar issue in one of the applications I contribute to. I couldn't find anything else that pointed to the root cause, so I started doing some Java AWT logging as illustrated on Oracle's Logging Overview page.
After analyzing parts of the file, I found that there were 5 mouse buttons being registered to the JVM:
<record>
<date>2015-06-18T15:45:54</date>
<millis>1434656754395</millis>
<sequence>70</sequence>
<logger>sun.awt.windows.WDesktopProperties</logger>
<level>FINE</level>
<class>sun.awt.windows.WDesktopProperties</class>
<method>setIntegerProperty</method>
<thread>1</thread>
<message>awt.mouse.numButtons=5</message>
</record>
I also realized that other mouse events (MOUSE_ENTERED, MOUSE_EXITED, MOUSE_DRAGGED) had a extModifiers value of Button5, which is weird because I was just using a touch pad and no other button is pressed. I'm not sure if this would prevent the MOUSE_MOVED event from being fired - I'm guessing this would take some research into lower level Java.
<record>
<date>2015-06-18T15:45:55</date>
<millis>1434656755026</millis>
<sequence>329</sequence>
<logger>java.awt.event.EventDispatchThread</logger>
<level>FINEST</level>
<class>java.awt.EventDispatchThread</class>
<method>pumpOneEventForFilters</method>
<thread>13</thread>
<message>Dispatching: java.awt.event.MouseEvent[MOUSE_ENTERED,(388,387),absolute(388,387),button=0,extModifiers=Button5,clickCount=0] on frame0</message>
</record>
I did some research on extra mouse buttons and found another Oracle page talking about Desktop Properties. I changed the startup parameters of Java to include -Dsun.awt.enableExtraMouseButtons=false, and voila, my application started working again.
I tested a very simple Java application with listening to MOUSE_MOVED on a variety of Windows JRE's, and they all exhibited the same issue when not setting this parameter.
If extra mouse buttons aren't going to be used in your application, then this may be a workaround for you.
Well, it seemed that I had those problems when I used my A4TECH G10-770F mouse on Windows 8. If I turned it off, things went back to normal. I didn't look into it in greater detail though - I already had another mouse and used that one instead.

Passing events to parent

I'd like to create an app where some events are supposed to be handled as if they were delivered to parent containers. For example I've got a JPanel which contains JLabel. The top JPanel implements mousepress and dragging right now. What do I need to do, in order to make the events look like they arrived to JPanel instead of the label itself. (changing source object is important)
Is there some better solution than actually implementing the events and replicating them in the parent? (this would get tedious after some objects with >5 children).
At your event listener, you can dispatch the event to the parent component.
Being myEvent the event handling function argument:
Component source=(Component)myEvent.getSource();
source.getParent().dispatchEvent(myEvent);
But this solution implies creating a new EventListener for each element to add.
So, you could create a single event handler and reuse it, adding it to all the chosen children, like this:
final Container parent=this; //we are a the parent container creation code
MouseListener myCommonListener=new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mouseEntered(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mouseExited(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mousePressed(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mouseReleased(MouseEvent e) {
parent.dispatchEvent(e);
}
};
JLabel label=new JLabel("This is the first Label");
label.addMouseListener(myCommonListener);
JLabel label2=new JLabel("This is the second Label");
label2.addMouseListener(myCommonListener);
//... and so on
You should convert event before dispatching it to the parent. Conversion includes coordinates translation to parent-relative.
public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{
public void mouseClicked(MouseEvent e) {
redispatchToParent(e);
}
public void mousePressed(MouseEvent e) {
redispatchToParent(e);
}
public void mouseReleased(MouseEvent e) {
redispatchToParent(e);
}
public void mouseEntered(MouseEvent e) {
redispatchToParent(e);
}
public void mouseExited(MouseEvent e) {
redispatchToParent(e);
}
public void mouseWheelMoved(MouseWheelEvent e){
redispatchToParent(e);
}
public void mouseDragged(MouseEvent e){
redispatchToParent(e);
}
public void mouseMoved(MouseEvent e) {
redispatchToParent(e);
}
private void redispatchToParent(MouseEvent e){
Component source = (Component) e.getSource();
MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent());
source.getParent().dispatchEvent(parentEvent);
}
}
Mouse events are automatically targeted to the deepest component that has mouse listeners.
Because of this, to achieve your goal, you can simply remove all mouse listeners on the JLabel and it will never get picked as the target for mouse events.
The following code will disable mouse listeners on the given components and their children recursively:
public static void disableMouseForComponent(Component... components) {
for (Component c : components) {
if (c instanceof Container) {
disableMouseForComponent(((Container) c).getComponents());
}
for (MouseListener l : c.getMouseListeners()) {
c.removeMouseListener(l);
}
for (MouseMotionListener l : c.getMouseMotionListeners()) {
c.removeMouseMotionListener(l);
}
}
}

Categories