-2

I'm trying to create a mini version of Processing.

I created a subclass of JPanel and tried to store the Graphics of paintComponent() in a variable and created a ton of functions to render everything.

Would there be a way to create a function that would work like rect(0,0,100,100); without the Processing library? Here is my JPanel subclass:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel; 

public class Screen extends JPanel{
private static final long serialVersionUID = 1L;
private static BufferedImage image;
private int x, y, w, h;

public Screen() {
    repaint();
}
Graphics graphics;
public void paintComponent(Graphics g) {
    graphics = g;
}

public void rect(int x, int y, int width, int height) {
    graphics.fillOval(x, y, width, height);
}

public void ellipse(int x, int y, int width, int height) {          
    graphics.fillOval(x, y, width, height);
}

public void fill(int red, int gr, int bl) {
    graphics.setColor(new Color(red, gr, bl));
}

public void fill1(int gs) {
    graphics.setColor(new Color(gs,gs,gs));
}

public void background(int red, int gr, int bl) {
    Color c = graphics.getColor();
    graphics.setColor(new Color(red, gr, bl));
    graphics.fillRect(0, 0, SnakeGame.gameSizeX, SnakeGame.gameSizeY);
    graphics.setColor(c);
}

public void background(int gs) {
    Color c = graphics.getColor();
    graphics.setColor(new Color(gs, gs, gs));
    graphics.fillRect(0, 0, SnakeGame.gameSizeX, SnakeGame.gameSizeY);
    graphics.setColor(c);
}

public void text(String text, int x, int y) {
    graphics.drawString(text, x, y);
}

public BufferedImage loadImage(String img) {
    try {
        image = ImageIO.read(getClass().getResourceAsStream("/" + img));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return image;   
}

public void image(BufferedImage image, int x, int y, int w, int h) {

    graphics.drawImage(image, x, y, w, h, null);
}

}
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
James51332
  • 164
  • 11
  • 1
    Welcome to StackOverflow. Take the [tour], read [ask], and go through the [checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/) to improve the quality of your question. – RealSkeptic Aug 06 '18 at 15:24
  • 2
    One tip, though: the graphic of `paintComponent` is only valid within `paintComponent`. What you may want to do is create an image, and draw on that image as a graphic object, and then in `paintComponent` draw that image on your "transient" graphic. – RealSkeptic Aug 06 '18 at 15:26
  • I am voting to reopen this question. In its current form it's asking a pretty specific question, and has provide a [mcve] demonstrating what OP is trying to do. – Kevin Workman Aug 06 '18 at 19:15

2 Answers2

1

Processing is open-source, so you can look at exactly how Processing does this here. By default, Processing is built on top of Swing and AWT, so you're basically just trying to recreate what they're doing.

Notice that they don't directly extend JPanel. Instead, they use a BufferedImage as an off-screen buffer. Processing draws to the BufferedImage (which has its own Graphics2D), and then they draw that image to the screen.

That's exactly the approach I would take if I were you. That way you don't have to worry about your Graphics2D only being valid inside the paintComponent() function, and you wouldn't have to redo all of the settings every time your draw() function was called.

Try googling something like "java2d off-screen buffer" for a ton of results, including this Stack Overflow post.

Taking a step back, I'd ask yourself why you're doing this. If it's just for the challenge of understanding how a system like Processing is implemented, then that's cool. But otherwise, if you find yourself trying to recreate something that's already been done, you should generally just use the thing that already works.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • The benefit of recreating my own rendering system id that I can export as a full-blown application without a data folder or anything, whereas processing can only create an Applet. – James51332 Aug 07 '18 at 01:11
  • @James51332 You can export Processing as an application, just like you can export any Java library as an application. – Kevin Workman Aug 07 '18 at 16:16
  • With processing, you can't change the logo. plus this system will be more optimal. – James51332 Aug 07 '18 at 16:55
  • 1
    @James51332 Yes you can, and no it won't. But it's up to you- if this sounds interesting, go for it. – Kevin Workman Aug 07 '18 at 16:57
  • oops, poor assumption. I like the challenge though. – James51332 Aug 08 '18 at 00:34
  • 1
    I'm back reminiscing over some of the things I've done. I mostly program in C/C++ now and thought this was pretty cool. I was going into 7th grade at the time and am now pretty impressed with what I was able to achieve. Anyways, thank you for helping out! – James51332 Jun 26 '20 at 22:53
0

I see what you're trying to do now. Have your functions take in a Graphics object.

For example,

public void ellipse(Graphics g, int x, int y, int width, int height) {          
    g.fillOval(x, y, width, height);
}

And then in your paint component, call:

public void paintComponent(Graphics g){
    Graphics graphics = g;
    ellipse(graphics, x, y, w, h);
}
JasperHsu
  • 45
  • 11
  • Also, rereading your post, this doesn't answer for calling these functions in "any class" in "any method", but as RealSkeptic commented, the graphics of `paintComponent` is only valid within `paintComponent`. – JasperHsu Aug 06 '18 at 16:10
  • Note that you can edit existing answers instead of posting new answers. – Kevin Workman Aug 06 '18 at 16:25