XeroxMachine808
XeroxMachine808

Reputation: 43

How do I add an ActionListener to a specific JComponent?

I'm trying to make an ActionListener for a specific JComponent, but in my code, there are two JComponents which have ActionListeners.

Here's my code:

/**
 * This is a Java Swing program that lets you play Minesweeper! Make sure to play it in fullscreen or else it's not going to work.
 * @author  Joshua Diocares
 * @version  JDK14.0
 * @since  Still in development!
 */

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

/**
 * A class that shows the xy coordinates near the mouse cursor.
 */
class AlsXYMouseLabelComponent extends JComponent {

  public int x;
  public int y;

  /**
   * Uses the xy coordinates to update the mouse cursor label.
   */
  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    String coordinates = x + ", " + y; // Get the cordinates of the mouse
    g.setColor(Color.red);
    g.drawString(coordinates, x, y); // Display the coordinates of the mouse
  }

}

public class Minesweeper implements ActionListener {

  private static JComboBox < String > gameModeDropdown;
  private static JComboBox < String > difficultyDropdown;

  public static void main(String[] args) {

    JPanel panel = new JPanel();

    JFrame frame = new JFrame();
    frame = new JFrame();
    frame.setSize(1365, 767);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("Tic Tac Toe");
    frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
    frame.setVisible(true);
    frame.add(panel);

    panel.setLayout(null);

    AlsXYMouseLabelComponent alsXYMouseLabel = new AlsXYMouseLabelComponent();

    /**
     * Add the component to the DRAG_LAYER of the layered pane (JLayeredPane)
     */
    JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
    layeredPane.add(alsXYMouseLabel, JLayeredPane.DRAG_LAYER);
    alsXYMouseLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight());

    /**
     * Add a mouse motion listener, and update the crosshair mouse cursor with the xy coordinates as the user moves the mouse
     */
    frame.addMouseMotionListener(new MouseMotionAdapter() {

      /**
       * Detects when the mouse moved and what the mouse's coordinates are.
       * @param event the event that happens when the mouse is moving.
       */
      @Override
      public void mouseMoved(MouseEvent event) {
        alsXYMouseLabel.x = event.getX();
        alsXYMouseLabel.y = event.getY();
        alsXYMouseLabel.repaint();
      }

    });

    JLabel title = new JLabel("Minesweeper");
    title.setBounds(500, 100, 550, 60);
    title.setFont(new Font("Verdana", Font.PLAIN, 50));
    panel.add(title);

    JLabel gameModePrompt = new JLabel("Game Mode: ");
    gameModePrompt.setBounds(280, 335, 300, 25);
    gameModePrompt.setFont(new Font("Verdana", Font.PLAIN, 20));
    panel.add(gameModePrompt);

    String[] gameModes = {
      "Normal"
    };
    JComboBox < String > gameModeDropdown = new JComboBox < String > (gameModes);
    gameModeDropdown.setBounds(415, 335, 290, 25);
    gameModeDropdown.setFont(new Font("Verdana", Font.PLAIN, 20));
    gameModeDropdown.addActionListener(new Minesweeper());
    panel.add(gameModeDropdown);

    JLabel difficultyPrompt = new JLabel("Difficulty: ");
    difficultyPrompt.setBounds(800, 335, 240, 25);
    difficultyPrompt.setFont(new Font("Verdana", Font.PLAIN, 20));
    panel.add(difficultyPrompt);

    String[] difficulties = {
      "Medium"
    };
    JComboBox < String > difficultyDropdown = new JComboBox < String > (difficulties);
    difficultyDropdown.setBounds(910, 335, 120, 25);
    difficultyDropdown.setFont(new Font("Verdana", Font.PLAIN, 20));
    panel.add(difficultyDropdown);

    JButton playButton = new JButton("Play");
    playButton.setBounds(530, 480, 220, 25);
    playButton.setFont(new Font("Verdana", Font.PLAIN, 20));
    playButton.addActionListener(new Minesweeper());
    panel.add(playButton);

  }


  @Override
  public void actionPerformed(ActionEvent e) {

  }

}

Any suggestions would be really helpful

Upvotes: 1

Views: 950

Answers (1)

Gilbert Le Blanc
Gilbert Le Blanc

Reputation: 51543

I cleaned up your code. I added a PlayListener class as the ActionListener to your Play button. You don't need an ActionListener for either dropdown. You can get the selected dropdown values when you need them in the PlayListener class.

