Mouse clicked event non-responsive in java - java

I am trying to write a test java program in order to learn how mouse listeners work in java. Basically, I was trying to write a graphics program and that if I click on the canvas, the program generates a label "hello" at the place where I clicked my mouse. But nothing happens after I click my mouse. Here is my code. Can anybody help me with it?
import acm.program.*;
import acm.graphics.*;
import java.awt.event.*;
public class test extends GraphicsProgram{
public void run(){
addMouseListeners();
}
public void MouseClicked(MouseEvent e){
label=new GLabel("Hello",e.getX(),e.getY());
add(label);
}
private GLabel label=null;
}

Related

Displaying an image and capturing mouse clicks doesn't work at the same time

What I want to do:
I want to write a small application that can display an image. The user has to be able to zoom in and out of the image, move it around, and mark points on the image. Further down the line I want to analyze the points clicked, but I'm not there yet.
What I have so far:
In order to track down my problem I wrote a MVCE:
GUI class for handling the JFrame (and other UI elements later):
import javax.swing.*;
import java.net.MalformedURLException;
import java.net.URL;
public class MCVE_GUI {
public static void main(String[] args) throws MalformedURLException {
MCVE_ZoomPane zp = new MCVE_ZoomPane(new URL("https://fiji.sc/site/logo.png"));
JFrame f = new JFrame("PictureMeasurement");
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setContentPane(zp);
f.pack();
f.setLocationRelativeTo(null);
f.revalidate();
f.repaint();
f.setVisible(true);
}
}
ZoomPanel for handling the image and zooming:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
class MCVE_ZoomPane extends JPanel implements MouseMotionListener {
MCVE_ZoomPane(URL url){
JLabel image = new JLabel();
JScrollPane jsp = new JScrollPane(image);
//image.setIcon(new ImageIcon(url)); // picture, no input
//jsp.setPreferredSize(new Dimension(300,300)); //picture, no input
jsp.setPreferredSize(image.getPreferredSize()); //depends on position of image.setIcon
image.setIcon(new ImageIcon(url)); //no picture, input
this.add(jsp);
this.setPreferredSize(image.getPreferredSize());
this.addMouseMotionListener(this);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
}
public void mouseDragged(MouseEvent e) {
System.out.format("Dragged X:%d Y:%d\n",e.getX(), e.getY());
}
public void mouseMoved(MouseEvent e) {}
}
The problem:
Depending on where I put the image.setIcon(new ImageIcon(url)) I get either the image displayed or can listen to mouse clicks, but not both together. If I set the JScrollPane to a fixed preferred size without calling image.getPreferredSize() I always get a picture but no input.
Apparently I'm stupid. The JScrollPane/JLabel covered the JPanel which was the only component which had a MouseMotionListener. The solution is to add the single line of image.addMouseMotionListener(this);.
I thought about and tried different soltuions to this for at least three hours now. It's a hobby project, so no time constaints, but man do I feel stupid now.

Creating graphics for a simple board game in Java

