Search code examples
javaswingapplet

Am not able to test for actions, and therefore cannot update Applet


My main problem is I am confused on where to implement the listener classes so that whenever an action is made (whether it be a key press or mouse click) the applet is updated. I realize my compiling issue is from my CanvasPanel method in my CanvasPanel class and not having arguments in my actionPerformed method. However at this point I'm not sure how these listeners should be implemented correctly. Have tried looking over different questions already posted, so sorry if it is a duplicate.

Here is my code:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class WholePanel extends JPanel
{
   private Color foregroundColor, backgroundColor;
   private int currentDiameter, x1, y1;
   private CanvasPanel canvas;
   private JPanel buttonPanel;

   private JRadioButton filledRadio, unfilledRadio;
   private JRadioButton redRadio, greenRadio;
   private boolean fill;
   private Graphics myCircle;

   public WholePanel()
   {
      backgroundColor = Color.CYAN;
      foregroundColor = Color.RED;

      currentDiameter = 100;
      x1 = 200; y1 = 100;

      unfilledRadio = new JRadioButton("Unfilled", true);
      filledRadio = new JRadioButton("Filled", false);
      redRadio = new JRadioButton("Red", true);
      greenRadio = new JRadioButton("Green", false);

      buttonPanel = new JPanel();
      buttonPanel.add(unfilledRadio);
      buttonPanel.add(filledRadio);
      buttonPanel.add(redRadio);
      buttonPanel.add(greenRadio);

      canvas = new CanvasPanel();

      JSplitPane sPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, buttonPanel, canvas);

      setLayout(new BorderLayout());
      add(sPane, BorderLayout.CENTER);
    }

   private class ColorListener implements ActionListener
    {
     public void actionPerformed(ActionEvent event)
      {
          if (redRadio.isSelected()) {
              greenRadio.setSelected(false);
              backgroundColor = Color.RED;
          }
          else if (greenRadio.isSelected()) {
              redRadio.setSelected(false);
              backgroundColor = Color.GREEN;
          }
          // ...extra else/if statements
      }
    } // end of ColorListener


   private class FillListener implements ActionListener
    {
     private boolean fill;

     public void actionPerformed(ActionEvent event)
      {
            if (filledRadio.isSelected()) {
                unfilledRadio.setSelected(false);
                fill = true;
                paintComponent(myCircle);
            }
            else if (unfilledRadio.isSelected()) {
                filledRadio.setSelected(false);
                fill = false;
                paintComponent(myCircle);
            }
      }
    }

   private class CanvasPanel extends JPanel
    {
     public CanvasPanel( )
      {
        addKeyListener(new DirectionListener());
        addMouseListener(new PointListener());

        setBackground(backgroundColor);

        //This method needs to be called for this panel to listen to keys
        //When panel listens to other things, and go back to listen
        //to keys, this method needs to be called again.

        ColorListener.actionPerformed();
        FillListener.actionPerformed();
        requestFocus();
      }


     public void paintComponent(Graphics page)
      {
          super.paintComponent(page);
          setBackground(backgroundColor);

          page.setColor(foregroundColor);
          page.drawOval(x1, y1, currentDiameter, currentDiameter);
          if (fill == true) { 
              page.fillOval(x1, y1, currentDiameter, currentDiameter);
          }
      }

     /** This method is overriden to enable keyboard focus */
     public boolean isFocusable()
      {
        return true;
      }

     private class DirectionListener implements KeyListener 
       {
         public void keyReleased(KeyEvent e) {}
         public void keyTyped(KeyEvent e) {}
         public void keyPressed(KeyEvent e)
          {
            currentDiameter = 100;
            x1 = 200; y1 = 100;
            int keyCode = e.getKeyCode();
            // switch statement here

            }
          }
       } // end of DirectionListener


     public class PointListener implements MouseListener
       {
         public void mousePressed (MouseEvent event)
          {
            canvas.requestFocus();
          }

         public void mouseClicked (MouseEvent event) {}
         public void mouseReleased (MouseEvent event) {}
         public void mouseEntered (MouseEvent event) {}
         public void mouseExited (MouseEvent event) {}

       } // end of PointListener

    } // end of Canvas Panel Class

} // end of Whole Panel Class

Solution

  • Some major problems in that code:

    • You're calling paintComponent directly, something you should never do. Instead change a state field of your class, call repaint()and then have paintComponent use the state field to decide what it should paint.
    • Same for using a Graphics field -- don't. Instead only use the Graphics object given to your paintComponent method by the JVM. The Swing Graphics tutorial will explain this.
    • You're trying to call your listener call back methods directly, which is the exact opposite of how listeners are supposed to work and negates the benefits of using listeners. Instead ADD your listeners to the components that will use them -- including adding the ActionListeners to the buttons that need them, the KeyListeners to the components that need them, MouseListeners... etc...

    For instance, let's look at a much simpler example, one that uses two JRadioButtons and that's it:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class PartialPanel extends JPanel {
        private static final int PREF_W = 800;
        private static final int PREF_H = 650;
        private static final int CIRC_W = 200;
        private int circleX = 300;
        private int circleY = 200;
        private Color circleColor = null;
        private ButtonGroup buttonGroup = new ButtonGroup();
        private JRadioButton blueButton = new JRadioButton("Blue");
        private JRadioButton redButton = new JRadioButton("Red");
    
        public PartialPanel() {
            ColorListener colorListener = new ColorListener();
            blueButton.addActionListener(colorListener);
            redButton.addActionListener(colorListener);
    
            buttonGroup.add(blueButton);
            buttonGroup.add(redButton);
    
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(blueButton);
            buttonPanel.add(redButton);
    
            add(buttonPanel);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (circleColor != null) {
                g.setColor(circleColor);
                g.fillOval(circleX, circleY, CIRC_W, CIRC_W);
            }
        }
    
        @Override
        public Dimension getPreferredSize() {
            if (isPreferredSizeSet()) {
                return super.getPreferredSize();
            } else {
                return new Dimension(PREF_W, PREF_H);
            }
        }
    
        private class ColorListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == blueButton) {
                    circleColor = Color.BLUE;
                } else if (e.getSource() == redButton) {
                    circleColor = Color.RED;
                }
                repaint();
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    
        private static void createAndShowGui() {
            PartialPanel mainPanel = new PartialPanel();
            JFrame frame = new JFrame("PartialPanel");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    Here we add a ColorListener to the JRadioButtons. In the listener, we change the state of the class's circColor field, and then call repaint(). The paintComponent method then uses circColor's value to decide what color to use when drawing a circle.