-1

I have an applet which subclasses JFrame. The code is as follows:

package complexviewer;  

import java.awt.*;  
import java.awt.event.*;    
import java.util.concurrent.*;  
import static java.util.concurrent.TimeUnit.*;  
import javax.swing.*;   

public class Applet extends JFrame {    

    // Window and applet stats  
    public static final int windowSize = 400;   
    public static final int updateDelay = 20;   

    // Instance variables   
    private ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);   

    public static void main(String[] args) {    
        new Applet();   
    }   
    public Applet() {   
        // Set up window    
        super("Complex Viewing Frame"); 
        setSize(windowSize, windowSize);    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        setVisible(true);

        // Add listeners    
        JPanel panel = new JPanel();    
        panel.setFocusable(true);   
        panel.addKeyListener(new KeyListener() {    
            public void keyPressed(KeyEvent key) {  
                System.out.println("Key pressed."); 
            }   
            public void keyReleased(KeyEvent key) {}    
            public void keyTyped(KeyEvent key) {}   
        }); 
        panel.addMouseListener(new MouseListener() {    
            public void mouseReleased(MouseEvent mouse) {}  
            public void mouseClicked(MouseEvent mouse) {}   
            public void mousePressed(MouseEvent mouse) {    
                System.out.println("Mouse clicked.");   
            }   
            public void mouseEntered(MouseEvent mouse) {}   
            public void mouseExited(MouseEvent mouse) {}    
        }); 
        panel.addMouseMotionListener(new MouseMotionListener() {    
            public void mouseDragged(MouseEvent mouse) {    
                System.out.println("Mouse dragged.");   
            }   
            public void mouseMoved(MouseEvent mouse) {} 
        }); 
        add(panel); 
        panel.requestFocus();   

        timer.scheduleAtFixedRate(() -> repaint(), 0, 200, MILLISECONDS);   
    }   

    public void paint(Graphics G) { 
        // Drawing  
    }   

}

When I run it, the "Key pressed" event works just fine, but none of the mouse events work. What am I missing here? I looked at other answers like

Also, picking different components like getContentPane() does not seem to fix the problem either.

Community
  • 1
  • 1