I have created a board game in Java that is not different in principle from checkers. It works fine in the console but now I'm trying to create graphics. I have a Piece class, a Tile class that checks if it is empty or occupied by a white or a black checkers piece, a Grid class that keeps track of the tiles in a matrix, and a Game class.
Currently, the game can be played in the Grid class; when we run the Grid class, the user specifies the size of the board in the console and then plays the game by giving the x and y coordinates of the tile that the user wishes to select. What I would like to change is to run the game in the Game class, which is an extension of JPanel and implements MouseListener (code given below). The game board will be a fixed size (I'll begin with 5x5) and I have drawn a picture of a grid which should be in the background of the game. There will be an instance variable (Grid g = new Grid(5,5)). I have also drawn pictures of the different "checkers" pieces which will be used, they should be distributed in the foreground on specific tiles. What I want to happen is that when the user clicks a tile, the checkers pieces move. Ideally, I would do this so that the program sees the coordinates of the place that the mouse clicks (say that the JPanel is 500x500 pixels and the user clicks the pixel with the coordinate (0,500), then we check if (0,500) belongs to some tile, if it doesn't then nothing happens, if it does belong to a tile on the Grid g then g.play(something,something)).
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Game extends JPanel implements MouseListener {
private Grid g = new Grid(5,5);
public Game() {
JFrame frame = new JFrame("Boardgame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.setLayout(new FlowLayout());
frame.setPreferredSize(new Dimension(500,500));
frame.pack();
frame.setVisible(true);
frame.addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
//here we check if the user clicked on a tile,
if that happens then we get the x and y-coordinates of the tile and then g.play(x,y)
}
public void mouseEntered(MouseEvent e) {
// we are not really interested in this method or the following
mouse methods but they are necessary for the mouselistener
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public static void main(String args[]) {
new Game();
}
}
So in essence, what I would like to do is:
i) Have a background picture (this is easy right?) [update: I have done this by means of using a JLabel, if there is any better way to do it please tell me].
ii) Fix the MouseListener so that the pieces move when a tile is clicked. The only input I require is which tile is to be moved, we don't need to know which piece is supposed to go there.
Any help would be really appreciated and please ask if I can clarify something. This is not for school or anything, just a private project.
You could use Shape and attach listeners to catch user actions on the shapes.
To enable the user to interact with the graphics you display, you need to be able to determine when the user clicks on one of them. The hit method of the Graphics2D class provides a way to easily determine whether a mouse click occurred over a particular Shape object. Alternatively you can get the location of the mouse click and call contains on the Shape to determine whether the click was within the bounds of the Shape.
read on http://docs.oracle.com/javase/tutorial/2d/advanced/user.html

Why isn't the JButton depressing?

I have a very simple example. A button on the bottom of the screen that says "hi" and when its clicked it prints "hello" to the console. However, When I press the button, it doesn't change visually. Its the same with the other JSwing interactors, but for a SSCCE, here you go.
import acm.program.*;
import javax.swing.*;
import java.awt.event.*;
public class SimpleGUI extends ConsoleProgram {
public void init() {
JButton hi = new JButton("Hi");
add(hi, SOUTH);
addActionListeners();
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals("Hi")) println("Hello there sexy");
}
}
Appearance of Swing controls (including buttons) is controlled by the look-n-feel. This includes whether or not buttons look depressed when clicked.
This may help:
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

Java keylistener and action on object, what's wrong?