I added a call to the SwingUtilities invokeLater method. This method ensures that your Swing components are created and executed on the Event Dispatch Thread.

I rearranged your JFrame method calls. I don't know if you noticed, but you made the JFrame visible before you created the components. You have to create all the components before you display your JFrame.

Using a null layout and absolute positioning are discouraged. Swing GUIs have to run on different operating systems with different screen monitor pixel sizes. Your GUI barely fit on my monitor. I left your absolute positioning code alone, but in the future, you should learn to use Swing layout managers.

I made the AlsXYMouseLabelComponent class an inline class. You can have as many inline classes as you want. Generally, though, each class should be in a separate file. I made the classes inline to show you how inline classes are defined, and also so I can paste a runnable example file.

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Minesweeper implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Minesweeper());
    }

    private JComboBox<String> gameModeDropdown;
    private JComboBox<String> difficultyDropdown;

    @Override
    public void run() {
        JPanel panel = new JPanel();

        JFrame frame = new JFrame("Minesweeper");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));

        panel.setLayout(null);

        AlsXYMouseLabelComponent alsXYMouseLabel =
                new AlsXYMouseLabelComponent();

        /**
         * Add the component to the DRAG_LAYER of the layered pane (JLayeredPane)
         */
        JLayeredPane layeredPane = frame.getRootPane().getLayeredPane();
        layeredPane.add(alsXYMouseLabel, JLayeredPane.DRAG_LAYER);
        alsXYMouseLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight());

        /**
         * Add a mouse motion listener, and update the crosshair mouse cursor with the
         * xy coordinates as the user moves the mouse
         */
        frame.addMouseMotionListener(new MouseMotionAdapter() {

            /**
             * Detects when the mouse moved and what the mouse's coordinates are.
             *
             * @param event the event that happens when the mouse is moving.
             */
            @Override
            public void mouseMoved(MouseEvent event) {
                alsXYMouseLabel.x = event.getX();
                alsXYMouseLabel.y = event.getY();
                alsXYMouseLabel.repaint();
            }

        });

        JLabel title = new JLabel("Minesweeper");
        title.setBounds(500, 100, 550, 60);
        title.setFont(new Font("Verdana", Font.PLAIN, 50));
        panel.add(title);

        JLabel gameModePrompt = new JLabel("Game Mode: ");
        gameModePrompt.setBounds(280, 335, 300, 25);
        gameModePrompt.setFont(new Font("Verdana", Font.PLAIN, 20));
        panel.add(gameModePrompt);

        String[] gameModes = { "Normal" };
        gameModeDropdown = new JComboBox<String>(gameModes);
        gameModeDropdown.setBounds(415, 335, 290, 25);
        gameModeDropdown.setFont(new Font("Verdana", Font.PLAIN, 20));
        panel.add(gameModeDropdown);

        JLabel difficultyPrompt = new JLabel("Difficulty: ");
        difficultyPrompt.setBounds(800, 335, 240, 25);
        difficultyPrompt.setFont(new Font("Verdana", Font.PLAIN, 20));
        panel.add(difficultyPrompt);

        String[] difficulties = { "Easy", "Medium", "Hard" };
        difficultyDropdown = new JComboBox<String>(difficulties);
        difficultyDropdown.setSelectedIndex(1);
        difficultyDropdown.setBounds(910, 335, 120, 25);
        difficultyDropdown.setFont(new Font("Verdana", Font.PLAIN, 20));
        panel.add(difficultyDropdown);

        JButton playButton = new JButton("Play");
        playButton.setBounds(530, 480, 220, 25);
        playButton.setFont(new Font("Verdana", Font.PLAIN, 20));
        playButton.addActionListener(new PlayListener());
        panel.add(playButton);

        frame.add(panel);
        frame.setSize(1365, 767);
        frame.setVisible(true);
    }

    public class PlayListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            // TODO Auto-generated method stub

        }

    }

    /**
     * A class that shows the xy coordinates near the mouse cursor.
     */
    public class AlsXYMouseLabelComponent extends JComponent {

        private static final long serialVersionUID = 1L;

        public int x;
        public int y;

        /**
         * Uses the xy coordinates to update the mouse cursor label.
         */
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            String coordinates = x + ", " + y; // Get the cordinates of the mouse
            g.setColor(Color.red);
            g.drawString(coordinates, x, y); // Display the coordinates of the mouse
        }

    }

}

Upvotes: 1

Related Questions