Resigned June 2023
  • 4,638
  • 3
  • 38
  • 49
  • 1
    `"I have an applet which subclasses JFrame..."` -- an applet class, which must extend either Applet or JApplet, can not "subclass JFrame". Please clarify. And is your class's name really "Applet"? That is confusing to the extreme. Don't do that. – Hovercraft Full Of Eels Jun 06 '14 at 18:08
  • Consider creating and posting a [minimal compilable and runnable example program](http://stackoverflow.com/help/mcve). – Hovercraft Full Of Eels Jun 06 '14 at 18:09
  • 1
    And this line: `timer.scheduleAtFixedRate(() -> repaint(), 0, 200, MILLISECONDS);` suggests that you have code in a painting method, either paint or paintComponent, which changes the state of this class. You don't want to do that since you don't have control over when or if these methods get called, and you don't want to slow down painting methods. Again, post your minimal code example – Hovercraft Full Of Eels Jun 06 '14 at 18:11
  • 1
    ... And you shouldn't call `setVisible(true)` before adding all components. Only call this after adding all components. Again, create and post your [minimal example program](http://stackoverflow.com/help/mcve) if you are seriously in need of help. – Hovercraft Full Of Eels Jun 06 '14 at 18:15
  • @HovercraftFullOfEels For this (simple, just drawing and receiving keyboard/mouse events) application, what structure would you suggest using besides JFrame? What advantage is there to using JApplet? Or are you just saying it is confusing to call it an "applet"? – Resigned June 2023 Jun 06 '14 at 18:43
  • @HovercraftFullOfEels Furthermore, what is the accepted method of calling repaint() continuously if not a timer? According to [this question](http://stackoverflow.com/questions/1586984/what-is-the-best-way-to-call-repaint-at-regular-intervals-in-my-java2d-program), a javax.swing.Timer, which I heard was deprecated as I should use ScheduledExecutorService instead. – Resigned June 2023 Jun 06 '14 at 18:45
  • It's confusing to say you have an applet that extends JFrame when an applet is something that extends JApplet (and not JFrame) and which does not seem to extend JFrame. – James Kingsbery Jun 06 '14 at 18:57

2 Answers2

2

As noted, you should call setVisible(true) after adding all components. Other issues:

  • Don't name your non-applet GUI "Applet" as this will be extremely confusing to others reviewing your work as the name clashes with a commonly used core Java class. Your class is not an applet and even if it were, should be called something else.
  • You ask, what structure would you suggest using besides JFrame?. I suggest that you rarely extend JFrame but instead gear your code towards creating (or if need be, extending) JPanel. Doing so will increase the flexibility of your class since now it can be used anywhere in a GUI including in a JFrame, in another JPanel, swapped with CardLayout, in a JApplet...
  • You should never paint directly in a JFrame.
  • Instead extend JPanel and draw in its paintComponent(...) method.
  • You don't show your painting code, but since you're calling repaint repeatedly in a Timer, and that timer does nothing else, this suggests that your class's state is changed in the painting method, something that should never occur since you do not have full control over when or even if the painting method is called.
  • You state, According to this question, a javax.swing.Timer, which I heard was deprecated as I should use ScheduledExecutorService instead. This is so very wrong. You should use a Swing Timer for Swing timer needs, not a java.util.Timer. None of these guys are deprecated, but I'm using the ScheduledExecutorService more than a java util Timer in non-Swing applications.
  • The timer code should change the class's state and then call repaint().
  • You will want to favor use of Key Bindings instead of KeyListeners. For one you can avoid the kludge of forcing a JPanel or JFrame to have keyboard focus.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
0

It turned out the problem, as suggested by Hovercraft Full of Eels, was that setVisible(true) was called before add(panel). Moving this statement allowed all the listeners to work properly. A compilable example of the working code is as follows:

package complexviewer;  

import java.awt.*;  
import java.awt.event.*;    
import java.util.concurrent.*;  
import static java.util.concurrent.TimeUnit.*;  
import javax.swing.*;   

public class Applet extends JFrame {    

    // Window and applet stats  
    public static final int windowSize = 400;   
    public static final int updateDelay = 20;   

    // Instance variables   
    private ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);   

    public static void main(String[] args) {    
        new Applet();   
    }   
    public Applet() {   
        // Set up window    
        super("Complex Viewing Frame"); 
        setSize(windowSize, windowSize);    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        // Incorrect location for setVisible    

        // Add listeners    
        JPanel panel = new JPanel();    
        panel.setFocusable(true);   
        panel.addKeyListener(new KeyListener() {    
            public void keyPressed(KeyEvent key) {  
                System.out.println("Key pressed."); 
            }   
            public void keyReleased(KeyEvent key) {}    
            public void keyTyped(KeyEvent key) {}   
        }); 
        panel.addMouseListener(new MouseListener() {    
            public void mouseReleased(MouseEvent mouse) {}  
            public void mouseClicked(MouseEvent mouse) {}   
            public void mousePressed(MouseEvent mouse) {    
                System.out.println("Mouse clicked.");   
            }   
            public void mouseEntered(MouseEvent mouse) {}   
            public void mouseExited(MouseEvent mouse) {}    
        }); 
        panel.addMouseMotionListener(new MouseMotionListener() {    
            public void mouseDragged(MouseEvent mouse) {    
                System.out.println("Mouse dragged.");   
            }   
            public void mouseMoved(MouseEvent mouse) {} 
        }); 
        add(panel); 
        panel.requestFocus();   

        setVisible(true); // Correct location for setVisible    

        timer.scheduleAtFixedRate(() -> repaint(), 0, 200, MILLISECONDS);   
    }   

    public void paint(Graphics G) { 
        // Drawing  
    }   

}   
Resigned June 2023
  • 4,638
  • 3
  • 38
  • 49