Results 1 to 13 of 13
  1. #1
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default Mouse listener does not work through application layers

    I started my project using default NetBeans wizard, creating FrameView class. It handles events through ActionMap and works perfectly fine as a menu.

    However, inside the frame I embedded Applet which is supposed to execute the main game. I need it to handle MouseListener events. But it does not react to any mouse actions as long as it's running. Even Debugger shows that none of three different ways of catch mouse events worked. I guess it may come from weird hierarchy of components, but could find no way to fix it.

    Used Component hierarchy:

    FrameView
    -empty JPanel with MouseListsner
    --Applet with mouseListener

    Any insight would be helpful.
    Last edited by Warmonger; 05-11-2011 at 08:31 AM.

  2. #2
    doWhile is offline Moderator
    Join Date
    Jul 2010
    Location
    California
    Posts
    1,641
    Rep Power
    7

    Default

    Post an SSCCE to demonstrate the problem. We have no clue what is or is not missing...a typical error is not adding the listener to the component, but again we have no clue without code (in the form of an SSCCE and wrapped in the code tags). Further, see How to Write a Mouse Listener (The Java™ Tutorials > Creating a GUI With JFC/Swing > Writing Event Listeners)

  3. #3
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    I restructured the program, getting rid of NetBeans' wizard-created application classes. Apart from that, not much changed:

    Main class, holding main menu
    Java Code:
    public class SwarmShooterView extends JFrame
    {
        MainPanel mainPanel;
        OptionsPanel optionsPanel;
        CreditsPanel creditsPanel;
        Game gameApplet;
        JPanel gamePanel; //holds Applet, which is Panel but not JPanel
    
        public SwarmShooterView()
        {
            GuiHandler guihandler = new GuiHandler(); //static initialization
            setSize(GuiHandler.dimension.width,GuiHandler.dimension.height);
    
            mainPanel = new MainPanel(this);
            optionsPanel = new OptionsPanel(this);
            creditsPanel = new CreditsPanel(this);
            creditsPanel.setVisible(false);
    
            gameApplet = new Game(this);
            gamePanel = new JPanel();
            gamePanel.add(gameApplet, java.awt.BorderLayout.CENTER);
            gamePanel.setPreferredSize(GuiHandler.dimension);
            setContentPane(mainPanel);
            gamePanel.addMouseListener(gameApplet);
            setSize(GuiHandler.dimension);
            setResizable(false);
     
        }
    
        public static void main (String[] args)
        {
            SwarmShooterView swarmShooterView = new SwarmShooterView();
            swarmShooterView.setVisible(true);
        }
    
        @SuppressWarnings("unchecked")
    
        private final Icon[] busyIcons = new Icon[15];
        private int busyIconIndex = 0;
    
    //    public void setVisible(boolean yes)
    //    {
    ////        if (yes)
    ////            setComponent(null);
    ////        else
    ////            setComponent(mainPanel);
    //        gamePanel = mainPanel;
    //    }
    
        @Action
        public void swapView(JPanel currentPanel, JPanel newPanel)
        {
            newPanel.setBounds(mainPanel.getX(), mainPanel.getY(), GuiHandler.dimension.width, GuiHandler.dimension.height);
            newPanel.setVisible(true);
            currentPanel.setVisible(false);
            setContentPane(newPanel);
        }
    
        private JDialog aboutBox;
    }
    Game applet class:
    Java Code:
    public class Game extends Applet implements Runnable, MouseListener
    {
        StopGame pause;
        SwarmShooterView parentPanel;
        private Thread ticker;
        private Control control;
        private boolean running = false;
        MyCanvas canvas;
        Graphics2D graphics;
        BufferStrategy strategy;
    
        Game(SwarmShooterView pp)
        {
            parentPanel = pp;
            pause = new StopGame("Pause");
    
            resize(GuiHandler.dimension);
            setBackground(GuiHandler.backgroundColor);
            canvas = new MyCanvas();
            add(canvas);
            setLayout(null);
            //setIgnoreRepaint(true);
    //        canvas.createBufferStrategy(2);
    //        strategy = canvas.getBufferStrategy();
    //        graphics = (Graphics2D) strategy.getDrawGraphics();
    //        graphics.setColor(getBackground());
    //        graphics.fillRect(0,0,getMaximumSize().width, getMaximumSize().height);
        }
    
        public synchronized void start ()
        {
            if (ticker == null || !ticker.isAlive())
                running = true;
            ticker = new Thread(this);
            control = new Control(this);
            ticker.setPriority(Thread.MIN_PRIORITY + 1);
            control.setPriority(Thread.MAX_PRIORITY);
            addMouseListener(this);
            //control.addMouseListener(this);
            addMouseListener(control);
            ticker.start();
            control.start();
            setBackground(Color.ORANGE);
        }
        
        public void run ()
        {
            int i = 100;
            long lastLoopTime = 0;
            while (running && i > 0)
            {
                //handle timed events
                long delta = System.currentTimeMillis() - lastLoopTime;
                lastLoopTime = System.currentTimeMillis();
                //draw graphics
    //            graphics.dispose();
    //            strategy.show();
                try
                {
                    if (control.mouseClicked)
                    {
                        setBackground(Color.BLACK);
                        repaint();
                    }
                    Thread.sleep(1000 / 30);
                }
                catch (InterruptedException e)
                {}
                i--;
            }
            pause.actionPerformed(null);
        }
    
        @Override
        public synchronized void stop ()
        {
            running = false;
            control = null;
        }
    
        @Override
        public void init()
        {
            Image offscreenimage = createImage(getMaximumSize().width, getMaximumSize().height);
        }
    
        @Override
        public synchronized void paint(Graphics g)
        {
            g.setColor(Color.red);
            g.fillRect(getX(), getY(), getWidth(), getHeight());
        }
    
        public void mousePressed (MouseEvent evt){}
        public void mouseEntered(MouseEvent evt) {}
        public void mouseExited(MouseEvent evt) {}
        public void mouseClicked(MouseEvent evt)
        {
            pause.actionPerformed(null);
            setBackground(Color.BLACK);
            System.out.println("MouseClicked");
        }
        public void mouseReleased(MouseEvent evt) {}
    
        class StopGame extends AbstractAction
        {
            public StopGame(String text)
            {
                super(text);
            }
            public void actionPerformed(ActionEvent e)
            {
               parentPanel.swapView(parentPanel.gamePanel, parentPanel.mainPanel);
               stop();
            }
        }
    }
    Control thread
    Java Code:
    public class Control extends Thread implements KeyListener, MouseListener//, ActionListener
    {
        Game game;
        boolean mouseClicked = false;
    
        //ClickAction clickAction = new ClickAction("Click");
       // setAction(clickAction);
    
        public Control(Game target)
        {
    	super(target);
            game = target;
        }
    
        @Override
        public void run()
        {
            game.setBackground(Color.blue); //dodanie breakpointa sprawia, że okno pozostaje pomaranczowe
        }
    
        public void mousePressed(MouseEvent evt){}
        public void mouseReleased(MouseEvent evt){}
        public void mouseClicked(MouseEvent evt)
        {
            System.out.println("MouseClicked");
            mouseClicked = true;
            game.setBackground(Color.red);
        }
        public void mouseEntered(MouseEvent evt){}
        public void mouseExited(MouseEvent evt){}
        public void keyPressed(KeyEvent e)
        {
            System.out.println("Key Pressed!!!");
            if(e.getKeyCode() == 27)
            {
                System.exit(0);
            }
        }
        public void keyReleased(KeyEvent e)
        {
            System.out.println("Key Released!!!");
        }
        public void keyTyped(KeyEvent e)
        {
    
        }
    
        public void actionPerformed(ActionEvent e)
        {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
    }
    So, there are three ways I try to handle mouse clicking:
    1. Game Applet is Mouse Listener itself and should react to click. May not work due to sleep() call, but would be simplest.
    2. Control Thread is mouse listener itself, reacts to a click and changes color. I know it does so when run() is claled.
    3. Control Thread sets mouseClicked flag, which is checked in main Applet loop.

    Still, it's not quitewhat I wanted. So far I've been binding listener functions only to GUI components, not separate thread, ans used Abstract Actions for convenience. But here it doesn't look like the way it was meant.

  4. #4
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    Ok, I think I got the point. How should I implement Mouse / KeyListener when there are multiple swapping panels inside my frame and only one of them needs this interface, while the others are handled otherwise?

  5. #5
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default

    First off, don't reinvent CardLayout. And respect Swing's single threaded rule. Don't manipulate Swing components on any thread other than the EDT.
    Threads and Swing
    The Last Word in Swing Threads
    Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    How should I implement Mouse / KeyListener when there are multiple swapping panels inside my frame and only one of them needs this interface, while the others are handled otherwise?
    I fail to see the problem. Add the listeners to the component that needs to listen for events.

    db

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default

    Thread moved here from the Java Applets forum.

    db

  7. #7
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    Well, I made some progress.

    Member Listeners didn't seem to work, so I implemented them directly. Now I'm able to manipulate the state of application directly. Also, Timer thread works well.

    However, main thread now behaves competely different and application starts to work only AFTER is ended its Run(). Before that, it only catches mouse input, but performs no action. Not even displays new Panel which should replace Main Menu (which used to work before).

    Main game control:
    Java Code:
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    
    package swarmshooter;
    
    import javax.swing.JApplet;
    import javax.swing.JPanel;
    import java.awt.Component;
    import java.applet.Applet;
    import javax.swing.AbstractAction;
    import java.awt.event.ActionEvent;
    import java.awt.Image;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseMotionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Color;
    import java.awt.image.BufferStrategy;
    import java.awt.image.BufferedImage;
    import java.awt.GraphicsEnvironment;
    import java.awt.GraphicsDevice;
    import java.awt.GraphicsConfiguration;
    import java.awt.Canvas;
    import java.util.Timer;
    import java.util.TimerTask;
    import java.awt.Point;
    /**
     *
     * @author Warmonger
     */
    public class Game extends JPanel implements Runnable, MouseListener, KeyListener
    {
        StopGame pause;
        SwarmShooterView parentPanel;
        private Timer timer; //repaints game area
        private Thread ticker;
        private boolean running = false;
        Canvas canvas;
        Graphics graphics;
        Graphics2D g2d;
        BufferStrategy buffer;
    
        Color color = Color.BLUE;
    
        private static final int KEY_COUNT = 256;
        private static final int BUTTON_COUNT = 3;
    
        private enum KeyState
        {
            RELEASED, // Not down
            PRESSED, // Down, but not the first time
            ONCE      // Down for the first time
        }
        private enum MouseState
        {
    
            RELEASED, // Not down
            PRESSED, // Down, but not the first time
            ONCE      // Down for the first time
        }
        // Current state of the keyboard
        private boolean[] currentKeys = null;
        // Polled keyboard state
        private KeyState[] keys = null;
    
        // Polled position of the mouse cursor
        private Point mousePos = null;
        // Current position of the mouse cursor
        private Point currentPos = null;
        // Current state of mouse buttons
        private boolean[] state = null;
        // Polled mouse buttons
        private MouseState[] poll = null;
    
        Game(SwarmShooterView pp)
        {
            parentPanel = pp;
            pause = new StopGame("Pause");
    
            currentKeys = new boolean[KEY_COUNT];
            keys = new KeyState[KEY_COUNT];
            for (int i = 0; i < KEY_COUNT; ++i)
            {
                keys[i] = KeyState.RELEASED;
            }
            mousePos = new Point(0, 0);
            currentPos = new Point(0, 0);
            // Setup initial button states
            state = new boolean[BUTTON_COUNT];
            poll = new MouseState[BUTTON_COUNT];
            for (int i = 0; i < BUTTON_COUNT; ++i)
            {
                poll[i] = MouseState.RELEASED;
            }
    
            setBounds(GuiHandler.dimension.width, GuiHandler.dimension.height, pp.getX(), pp.getY());
            setMaximumSize(GuiHandler.dimension);
            setMinimumSize(GuiHandler.dimension);
            setPreferredSize(GuiHandler.dimension);
            canvas = new Canvas();
            canvas.setBounds(GuiHandler.dimension.width, GuiHandler.dimension.height, pp.getX(), pp.getY());
            canvas.setIgnoreRepaint( true );
            add(canvas);
            setLayout(null);
            setBackground(GuiHandler.backgroundColor);
    
            graphics = null;
            g2d = null;
        }
    
        public synchronized void start ()
        {
            addMouseListener(this);
            addKeyListener(this);
    
            if (ticker == null || !ticker.isAlive())
                running = true;
            ticker = new Thread(this);
            ticker.setPriority(Thread.MIN_PRIORITY + 1);
            ticker.start();
            setBackground(Color.ORANGE);
    
            timer = new Timer();
            timer.scheduleAtFixedRate(new DrawTimer(this), 0, 30);
        }
        
        public void run ()
        {
            int i = 100;
            long lastLoopTime = 0;
            while (running && i > 0)
            {
                //handle timed events
                long delta = System.currentTimeMillis() - lastLoopTime;
                lastLoopTime = System.currentTimeMillis();
                //draw graphics
    //            graphics.dispose();
    //            strategy.show();
                
                System.out.print(getPosition().toString());
                poll();
                processInput();
                setBackground(color);
                //repaint();
                if(buttonDown(1))
                {
                    System.out.println("Mouse Down detected!");
                }
                try
                {
                    ticker.sleep(15);
                }
                catch (InterruptedException e)
                {}
                i--;
            }
            pause.actionPerformed(null);
    //        stop();
    //        parentPanel.swapView(parentPanel.gamePanel, parentPanel.mainPanel);
        }
    
        public synchronized void stop ()
        {
            running = false;
        }
    
        public void init()
        {
            Image offscreenimage = createImage(getMaximumSize().width, getMaximumSize().height);
        }
    
        @Override
        public synchronized void paint(Graphics g)
        {
            g.setColor(color);
            g.fillRect(getX(), getY(), getWidth(), getHeight());
        }
    
        protected void processInput()
        {
            if (keyDown(1))
            {
                color = Color.BLACK; return;
            }
            if (keyDown(2))
            {
                color = Color.CYAN; return;
            }
            if (keyDown(0))
            {
                color = Color.MAGENTA;
                return;
            }
        }
    
        public synchronized void poll() {
            for (int i = 0; i < KEY_COUNT; ++i)
            {
                if (currentKeys[i])
                {
                    if (keys[i] == KeyState.RELEASED)
                    {
                        keys[i] = KeyState.ONCE;
                    }
                    else
                    {
                        keys[i] = KeyState.PRESSED;
                    }
                }
                else
                {
                    keys[i] = KeyState.RELEASED;
                }
            }
    
            mousePos = new Point(currentPos);
            for (int i = 0; i < BUTTON_COUNT; ++i)
            {
                if (state[i])
                {
                    if (poll[i] == MouseState.RELEASED)
                    {
                        poll[i] = MouseState.ONCE;
                    }
                    else
                    {
                        poll[i] = MouseState.PRESSED;
                    }
                }
                else
                {
                    poll[i] = MouseState.RELEASED;
                }
            }
        }
    
        public Point getPosition()
        {
            return mousePos;
        }
    
        public boolean buttonDownOnce(int button)
        {
            return poll[button - 1] == MouseState.ONCE;
        }
    
        public boolean buttonDown(int button)
        {
            return poll[button - 1] == MouseState.ONCE
                    || poll[button - 1] == MouseState.PRESSED;
        }
    
        public synchronized void mousePressed(MouseEvent e)
        {
            System.out.println(e.getButton());
            state[e.getButton() - 1] = true;
            if (state[0])
            {
                color = Color.BLACK;
            }
            if (state[1])
            {
                color = Color.CYAN;
            }
            if (state[2])
            {
                color = Color.MAGENTA;
            }
        }
    
        public synchronized void mouseReleased(MouseEvent e)
        {
            state[e.getButton() - 1] = false;
        }
    
        public synchronized void mouseEntered(MouseEvent e)
        {
            mouseMoved(e);
        }
    
        public synchronized void mouseExited(MouseEvent e)
        {
            mouseMoved(e);
        }
    
        public synchronized void mouseDragged(MouseEvent e)
        {
            mouseMoved(e);
        }
    
        public synchronized void mouseMoved(MouseEvent e)
        {
            currentPos = e.getPoint();
        }
    
        public synchronized void mouseClicked(MouseEvent e)
        {
            state[e.getButton() - 1] = true;
        }
    
       public boolean keyDown(int keyCode)
       {
            return keys[keyCode] == KeyState.ONCE || keys[keyCode] == KeyState.PRESSED;
        }
    
        public boolean keyDownOnce(int keyCode)
        {
            return keys[keyCode] == KeyState.ONCE;
        }
    
        public synchronized void keyPressed(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            if (keyCode >= 0 && keyCode < KEY_COUNT)
            {
                currentKeys[keyCode] = true;
            }
        }
    
        public synchronized void keyReleased(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            if (keyCode >= 0 && keyCode < KEY_COUNT)
            {
                currentKeys[keyCode] = false;
            }
        }
    
        public synchronized void keyTyped(KeyEvent e)
        {
            if (e.getKeyChar() == 27)
            {
                System.out.println("Esc - exiting");
                pause.actionPerformed(null);
            }
        }
    
        class StopGame extends AbstractAction
        {
            public StopGame(String text)
            {
                super(text);
            }
            public void actionPerformed(ActionEvent e)
            {
               parentPanel.swapView(parentPanel.gamePanel, parentPanel.mainPanel);
               stop();
            }
        }
    }
    Trivial Timer:
    Java Code:
    public class DrawTimer extends TimerTask
    {
        private Game game;
    
        DrawTimer(Game g)
        {
            game = g;
        }
    
        @Override
        public void run()
        {
            //game.processInput();
            game.color = Color.GREEN;
        }
    
    }
    Launching game:

    Java Code:
        class BeginGame extends AbstractAction
        {
            public BeginGame(String text)
            {
                super(text);
            }
            public void actionPerformed(ActionEvent e)
            {
               parentPanel.gamePanel.start();
               parentPanel.gamePanel.run();
               parentPanel.swapView(parentPanel.mainPanel, parentPanel.gamePanel);
            }
        };
    I'm hoping to poll controls in main thread and repaint applet in Timer (possibly also handle game mechanics in another TimerTask), but first of all need to get reliable application control.

  8. #8
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    Ok, I made some progress.

    Member Listeners didn't seem to work, so I implemented these interfaces directly.

    Now app reacts to mouse clicks. Also, there's Timer which influences the display.

    However, main thread behaves oddly. App frezes until it ends its Run(). In the meantime, all mouse actions are remebered and their result is displayed only after this 1.5 second.

    Now app doesn't return to main menu after that period, even though it used to.

    Main game class:

    Java Code:
    public class Game extends JPanel implements Runnable, MouseListener, KeyListener
    {
        StopGame pause;
        SwarmShooterView parentPanel;
        private Timer timer; //repaints game area
        private Thread ticker;
        private boolean running = false;
        Canvas canvas;
        Graphics graphics;
        Graphics2D g2d;
        BufferStrategy buffer;
    
        Color color = Color.BLUE;
    
        private static final int KEY_COUNT = 256;
        private static final int BUTTON_COUNT = 3;
    
        private enum KeyState
        {
            RELEASED, // Not down
            PRESSED, // Down, but not the first time
            ONCE      // Down for the first time
        }
        private enum MouseState
        {
    
            RELEASED, // Not down
            PRESSED, // Down, but not the first time
            ONCE      // Down for the first time
        }
        // Current state of the keyboard
        private boolean[] currentKeys = null;
        // Polled keyboard state
        private KeyState[] keys = null;
    
        // Polled position of the mouse cursor
        private Point mousePos = null;
        // Current position of the mouse cursor
        private Point currentPos = null;
        // Current state of mouse buttons
        private boolean[] state = null;
        // Polled mouse buttons
        private MouseState[] poll = null;
    
        Game(SwarmShooterView pp)
        {
            parentPanel = pp;
            pause = new StopGame("Pause");
    
            currentKeys = new boolean[KEY_COUNT];
            keys = new KeyState[KEY_COUNT];
            for (int i = 0; i < KEY_COUNT; ++i)
            {
                keys[i] = KeyState.RELEASED;
            }
            mousePos = new Point(0, 0);
            currentPos = new Point(0, 0);
            // Setup initial button states
            state = new boolean[BUTTON_COUNT];
            poll = new MouseState[BUTTON_COUNT];
            for (int i = 0; i < BUTTON_COUNT; ++i)
            {
                poll[i] = MouseState.RELEASED;
            }
    
            setBounds(GuiHandler.dimension.width, GuiHandler.dimension.height, pp.getX(), pp.getY());
            setMaximumSize(GuiHandler.dimension);
            setMinimumSize(GuiHandler.dimension);
            setPreferredSize(GuiHandler.dimension);
            canvas = new Canvas();
            canvas.setBounds(GuiHandler.dimension.width, GuiHandler.dimension.height, pp.getX(), pp.getY());
            canvas.setIgnoreRepaint( true );
            add(canvas);
            setLayout(null);
            setBackground(GuiHandler.backgroundColor);
    
            graphics = null;
            g2d = null;
        }
    
        public synchronized void start ()
        {
            addMouseListener(this);
            addKeyListener(this);
    
            if (ticker == null || !ticker.isAlive())
                running = true;
            ticker = new Thread(this);
            ticker.setPriority(Thread.MIN_PRIORITY + 1);
            ticker.start();
            setBackground(Color.ORANGE);
    
            timer = new Timer();
            timer.scheduleAtFixedRate(new DrawTimer(this), 0, 30);
        }
        
        public void run ()
        {
            int i = 100;
            long lastLoopTime = 0;
            while (running && i > 0)
            {
                //handle timed events
                long delta = System.currentTimeMillis() - lastLoopTime;
                lastLoopTime = System.currentTimeMillis();
                //draw graphics
    //            graphics.dispose();
    //            strategy.show();
                
                //System.out.print(getPosition().toString());
                poll();
                processInput();
                setBackground(color);
                //repaint();
                if(buttonDown(1))
                {
                    System.out.println("Mouse Down detected!");
                }
                try
                {
                    ticker.sleep(15);
                }
                catch (InterruptedException e)
                {}
                i--;
            }
            pause.actionPerformed(null);
    //        stop();
    //        parentPanel.swapView(parentPanel.gamePanel, parentPanel.mainPanel);
        }
    
        public synchronized void stop ()
        {
            running = false;
        }
    
        public void init()
        {
            Image offscreenimage = createImage(getMaximumSize().width, getMaximumSize().height);
        }
    
        @Override
        public synchronized void paint(Graphics g)
        {
            g.setColor(color);
            g.fillRect(getX(), getY(), getWidth(), getHeight());
        }
    
        protected void processInput()
        {
            if (keyDown(1))
            {
                color = Color.BLACK; return;
            }
            if (keyDown(2))
            {
                color = Color.CYAN; return;
            }
            if (keyDown(0))
            {
                color = Color.MAGENTA;
                return;
            }
        }
    
        public synchronized void poll() {
            for (int i = 0; i < KEY_COUNT; ++i)
            {
                if (currentKeys[i])
                {
                    if (keys[i] == KeyState.RELEASED)
                    {
                        keys[i] = KeyState.ONCE;
                    }
                    else
                    {
                        keys[i] = KeyState.PRESSED;
                    }
                }
                else
                {
                    keys[i] = KeyState.RELEASED;
                }
            }
    
            mousePos = new Point(currentPos);
            for (int i = 0; i < BUTTON_COUNT; ++i)
            {
                if (state[i])
                {
                    if (poll[i] == MouseState.RELEASED)
                    {
                        poll[i] = MouseState.ONCE;
                    }
                    else
                    {
                        poll[i] = MouseState.PRESSED;
                    }
                }
                else
                {
                    poll[i] = MouseState.RELEASED;
                }
            }
        }
    
        public Point getPosition()
        {
            return mousePos;
        }
    
        public boolean buttonDownOnce(int button)
        {
            return poll[button - 1] == MouseState.ONCE;
        }
    
        public boolean buttonDown(int button)
        {
            return poll[button - 1] == MouseState.ONCE
                    || poll[button - 1] == MouseState.PRESSED;
        }
    
        public synchronized void mousePressed(MouseEvent e)
        {
            System.out.println(e.getButton());
            state[e.getButton() - 1] = true;
            if (state[0])
            {
                color = Color.BLACK;
            }
            if (state[1])
            {
                color = Color.CYAN;
            }
            if (state[2])
            {
                color = Color.MAGENTA;
            }
        }
    
        public synchronized void mouseReleased(MouseEvent e)
        {
            state[e.getButton() - 1] = false;
        }
    
        public synchronized void mouseEntered(MouseEvent e)
        {
            mouseMoved(e);
        }
    
        public synchronized void mouseExited(MouseEvent e)
        {
            mouseMoved(e);
        }
    
        public synchronized void mouseDragged(MouseEvent e)
        {
            mouseMoved(e);
        }
    
        public synchronized void mouseMoved(MouseEvent e)
        {
            currentPos = e.getPoint();
        }
    
        public synchronized void mouseClicked(MouseEvent e)
        {
            state[e.getButton() - 1] = true;
        }
    
       public boolean keyDown(int keyCode)
       {
            return keys[keyCode] == KeyState.ONCE || keys[keyCode] == KeyState.PRESSED;
        }
    
        public boolean keyDownOnce(int keyCode)
        {
            return keys[keyCode] == KeyState.ONCE;
        }
    
        public synchronized void keyPressed(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            if (keyCode >= 0 && keyCode < KEY_COUNT)
            {
                currentKeys[keyCode] = true;
            }
        }
    
        public synchronized void keyReleased(KeyEvent e)
        {
            int keyCode = e.getKeyCode();
            if (keyCode >= 0 && keyCode < KEY_COUNT)
            {
                currentKeys[keyCode] = false;
            }
        }
    
        public synchronized void keyTyped(KeyEvent e)
        {
            if (e.getKeyChar() == 27)
            {
                System.out.println("Esc - exiting");
                pause.actionPerformed(null);
            }
        }
    
        class StopGame extends AbstractAction
        {
            public StopGame(String text)
            {
                super(text);
            }
            public void actionPerformed(ActionEvent e)
            {
               parentPanel.swapView(parentPanel.gamePanel, parentPanel.mainPanel);
               stop();
            }
        }
    }
    Trivial Timer:

    Java Code:
    public class DrawTimer extends TimerTask
    {
        private Game game;
    
        DrawTimer(Game g)
        {
            game = g;
        }
    
        @Override
        public void run()
        {
            //game.processInput();
            game.color = Color.GREEN;
        }
    
    }
    Starting game:

    Java Code:
            {
               //parentPanel.swapView(parentPanel.mainPanel, parentPanel.gamePanel);
               parentPanel.gamePanel.start();
               parentPanel.gamePanel.run();
               parentPanel.swapView(parentPanel.mainPanel, parentPanel.gamePanel);
            }
    I'm hoping to use main thread above only for key poll and TimerTasks(s) for drawing and game mechanic,s but firts need to get some insight of how to get reliable interactive application.
    Any insight is welcome.

  9. #9
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    It works fine now. I do nothing in run() method and cyclic application mehcanisms like repainting or key polling is handled in Timer threads.

    Can be closed now.

  10. #10
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    Hello, I have another issue. I'm going to present my university project soon, but it still needs some tweaks:



    This is the layout of my game. It's a cheap clone of Crimsonland, where you use mouse to aim and shoot.
    Problem was introduced by upper JPanel which displays game stats and is transparent, covering playable area. However, mouse does not accept clicks while I hover the crosshair over this Panel. Of course it works perfectly while at the rest area which is JPanel itself, and mouse position is detected correctly (scaling crosshair) in all visible areas.

    So, how to make mouse work over info panel? Adding listener to it doesn't seem to work, unfortunately.
    Last edited by Warmonger; 06-07-2011 at 09:31 AM.

  11. #11
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Warmonger: I'd create a new forum thread for a new question.

    Also create an SSCCE that illustrates the problem. For instance, when I created an SSCCE to try to reproduce your problem, I couldn't and in fact I could click through an overlayed JPanel with a JLabel without difficulty:

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class MouseThroughComponent extends JPanel {
        private static final int W = 600;
        private static final int H = 400;
        private static final Color BCKGRND = Color.GREEN.darker().darker();
        private static final float PTS = 24f;
    
        private JLabel positionLabel;
    
        public MouseThroughComponent() {
            JPanel topPanel = new JPanel();
            topPanel.setOpaque(false);
            topPanel.setLayout(new GridLayout(2, 3));
    
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < 3; j++) {
                    JLabel label = new JLabel("Label");
                    label.setFont(label.getFont().deriveFont(PTS));
                    label.setBorder(BorderFactory
                            .createLineBorder(Color.LIGHT_GRAY));
                    label.setForeground(Color.white);
                    topPanel.add(label);
                    if (i == 0 && j == 0) {
                        positionLabel = label;
                    }
                }
            }
    
            setBackground(BCKGRND);
            setLayout(new BorderLayout());
            add(topPanel, BorderLayout.NORTH);
    
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    Point p = e.getPoint();
                    String position = String.format("[%03d, %03d]", p.x, p.y);
                    positionLabel.setText(position);
                }
            });
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(W, H);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createGui();
                }
            });
        }
    
        private static void createGui() {
            JFrame frame = new JFrame("App");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new MouseThroughComponent());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    Last edited by Fubarable; 06-07-2011 at 08:11 PM.

  12. #12
    Warmonger is offline Member
    Join Date
    Jan 2011
    Posts
    16
    Rep Power
    0

    Default

    The problem is that by now my game became quite complex and the only way to make it work was to define main class like this:

    Java Code:
    public class Game extends JPanel implements Runnable, MouseListener, MouseMotionListener, KeyListener
    Java Code:
            addMouseListener(this); // works
            expPanel.addMouseListener(this);
            hpLevelPanel.addMouseListener(this);
            weaponPanel.addMouseListener(this);
            ammoPanel.addMouseListener(this);
    So listener is not nested object, but inherited interface.
    Last edited by Warmonger; 06-07-2011 at 10:46 PM.

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    That MouseListener has to be unnecessarily complicated and this can lead to a debugging nightmare. So just don't do that. Don't have a GUI class implement a listener but instead use either anonymous inner classes as I show above or separate stand alone listener classes. You can improve your current code by doing just this.

Similar Threads

  1. mouse click listener from textfield
    By ryanmk54 in forum AWT / Swing
    Replies: 2
    Last Post: 05-11-2011, 03:22 AM
  2. Need Help with Mouse Listener!!!!
    By Doggir in forum New To Java
    Replies: 11
    Last Post: 05-06-2011, 12:48 AM
  3. Mouse Listener
    By Quizerno in forum New To Java
    Replies: 8
    Last Post: 03-17-2011, 06:25 AM
  4. Mouse listening across layers
    By dvreed77 in forum AWT / Swing
    Replies: 1
    Last Post: 02-17-2011, 04:42 PM
  5. Mouse Listener for mouse floating over object?
    By Krooger in forum AWT / Swing
    Replies: 1
    Last Post: 11-18-2009, 05:34 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •