1

I'm trying to make some custom fields/circles, but I can't figure out how to call my method, as it needs to take Graphics as a parameter.

I'm already using the standard paint() and paintComponent() in other methods and do not want to move these fields inside one of those.

I've tried to make a ''new'' object like I would do with scanner, arraylist etc., but it is not possible and I can't seem to find anything on how to do so - Is it not even possible? If not, how are you guys calling your methods then?

public void paintFields(Graphics g){
                Graphics2D g2d = (Graphics2D) g;
                g2d.setColor(LightBlue);
                g2d.setStroke(new BasicStroke(5));
                g2d.drawOval(300,300,300,300);

Overview of the code in THIS class, maybe it gives a better understanding. I have a MyFrame dc = new MyFrame(); in another class which sets the underneath class in action

public class MyFrame extends JPanel {
        //color for fields
        Color lightRed = new Color(255,100,100);
        Color lightYellow = new Color(255,255,150);
        Color LightBlue = new Color(170,220,255);
        //attribute for fields (location, size, rotation)
        int xc = 300, yc = 200, r = 100, diam = 25;
        double inc = Math.PI/360, theta = 0, theta2 = 0;


        public MyFrame () {
                Timer timer = new Timer(0, event -> { //set a delay for printing
                        theta = theta + inc;
                        repaint();
                        theta2 = theta2 + inc;
                        repaint();
                }); //Anonymoous class
                timer.start();
        }

        @Override
        public void paint(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;

                g2d.rotate(theta2, xc, yc);
                g2d.setColor(LightBlue);
                g2d.setStroke(new BasicStroke(5));
                g2d.drawOval(xc + r - diam / 2, yc + r - diam / 2, diam, diam);
        }

        public void fields(Graphics g){
                Graphics2D g2d = (Graphics2D) g;
                g2d.setColor(LightBlue);
                g2d.setStroke(new BasicStroke(5));
                g2d.drawOval(300,300,300,300);
        }
}


Narj
  • 39
  • 5
  • 2
    `paintComponent` is passed a `Graphics` context, why can't you just call `instanceOfPaintableObject.paintFields(g);` where `g` is the `Graphics` context passed to `paintComponent`? – MadProgrammer May 18 '22 at 00:20
  • Hmm, because it doesn't accept a (g) if I try. – Narj May 18 '22 at 00:34
  • 1
    [mcve] - otherwise it's guess work – MadProgrammer May 18 '22 at 00:35
  • 2
    Don't call `super.paintComponent` from `paint` - you've just broken the whole paint chain and are going to end up with no end of issues. Instead, override `paintComponent` – MadProgrammer May 18 '22 at 00:38
  • 2
    `Timer(0, `... well, you really don't like yourself. This is likely going to cause you a lot of long time harm as you going to spam the Event Dispatching Thread, besides, in most cases, you're probably not going to achieve better the 5 milliseconds between updates anyway – MadProgrammer May 18 '22 at 00:40
  • Otherwise, when I add `fields(g);` to the end of `paintComponent` (I changed your code), it compiles and works in for me – MadProgrammer May 18 '22 at 00:42
  • Haha, I like your comments ;) I'm a rookie so I will make a lot of these mistakes and are driving while I lay the roads, unfortunately. The timer setup has just been set to 0 to begin with. paint() has now be refactored ;) – Narj May 18 '22 at 00:44
  • Ahh I see, didn't try to put fields(g) at that scope, but what if I didn't wanted it there but under MyFrame()? (where I tried) – Narj May 18 '22 at 00:47
  • At least you're building roads, I tend to just off road and bush bash my way to solution – MadProgrammer May 18 '22 at 00:47
  • 1
    *"but what if I didn't wanted it there but under MyFrame()? (where I tried)"*, well you can't, as you don't have a valid `Graphics` context and it's unlikely that when `MyFrame` is constructed, any will be available to it, nor does it make any sense. Paint is destructive, that is, every time a paint pass occurs, your component is expected to repaint itself from scratched – MadProgrammer May 18 '22 at 00:49
  • Ahh, but sometimes that is the funniest roads to take :P – Narj May 18 '22 at 00:54
  • Hmm okay, it makes sense, but wouldn't it then make most sense to just make ALL graphics under paint() or paintComponent() instead like me and given it an extra call for fields to be painted? – Narj May 18 '22 at 00:56
  • You have to, it's how the painting system works in Swing - see [Painting in AWT and Swing](https://www.oracle.com/java/technologies/painting.html) and [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) for more details. If you want to do "off screen" rendering (fyi, Swing is already double buffered), you could use a `BufferedImage` and use it's `Graphics` context when ever you want, but if you wanted the results on the screen, you'd need to paint the image via the `paintComponent` method. – MadProgrammer May 18 '22 at 01:15
  • Also, as you seem to be doing, call `repaint` to request a new paint pass at some point in the future – MadProgrammer May 18 '22 at 01:15

0 Answers0