I'm writing a game in java. The problem here is I wrote my game to run in a JFrame, not thinking that i would want to add menus and a results screen and all that good stuff. The game itself runs great in the JFrame. What i decided to do, though, was turn my JFrame into a JPanel, create a separate class for my JFrame and then just add my JPanel to the frame. Everything works just peachy except my MouseListener no longer does a darn thing. Can someone tell me how to make this work or a different idea of how this can be done?
/////UPDATE
So apparently i found an answer while recreating the problem.... I just need the figure out the difference between my game code and the test code.
Here is the example i wrote up to try and reproduce the problem.. Oddly enough this works. Now I'm even more confused. So apparently this is ok:
//Class for the JFrame
package mousetest;
import java.awt.Color;
import javax.swing.JFrame;
public class MouseTest extends JFrame{
public static void main(String[] args) {
MouseTest test = new MouseTest();
}
public MouseTest(){
//create teh board
Board game = new Board();
//framestuff
setSize(406, 630);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
setBackground(Color.black);
add(game); // add it
}
}
========================================================================
//Class for the JPanel that my game is in
package mousetest;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Board extends JPanel{
JLabel testlabel = new JLabel("testtext");
//CONSTRUCTOR
public Board(){
setBackground(Color.WHITE);
testlabel.addMouseListener(new Mousehandle());
setVisible(true);
add(testlabel);
}
// control ALLTHECLICKS!!!!!
class Mousehandle implements MouseListener{
public Mousehandle(){
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if(e.getSource() == testlabel){
System.out.println("mouse down");
}
}
public void mouseReleased(MouseEvent e) {
if(e.getSource() == testlabel){
System.out.println("mouse up");
}
}
public void mouseEntered(MouseEvent e) {
if(e.getSource() == testlabel){
System.out.println("rollover");
}
}
public void mouseExited(MouseEvent e) {
if(e.getSource() == testlabel){
System.out.println("roll off");
}
}
public void mouseDragged(MouseEvent e){
}
}
}
Related
For some reason my jFrame no longer pops up after I add the menu. Is there something I am missing? I'm trying to make a menu that pops up before the beginning of the game and has buttons "play" as well as a text box that allows the user to input a username.
Any suggestions for how I could fix my code? Thank you!
this is my Menu class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Menu extends JPanel{
private static final long serialVersionUID = 1L;
public Menu() {
JPanel buttonPanel = new JPanel(new GridLayout());
JButton play = new JButton();
JButton help = new JButton();
buttonPanel.add(play);
buttonPanel.add(help);
setFocusable(true);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Game.started = true;
}
});
}
public void paint (Graphics g) {
super.paint(g);
g.setColor(Color.black);
g.fillRect(400, 400, Game.WIDTH, Game.HEIGHT);
}
}
and this is my Main class from which I run my program:
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main implements Runnable{
public void run() {
final JFrame frame = new JFrame();
frame.setTitle("Flying Square");
frame.setSize(Game.WIDTH, Game.HEIGHT);
//The menu
final Menu menu = new Menu();
final Game game = new Game();
frame.add(menu, BorderLayout.CENTER);
menu.setVisible(true);
try {while (Game.started == false) {
Thread.sleep(10);
}} catch (InterruptedException e){
e.printStackTrace();
}
frame.remove(menu);
//Main playing area
frame.add(game, BorderLayout.CENTER);
game.setVisible(true);
frame.revalidate();
// Put the frame on the screen
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// add listeners
frame.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
flyingObject.jump();
}
});
frame.addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE)
{
flyingObject.jump();
}
}
});
// Start game
Game.reset();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());
}
}
So, this...
try {while (Game.started == false) {
Thread.sleep(10);
}} catch (InterruptedException e){
e.printStackTrace();
}
Is blocking the Event Dispatching Thread, preventing it from processing any events and basically causing your program to hang.
This is not how you want to process responses from the user. Your Menu should be monitoring for input from the user, probably through one or more ActionListeners, when an action is triggered, it should be notifying some kind of controller, the controller can then make decisions about what it needs to do, like switch the panels for example
You're going to want to break your code down into at least three chunks, the "game" the "menu" and the "controller", this way it will be easier to manage, rather than trying to retrofit the functionality into an existing code
It would recommend having a look at
How to Use CardLayout to help you facilite the switching of the view
How to Use Key Bindings instead of KeyListener
Model-View-Controller
Observer Pattern
The frame opens and close normally but mouse click doesn't work.
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//Create a frame window that responds to mouse click
public class AWT3 extends Frame {
String Mmsg="";
int mouseX=0, mouseY=0;
public AWT3() {
addWindowListener(new MyWindowwAdapter(this));
addMouseListener(new MyMouseeAdapter(this));
}
public void paint(Graphics g){
g.drawString(Mmsg, mouseX, mouseY);
}
public static void main(String args[]){
AWT3 awt3 = new AWT3();
awt3.setSize(new dimension(500, 500));
awt3.setTitle("Window framee");
awt3.setVisible(true);
}
}
class MyWindowwAdapter extends WindowAdapter{
AWT3 awt3;
public MyWindowwAdapter(AWT3 awt3) {
this.awt3=awt3;
}
public void windowClosing(WindowEvent we){
awt3.setVisible(false);
}
}
class MyMouseeAdapter extends MouseAdapter{
AWT3 awt3;
public MyMouseeAdapter(AWT3 awt3) {
this.awt3=awt3;
}
public void MouseClicked(MouseEvent me){
awt3.Mmsg="the mouse is clicked";
awt3.mouseX= me.getX();
awt3.mouseY=me.getY();``
awt3.repaint();
}
}
From what it looks like, this code won't compile. You have an error that you need to fix:
awt3.setSize(new dimension(500, 500));
to
awt3.setSize(new Dimension(500, 500));
and add the proper import java.awt.Dimension as pointed out by others.
Another mistake is that MouseClicked(MouseEvent me) is not overriding the super class method from MouseAdapter as its syntactically wrong (super class method starts with small case). Change it to mouseClicked(MouseEvent me) (add the optional #Override annotation if you wish).
The method name should be public void mouseClicked(MouseEvent me)
instead of public void MouseClicked(MouseEvent me).
mouseClicked() is when the mouse button has been pressed and released.
mousePressed() is when the mouse button has been pressed.
Your code is working. tested on java 1.7. only the problem I saw, was with out importing the java.awt.Dimension class you are trying to create a new dimension(500, 500); although the class name is in simple form you can fix this error and try the code.
1.I am making a cookie click clone i know so mature I'm only 12 and I'm testing my abilities. I have a problem I'm trying to get a label to update but it just won't
tried everything
Also sorry in advance for weird indentation and messiness I'm not great at making good looking code
class
package learning;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.JPanel;
public class Learning extends JFrame implements MouseListener {
int clicks;
boolean Update;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Learning().start();
}
public void start(){
ImageImplement panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(600,600);
setResizable(false);
JLabel Click = new JLabel("Clicks: " + clicks);
Click.setFont(new Font("Arial",Font.PLAIN , 20));
panel.add(Click);
Click.setSize(100,100);
Click.setVisible(true);
addMouseListener(this);
if(Update == true){
Click.setText("Clicks: "+ clicks);
System.out.println("Reached");
}
}
#Override
public void mouseClicked(MouseEvent e) {
clicks += 1;
System.out.println(clicks);
Update = true;
if(Update = true){
Update = false;
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Other picture class
package learning;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
class ImageImplement extends JPanel {
private Image img;
public ImageImplement(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
#Override
public void paintComponent(Graphics g){
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
}
}
Problem #1
Swing, like most GUI's, is event driven, that is something happens and you respond to it. This makes your program non-linear (the code doesn't progress in a straight line).
Events can happen at any time for a multitude of reasons, depending on the event. This means...
if(Update == true){
Click.setText("Clicks: "+ clicks);
System.out.println("Reached");
}
Will never be true, because the event has not occurred at the time the program interprets this command
Problem #2
To over come this issue, your mouseClicked event handler will need to know about the objects you want to update. Currently, you are declaring your variables within a local scope, within the start method...
public void start(){
//...
ImageImplement panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
//...
JLabel Click = new JLabel("Clicks: " + clicks);
}
You will need to change these so that they are accessible at a class instance level
public class Learning extends JFrame implements MouseListener {
int clicks;
boolean Update;
private ImageImplement panel;
private JLabel Click
public void start(){
//...
//ImageImplement panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
panel = new ImageImplement(new ImageIcon("Cookie.jpg").getImage());
//...
//JLabel Click = new JLabel("Clicks: " + clicks);
Click = new JLabel("Clicks: " + clicks);
}
This will allow you to access these objects from any method within any instance of the current class.
Then, within your mouseClicked handler, you can update the Click label...
#Override
public void mouseClicked(MouseEvent e) {
clicks += 1;
Click.setText("Clicks: "+ clicks);
}
Problem #3
Mouse events are contextual to the component that the MouseListener is registered. This means a few things, but in your case, it's possible that the JLabel and ImageImplement could potentially block block mouse events from reaching the component that the MouseListener is registered to.
Instead, it might be better to add the MouseListener to the ImageImplement instead...
addMouseListener(panel);
Additional
JLabel is capable of displaying images, unless you're playing on doing some kind of image manipulation or graphical effect, it might just be easier to use it instead.
You should be calling super.paintComponent in your ImageImplement's paintComponent before doing any additional painting.
You should avoid using setPreferred/Minimum/MaximumSize and instead, override these methods as you need to achieve your desired results
On my Mac, fullscreen JFrames initially have key bindings that do not work, and the computer outputs alert beeps each time I try to type. There is a workaround, though, after fully initializing my JFrame, I added these lines of code and all the errors stopped:
setVisible(false);
setVisible(true);
Here's the source of this workaround: http://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-November/005109.html
Another problem which is yet to be solved is adding a mouse adapter to my full screen JFrame application. Whenever I clicked, the focus changed--to where, I couldn't quite tell, but setting the inputmap of my keybindings to each one of the three options didn't help.
I even tried redoing the workaround when the mouse was clicked by adding this:
event.getComponent().setVisible(false);
event.getComponent().setVisible(true);
but to no avail.
Here is an SSCCE of the problem (it will only show up on a mac):
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class FocusTest extends JFrame{
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public FocusTest() {
MyPanelDescendent myPanelDescendent = new MyPanelDescendent();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(myPanelDescendent);
pack();
setLocationByPlatform(true);
setVisible(true);
KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
Action escapeAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
dispose();
System.exit(0);
}
};
getRootPane().getInputMap(JComponent.WHEN_FOCUSED).put(escapeKeyStroke, "ESCAPE");
getRootPane().getActionMap().put("ESCAPE", escapeAction);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
gs.setFullScreenWindow(this);
setVisible(false);
setVisible(true);
}
private class MyPanelAscendent extends JPanel{
public MyPanelAscendent() {
setFocusable(true);
requestFocusInWindow();
getInputMap(0).put(KeyStroke.getKeyStroke("pressed A"), "pressed");
getActionMap().put("pressed", new AbstractAction() {
#Override public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("a")) {
System.out.println("a was pressed");
}
}
});
addMouseListener(new MyAdapter());
}
}
private class MyPanelDescendent extends MyPanelAscendent {
public MyPanelDescendent() {
super();
}
}
private class MyAdapter extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent event) {
event.getComponent().setVisible(false);
event.getComponent().setVisible(true);
System.out.println("clicked");
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FocusTest();
}
});
}
}
If you press the a key, then click, then do it again, it will not work. The same goes for the escape key: if you click then try to use it, it won't work.
here is an example for fullscreen posted by trashgod which I've also found impossible to make work with both keybindings, fullscreen, and a mouse adapter at the same time.
I have a JComponent, and I want it do preform a piece of code when the component is pressed. Can someone help me?
JComponent comp = new JPanel();
comp.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// Place your code here
}
});
Assuming you have a Class that extends JComponent
import java.swing.*;
import java.awt.*;
import java.awt.event.*;
class MyClass extends JComponent{
public MyClass(){
//Other code
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// Place your code here
}
});
//Other code
}
}