Results 1 to 10 of 10
  1. #1
    Thez is offline Member
    Join Date
    Dec 2007
    Posts
    13
    Rep Power
    0

    Default Problem going outside paintComponent

    I got two classes which can draw a scene/canvas on which I can paint stuff like circles, triangles etc.
    If I draw a shape inside the paintComponent and then fill it, it works fine.

    If I try to do the same thing from outside of the paintCompoment, using the same methods, it gives a nullPointerException.

    The two classes:

    Scene.java

    Java Code:
    // Created by Thez
    // Created on 04 December 2007, 18:48
    
    package crossfire;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Polygon;
    import java.awt.Shape;
    import javax.swing.JPanel;
    
    public class Scene extends javax.swing.JPanel {
        
        private Graphics2D theScene;
        
        //this overrides the original method to allow for modification
        public void paintComponent(Graphics renderScene){
          
            super.paintComponent(renderScene);
            theScene = (Graphics2D)renderScene;
    
            //Shape test = createRectangle(20,20,200,100);
            //fillShape(theShape,new Color(200,120,0));
            
            System.out.println("test");
            
        }      
        
        
        //makes a fully filled drawing of the shape given
        public void fillShape(Shape theShape, Color theColor){
    
            theScene.setColor(theColor);
            theScene.fill(theShape);
            
        }
        
        //makes an outline drawing of the shape given
        public void drawShape(Shape theShape, Color theColor){
            
            theScene.setColor(theColor);
            theScene.draw(theShape);
            
        }
        
        //this creates a rectangle
        public Shape createRectangle(int offsetX, int offsetY, int shapeWidth, int shapeHeight){
            
            Shape newShape = null;
            
            //set the size and position
            int[] xPoints = {offsetX, offsetX + shapeWidth, offsetX + shapeWidth, offsetX};
            int[] yPoints = {offsetY, offsetY, offsetY + shapeHeight, offsetY + shapeHeight};
            
            //a rectangle always has 4 points/corners
            Polygon theRectangle = new Polygon(xPoints,yPoints,4);
            
            //make a shape out of it
            newShape = theRectangle;
            
            return newShape;
        }
    }
    Main.java

    Java Code:
    //Created on 04-12-2007 18:26
    //Created by Thez
    package crossfire;
    
    import java.awt.Color;
    import java.awt.Shape;
    import javax.swing.JFrame;
    
    public class Main {
       
        private Window theWindow;
        private JFrame theFrame;
        private Scene theSceneGenerator;
        
        //load the window, note the dimensions are still needed if made fullscreen, in case the user minimizes
        public Main(){
            
            theWindow = new Window(false,true,800,600,"Test");
            loadSceneIntoFrame();
        }
        
        //startup
        public static void main(String[] args) {
        
            new Main();
            
        }
        
        //this loads the scene class and puts it into the frame
        public void loadSceneIntoFrame(){
            
            //first we get the JFrame
            theFrame = theWindow.getFrame();
            theSceneGenerator = new Scene();
            
            theFrame.getContentPane().add(theSceneGenerator);
            
            Shape test = theSceneGenerator.createRectangle(20,20,200,100);
            theSceneGenerator.fillShape(test,new Color(200,120,0));
        }
        
    }
    Now I've been at it a few hours but I just can't seem to get it to work.
    All I need is to able to draw and remove shapes from the scene/canvas outside the paintComponent.

    Any ideas?

  2. #2
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Using a non–live (eg, member variable) graphics context reference will generally result in a NullPointerException. The way to draw in java is to set up your graphic component to be able to draw the current state of its enclosing class at any time and communicate with it from your event code to change its state and tell it to repaint itself to reflect the changes. All drawing should be placed inside or called from the relevant painting method, here, paintComponent. More like this:
    Java Code:
    import java.awt.*;
    import javax.swing.*;
    
    public class MainScene {
        private JFrame theFrame;
        private Scene theSceneGenerator;
        
        public MainScene(){
            theFrame = new JFrame();
            theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            theFrame.setSize(400,400);
            theFrame.setLocation(200,200);
            theFrame.setVisible(true);
            loadSceneIntoFrame();
        }
        
        private void loadSceneIntoFrame(){
            theSceneGenerator = new Scene();
            theFrame.getContentPane().add(theSceneGenerator);
            // Tell the frame to make a new layout/inventory
            // of its children when making changes after
            // realization.
            theFrame.validate();
            // Sometimes you need this next line, sometimes not;
            // you have to try for the minimum in each case.
    //        theFrame.repaint();
            Shape test = createRectangle(20,20,200,100);
            theSceneGenerator.setFill(true);
            theSceneGenerator.setFillColor(new Color(200,120,0));
            theSceneGenerator.setShape(test);
        }
        
        private Shape createRectangle(int offsetX, int offsetY,
                                      int shapeWidth, int shapeHeight){
            //set the size and position
            int[] xPoints = {offsetX, offsetX + shapeWidth,
                             offsetX + shapeWidth, offsetX};
            int[] yPoints = {offsetY, offsetY, offsetY + shapeHeight,
                             offsetY + shapeHeight};
            
            //a rectangle always has 4 points/corners
            Polygon polygon = new Polygon(xPoints,yPoints,4);
            
            Rectangle rect = new Rectangle(offsetX, offsetY,
                                           shapeWidth, shapeHeight);
            // Both Polygon and Rectangle implement the Shape
            // interface so you can return either one okay.
            
            return rect;
                   //polygon;
        }
        
        public static void main(String[] args) {
            new MainScene();
        }
    }
    
    class Scene extends JPanel {
        private boolean fill = false;
        Color fillColor;
        Shape theShape;
        
        protected void paintComponent(Graphics renderScene){
            super.paintComponent(renderScene);
            Graphics2D g2 = (Graphics2D)renderScene;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            if(fill) {
                g2.setPaint(fillColor);
                g2.fill(theShape);
            }
            g2.setPaint(Color.blue);
            g2.draw(theShape);
            System.out.println("test");
        }      
        
        public void setFill(boolean fill){
            this.fill = fill;
            repaint();
        }
    
        public void setFillColor(Color color) {
            fillColor = color;
            repaint();
        }
        
        public void setShape(Shape theShape){
            this.theShape = theShape;
            repaint();
        }
    }

  3. #3
    Thez is offline Member
    Join Date
    Dec 2007
    Posts
    13
    Rep Power
    0

    Default

    Thanks, I'll sift through it all, but one thing, how can I create multiple shapes in the same scene?
    When I create another shape and fill/draw it, the first one is gone.

  4. #4
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Send in an array of shapes or a list:
    Java Code:
    Shape[] shapes = new Shape[1];
    shapes[0] = rect;
    List<Shape> list = new ArrayList<Shape>();
    list.add(rect);

  5. #5
    Thez is offline Member
    Join Date
    Dec 2007
    Posts
    13
    Rep Power
    0

    Default

    Ah, thanks, I got it working it now.

    One thing, why is the inner class (Scene) protected and not private or public?

  6. #6
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    why is the inner class (Scene) protected and not private or public?
    I didn't see that Scene was an inner class in your original post.

  7. #7
    Thez is offline Member
    Join Date
    Dec 2007
    Posts
    13
    Rep Power
    0

    Default

    Another problem now, using images by classpath.
    I use the Toolkit.getImage() and it will work fine if I use a full path (e.g ""C:\Documents\Thez\test.jpg") but if I try to use a classpath it gives an 'Uncaught error fetching image: NullPointerException'.

    My project has two packages, 'core' and 'images'.
    I tried with a simple JLabel from NetBeans and it uses 'getClass().getResource("/images/test.jpg")' and the label shows the image just fine.

    If I try Toolkit.getImage(getClass().getResource("/images/test.jpg")); it gives the error.

    Any idea what I'm doing wrong?

  8. #8
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    You'll have to experiment with the path until you get it figured out. If the class file is in folder "core" and the image files are in folder "images" and both folders are on the same level in their parent directory/folder "Thez" you could try
    ../images/test.jpg
    in a File constructor. The "../" part moves you up to the parent folder.
    The getResource method requires that the resource be in/on the classpath which means that
    C:\Documents\Thez
    should be part of your classpath environment variable. You can check this environment variable with
    set classpath
    at the prompt.
    If you do have the images in/on the class path then you can experiment with
    Java Code:
    String path_to_try = ...
    URL url = getClass().getReaource(path_to_try);
    System.out.println("url = " + url.getPath());
    to see what the jvm is retuning for a given path.

  9. #9
    Thez is offline Member
    Join Date
    Dec 2007
    Posts
    13
    Rep Power
    0

    Default

    Okay I got that working as well now, but I got another weird problem.
    If I draw an animated gif over a shape (say a red square), it seems to flicker a bit, parts of the red square pop in and out of it while it animates.

    It does animate properly though, but bits of the shape behind it flicker through it randomly.

    Maybe there is some kind of z-index setting like in CSS that is needed?

  10. #10
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    I would load the animated gif into a JLabel with ImageIcon and let the jvm display it. If you want to draw it in paintComponent then you can unpack the images, save them into an array or collection and animate them in your code.

Similar Threads

  1. Drawing outside paintComponent()
    By DarkSide1 in forum Java 2D
    Replies: 2
    Last Post: 11-08-2007, 10:36 PM
  2. paint() and paintComponent()
    By goldhouse in forum Java 2D
    Replies: 1
    Last Post: 07-17-2007, 03:43 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •