1

First Java project so this question is probably very amateur. I'm trying to run the method paintComponent for drawing shapes in a class that extends JFRAME I just can't figure out how to call it. Do I need to create a graphics variable to act as the background so I can call paintComponent(background)? Or maybe a new Planel?

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.Graphics.*;
import java.awt.event.*;
import java.text.*;
public class Pythag extends JFrame implements ActionListener
{

JTextField text1,text2;
JLabel label1,label2,label3;
JButton buttonC;
public Pythag(){
    super ("Pythagorean Theorem");
    // Set up the frame
    this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    this.setBounds (300, 300, 200, 350);
    //creating objects
    JPanel boxY = new JPanel ();
    boxY.setLayout(new BoxLayout(boxY,BoxLayout.Y_AXIS));
    label1 = new JLabel ("A side length",JLabel.CENTER);
    label2 = new JLabel ("B side length",JLabel.CENTER);
    label3 = new JLabel ("Type in side lengths to calculate hypotenuse",JLabel.CENTER);
    buttonC = new JButton ("Button1");
    text1 = new JTextField (10);
    text2 = new JTextField (10);

    //Nestled flow layouts:
    //layout1
    JPanel line = new JPanel();
    line.add(label1);
    line.add(text1);
    boxY.add(line);

    //layout2
    JPanel line2 = new JPanel();
    line2.add(label2);
    line2.add(text2);
    boxY.add(line2);
    //layout 3

    JPanel line3 = new JPanel();
    line3.add(label3);
    boxY.add(line3);
    //layout 4

    JPanel line4 = new JPanel();
    line4.add(buttonC);
    boxY.add(line4);
    //Adding listeners
    buttonC.addActionListener (this);
    text1.addActionListener (this);        
    text2.addActionListener (this);        

    //Setting up
    this.setContentPane (boxY);
    this.setVisible (true);
    this.setSize(450,200);
    // this.add(panel);
    //  Graphics bg = backbuffer.getGraphics();

}

public void actionPerformed (ActionEvent e)
{
    if (e.getSource () == buttonC)
    { 
        calculate();

    }

}

public void calculate(){
    double a,b;
    DecimalFormat Formatter = new DecimalFormat("#0.00");
    try
    {
        a = Double.parseDouble (text1.getText());
        b = Double.parseDouble (text2.getText());
        double hypot=Math.sqrt(a*a + b*b);
        label3.setText("The length of the hypotenuse is: " + Formatter.format(hypot));
    }
    catch (NumberFormatException ex)
    {

        label3.setText("You're clearly a confused, please use NUMBERS for side lengths.");

    }

}
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.fillRect(100,100,20,20);

}


public static void main (String[] args)
{
    new Pythag ();

} // main method
} 
Trows
  • 291
  • 2
  • 12
  • 3
    I don't understand what your question is, but you should call `super.paintComponent(g)` on JPanels with Graphics. (also use `paintComponent(Graphics g)`, not `paint(Graphics g)` on JPanels). Maybe a [mcve] would be helpful :) – Lukas Rotter Sep 13 '15 at 18:20
  • @LuxxMiner Sorry about that. So I'm using a class that extends JFrame – Trows Sep 13 '15 at 18:47
  • You basically CANNOT use a class that extends JFrame in an applet. You have to use a class that extends JApplet. There ain't no other way. You also cannot use `public static void main()` in an applet, but maybe that's just for testing. – markspace Sep 13 '15 at 18:55
  • @LuxxMiner sorry my description here has been super vague I edited the question, which will hopefully explain my situation better. – Trows Sep 13 '15 at 18:57
  • @Trows I know you will call me stupid now :P, but if you want to draw **directly** on the JFrame you indeed have to use `paint(Graphics g)` and `super.paint(g)` - But you *should* draw on a new JPanel with `paintComponent(g)`. The code works for me when I edit it with `paint`... You can also repaint the frame any time with `repaint()`. – Lukas Rotter Sep 13 '15 at 18:59
  • @LuxxMiner So what should I do in order to paint it on a specific JPanel? – Trows Sep 13 '15 at 19:03
  • @Trows I will post an example in a few minutes. – Lukas Rotter Sep 13 '15 at 19:04
  • Add the `@Override` annotation to your `paintComponent` it should produce a compiler error (along with the `super.paintComponent` call). `JFrame` does not have a `paintComponent` so it will never be called as part of the painting process. Have a look at [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html) and [Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/) for more details – MadProgrammer Sep 13 '15 at 23:50

1 Answers1

3

If you do want to override paint(), then only of top-level-containers, see this for a fuller explanation. Still, the "cleanest" way is to create a new class that extends JPanel and overrides paintComponent(). If you want to repaint the panel at runtime, you can just call repaint(). This is an example:

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.Graphics.*;
import java.awt.event.*;
import java.text.*;
import java.util.Random;

public class Pythag {

    public Pythag() {

        JFrame frame = new JFrame("JFrame");

        frame.setContentPane(new MyPanel());

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setVisible(true);

    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Pythag();
            }
        });

    }

    public class MyPanel extends JPanel {

        int x;
        int y;

        public MyPanel() {

            ActionListener al = new ActionListener() {
                Random r = new Random();

                @Override
                public void actionPerformed(ActionEvent e) {

                    x = r.nextInt(getWidth()); // Random x-coordinate
                    y = r.nextInt(getHeight()); // Random y-coordinate
                    repaint(); // Repaints the panel

                }
            };

            Timer timer = new Timer(500, al); // Runs ever 500 milliseconds.
            timer.start();

        }

        @Override
        public void paintComponent(Graphics g) {

            super.paintComponent(g); // Removes previous drawings

            g.setColor(Color.RED);
            g.fillRect(x, y, 10, 10);

        }

    }

}
Community
  • 1
  • 1
Lukas Rotter
  • 4,049
  • 1
  • 13
  • 31