Healer_hg
Healer_hg

Reputation: 3

actionPerformed only runs when a Timer starts

Sup, hope you're all ok. For some reason in my java code when I press a key (while that works) my ActionListener is asking me to keep the Timer to start otherwise the condition that would draw a rectangle and show the JLabel simple doesn't run because the actionListener can't call it.

Here is the working code.

package Game;

import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.Rectangle;
import javax.swing.Timer;

public class Riven extends JPanel implements ActionListener
{
    private keyBindings kb;
    private int C_ImageID = 0;
    private Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); //Get screen resolution
    private Image C_Image;
    JLabel mouseX = new JLabel();
    private final int DELAY = 10;
    private Timer timer;

    public Riven()
    {
        initRiven();
    }

    private void initRiven()
    {
        addKeyListener(new TAdapter());
        setBackground(Color.black);
        loadImage();
        setFocusable(true);

        kb = new keyBindings(); //set keyBindings

        //Configuring the Debug JLabel
        mouseX.setFont(new java.awt.Font("Microsoft YaHei UI", Font.PLAIN, 16)); //Set configurations such as Font, and size
        mouseX.setText("Test");
        mouseX.setOpaque(false);
        mouseX.setForeground(Color.white);
        add(mouseX);

        setLayout(null);
        mouseX.setBounds(new Rectangle(new Point(200, 300), mouseX.getPreferredSize()));
        mouseX.setLocation(mouseX.WIDTH + 10, 10);
        mouseX.setVisible(false);

        timer = new Timer(DELAY, this);
        timer.start();
    }

    private void loadImage()
    {
        String imagedir = showImage.importImage(C_ImageID, size);
        ImageIcon ii = new ImageIcon(imagedir);
        C_Image = ii.getImage();
    }

    //Paints
    @Override
    public void paintComponent(Graphics g)
    {
        g.drawImage(C_Image, 0, 0, null); //Draw the front frame
        paintDBG(g);
    }

    private void paintDBG(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;

        if (kb.getDBG()) //If the debug is set to ON
        {
            //set shape color
            g2d.setPaint(Color.black);

            //drawing the rectangle
            g2d.fillRect(0, 0, size.width / 10 , size.height / 10);
            mouseX.setVisible(true);
        }
        else
        {
            g2d.dispose();
            mouseX.setVisible(false);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        repaint();
    }
    
    //Key Bindings
    private class TAdapter extends KeyAdapter
    {
        @Override
        public void keyPressed(KeyEvent e)
        {
            System.out.print("Entrei");
            kb.keyPressed(e);
        }

        @Override
        public void keyReleased(KeyEvent e)
        {
            System.out.print("Sai");
            kb.keyReleased(e);
        }
    }
}

and here is what makes the actionEvent not to execute

package Game;

import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.Rectangle;
import javax.swing.Timer;

public class Riven extends JPanel implements ActionListener
{
    private keyBindings kb;
    private int C_ImageID = 0;
    private Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); //Get screen resolution
    private Image C_Image;
    JLabel mouseX = new JLabel();
    private final int DELAY = 10;
    private Timer timer;

    public Riven()
    {
        initRiven();
    }

    private void initRiven()
    {
        addKeyListener(new TAdapter());
        setBackground(Color.black);
        loadImage();
        setFocusable(true);

        kb = new keyBindings(); //set keyBindings

        //Configuring the Debug JLabel
        mouseX.setFont(new java.awt.Font("Microsoft YaHei UI", Font.PLAIN, 16)); //Set configurations such as Font, and size
        mouseX.setText("Test");
        mouseX.setOpaque(false);
        mouseX.setForeground(Color.white);
        add(mouseX);

        setLayout(null);
        mouseX.setBounds(new Rectangle(new Point(200, 300), mouseX.getPreferredSize()));
        mouseX.setLocation(mouseX.WIDTH + 10, 10);
        mouseX.setVisible(false);

        //timer = new Timer(DELAY, this);
        //timer.start();
    }

    private void loadImage()
    {
        String imagedir = showImage.importImage(C_ImageID, size);
        ImageIcon ii = new ImageIcon(imagedir);
        C_Image = ii.getImage();
    }

    //Paints
    @Override
    public void paintComponent(Graphics g)
    {
        g.drawImage(C_Image, 0, 0, null); //Draw the front frame
        paintDBG(g);
    }

    private void paintDBG(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;

        if (kb.getDBG()) //If the debug is set to ON
        {
            //set shape color
            g2d.setPaint(Color.black);

            //drawing the rectangle
            g2d.fillRect(0, 0, size.width / 10 , size.height / 10);
            mouseX.setVisible(true);
        }
        else
        {
            g2d.dispose();
            mouseX.setVisible(false);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        repaint();
    }
    
    //Key Bindings
    private class TAdapter extends KeyAdapter
    {
        @Override
        public void keyPressed(KeyEvent e)
        {
            System.out.print("Entrei");
            kb.keyPressed(e);
        }

        @Override
        public void keyReleased(KeyEvent e)
        {
            System.out.print("Sai");
            kb.keyReleased(e);
        }
    }
}

Upvotes: 0

Views: 56

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

You appear to be asking why code within an ActionListener is never called unless you turn on a Swing Timer.

The reason is, the Swing library is an event-driven GUI library, and this library has listener classes that when wired into your code properly, have call-back methods that are called in response to events that occur while the program is running, such as KeyListeners that are called only when a keypress occurs.

The same is true for ActionListeners. Their code is only called when the listener is attached to an event generator, and that generator generates an event. For an ActionListener the event generator may be a JButton (via addActionListener) and then the listener code is called when the JButton has been pressed, or it can be attached to a Swing Timer, and when the Timer is started this generates an event that repeats every timer-delay milliseconds until the timer stops.

Other issues with your code:

  • Always call the super's paintComponent method within your override. Otherwise housekeeping painting, such as cleaning of dirty pixels, is not done
  • Never delete a Graphics object given to you by the JVM, such as you are doing, since this breaks the painting chain. Only delete one that you yourself have created.
  • Your paintComponent method does more than it should, as it calls the paintDBG(...) method which changes the state of JLabel's visibility. That state change should go in the timer's ActionListener and not in the painting method.

Upvotes: 1

Related Questions