Here is my code, what i'm trying to do is to move that rectangle with a key press. Questions - how do i specify it on arrow keys and why it won't allow me to work it that way? It underlines
my paddle object in red in KeyPressed event and won't run.
import acm.graphics.*;
import acm.program.*;
import java.awt.event.*;
public class BreakOut extends GraphicsProgram {
/** Runs the program */
public void run() {
GRect paddle = new GRect(200, 400, 100, 20);
add(paddle);
addKeyListeners();
}
public void keyPressed(KeyEvent e){
paddle.move(5,0);
}
paddle is a local variable in the run() method. It is not accessible from the keyPressed(KeyEvent e) method.
You probably want to turn paddle into a field.
I have no idea what the ACM packages are about and I have no idea what the GrphaicsProgram class is so I don't really know what you are doing.
But, in general, KeyEvents are only passed to object that have have focus. I can't tell if your paddle object has focus or not.
I would suggest you can write your program using Swing and then take advantage of using Key Bindings instead of relying on KeyEvents.
try this:
import acm.graphics.*;
import acm.program.*;
import java.awt.event.*;
public class BreakOut extends GraphicsProgram {
GRect paddle;
public void run() {
paddle = new GRect(200, 400, 100, 20);
add(paddle);
addKeyListeners();
}
public void keyPressed(KeyEvent e){
paddle.move(5,0);
}
}
There are two problems that I can see as of now:
Your program has unbalanced curly braces right now, so you should probably add one to the end of your keyPressed method.
You're not updating the rectangle, so you'll need a loop of some kind.

How to run/compile Java code from JTextArea at Runtime?

I have a JInternalFrame painted with a BufferedImage and contained in the JDesktopPane of a JFrame. I also have a JTextArea where I want to write some java code (function) that takes the current JInternalFrame's painted BufferedImage as an input and after doing some manipulation on this input it returns another manipulated BufferedImage that paints the JInternalFrame with new manipulated Image again.
Manipulation java code of JTextArea:-
public BufferedImage customOperation(BufferedImage CurrentInputImg)
{
Color colOld;
Color colNew;
BufferedImage manipulated=new BufferedImage(CurrentInputImg.getWidth(),CurrentInputImg.getHeight(),BufferedImage.TYPE_INT_ARGB);
// make all Red pixels of current image black
for(int i=0;i< CurrentInputImg.getWidth();i++) {
for(int j=0;j< CurrentInputImg.getHeight(),j++) {
colOld=new Color(CurrentInputImg.getRGB(i,j));
colNew=new Color(0,colOld.getGreen(),colOld.getBlue(),colOld.getAlpha());
manipulated.setRGB(i,j,colNew.getRGB());
}
}
return manipulated;
}
How can I run/compile this JTextArea java code at runtime and get a new
manipulated image for painting on JInternalFrame?
Here is my Main class:
(This class is not actual one but I have created it for you for basic interfacing containing JTextArea,JInternalFrame,Apply Button)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import java.io.File;
import java.util.*;
class MyCustomOperationSystem extends JFrame
{
public JInternalFrame ImageFrame;
public BufferedImage CurrenFrameImage;
public MyCustomOperationSystem() {
setTitle("My Custom Image Operations");
setSize((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight());
JDesktopPane desktop=new JDesktopPane();
desktop.setPreferredSize(new Dimension((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(),(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()));
try {
CurrenFrameImage=ImageIO.read(new File("c:/Lokesh.png"));
}catch(Exception exp) {
System.out.println("Error in Loading Image");
}
ImageFrame=new JInternalFrame("Image Frame",true,true,false,true);
ImageFrame.setMinimumSize(new Dimension(CurrenFrameImage.getWidth()+10,CurrenFrameImage.getHeight()+10));
ImageFrame.getContentPane().add(CreateImagePanel());
ImageFrame.setLayer(1);
ImageFrame.setLocation(100,100);
ImageFrame.setVisible(true);
desktop.setOpaque(true);
desktop.setBackground(Color.darkGray);
desktop.add(ImageFrame);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add("Center",desktop);
this.getContentPane().add("South",ControlPanel());
pack();
setVisible(true);
}
public JPanel CreateImagePanel() {
JPanel tempPanel=new JPanel() {
public void paintComponent(Graphics g) {
g.drawImage(CurrenFrameImage,0,0,this);
}
};
tempPanel.setPreferredSize(new Dimension(CurrenFrameImage.getWidth(),CurrenFrameImage.getHeight()));
return tempPanel;
}
public JPanel ControlPanel() {
JPanel controlPan=new JPanel(new FlowLayout(FlowLayout.LEFT));
JButton customOP=new JButton("Custom Operation");
customOP.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evnt) {
JFrame CodeFrame=new JFrame("Write your Code Here");
JTextArea codeArea=new JTextArea("Your Java Code Here",100,70);
JScrollPane codeScrollPan=new JScrollPane(codeArea,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
CodeFrame.add(codeScrollPan);
CodeFrame.setVisible(true);
}
});
JButton Apply=new JButton("Apply Code");
Apply.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
// What should I do!!! Here!!!!!!!!!!!!!!!
}
});
controlPan.add(customOP);
controlPan.add(Apply);
return controlPan;
}
public static void main(String s[]) {
new MyCustomOperationSystem();
}
}
Note: in the above class JInternalFrame (ImageFrame) is not visible even though I have declared it visible. So, ImageFrame is not visible while compiling and running the above class. You have to identify this problem before running it.
Take a look at the Java 6 Compiler API
If you want to actually compile code from within java, it's doable but not trivial.
It's much better to use a scripting framework like Groovy--that would work great. Groovy is very java-compatible, it will almost always run java code directly (there are a few strange exceptions)
BeanShell is another scripting framework.
These both do just what you want without the effort of trying to figure out how to compile a class then load it into your existing runtime. (Actually, the problem I've seen isn't the initial compile, it's flushing your class so you can replace it with a new one after an edit).

Categories

Resources