Page 1 of 2 12 LastLast
Results 1 to 20 of 21
  1. #1
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Question Shared variable for other classes

    Solved the initial question, however posted a new one in the fourth post if you would bother to scroll down and see if you know the answer! :) Thank you!
    Direct link to new question:
    Shared variable for other classes

    ____________
    Original post

    In my effort of trying to make my program more tidy and clean I've encountered a problem. Previously I've only coded my programs in one big mess, so now I'm trying to split it up into separate classfiles.

    I'm trying to make a simple paint program, where I'm trying to split it into classfiles as to what makes sense to me. I might have tried to do it in a very difficult way, and I appreciate any tips beyond my problem, the thing I can't quite figure out however is how I can efficiently share variables between my classes.

    I've divided my program into the following java files:
    mainProgram
    - Contains only one line of code generating the GUI which is in a seperate file.

    gui
    - Contains the GUI and actionlisteners, as well as the mouselistener which I want to get the coordinates from.

    settings
    - Contains information about what the user has chosen. Currently there is selection of shape, fixed sizes, fill or just the "edge" and color. This also contains the xStart, xEnd, yStart and yEnd variables which I want to pass from gui into the drawing file.

    drawingPanel
    - Contains the functions for drawing.

    The problem is however, when I do make a new instance of settings in each file they do not share variables obviously.

    So when I in the gui class after having instanced

    Java Code:
    settings s = new settings();
    in both files, they do not share the same variables. This might be obvious, but I thought it was going to work :)

    I then do in the gui file a

    Java Code:
    s.setxStart(event.getX())
    for each of the variables. This ends up with the instance of settings in the gui file containing the right value but obviously not in the drawingPanel file.

    How do I pass variables from one class file to another? Can I make like a public double xStart which all classes can access and edit?

    Thank you for answers, and sorry if my english isn't that good. If anything is unclear please ask and I'll try to clarify.
    - Cemi
    Last edited by Cemi; 04-09-2010 at 10:46 AM.
    Carpe Diem
    Each day's a gift and not a given right

  2. #2
    Webuser is offline Senior Member
    Join Date
    Dec 2008
    Posts
    526
    Rep Power
    0

    Default

    first thing about this that is my question
    why are you using static field? Do you have a const or what?

  3. #3
    exfreelance is offline Member
    Join Date
    Apr 2010
    Posts
    3
    Rep Power
    0

    Default

    static variable can be use to share between classed.
    Other classes can see it and modify it as well

  4. #4
    j2me64's Avatar
    j2me64 is offline Senior Member
    Join Date
    Sep 2009
    Location
    Zurich, Switzerland
    Posts
    962
    Rep Power
    6

    Default

    Quote Originally Posted by exfreelance View Post
    Other classes can see it and modify it as well

    as long the variable is not declared with final.

  5. #5
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    Thanks for replies, I do however have another question.

    I am trying to make it retain the items I have painted when I resize the window, however when I make a "componentListener" which listens to when the JFrame is resized, the for loop runs and is supposedly painting all the shapes which I store in an ArrayList, but there is nothing to be shown. If I do however put it in my paintComponent function it will paint all the shapes next time I paint a new shape after resizing the window. If I do this however, it paints all the shapes every time I paint a shape, which makes all shapes grow in thickness each time, and I asume it's unnecessarily taking up resources.

    Is it because a resize listener will repaint before the window updates, thus the shapes not beeing shown at the JFrame? Where do I have to put it if so?

    My function for repainting:
    Java Code:
    public void paintAll(Graphics g){
    		Graphics2D g2 = (Graphics2D)g;
    		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    				RenderingHints.VALUE_ANTIALIAS_ON);
    		for (int i = 0; i < als.size(); i++){
    			g2.setPaint((Color)alc.get(i));
    			g2.draw((Shape)als.get(i));}
    	}
    As said this does work if I put it inside the paintComponent function, but not if I try to run it upon window resize.

    Why? :/
    Carpe Diem
    Each day's a gift and not a given right

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    I recommend that you do your painting from within the paintComponent method (exceptions if you are using a BufferedImage for the stable portions of the image). Are you calling super.paintComponent(g) as the first method of your paintComponent override? If not, doing this will likely prevent the side effects you are seeing. Best of luck.

  7. #7
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    The problem with doing it in the paintComponent function, in addition to the lines getting thicker is the fact that I can't see the rectangles after resizing until I paint another shape. If I call it in the resize listener the same thing as calling the paintAll function at the moment happens, it writes out my test message which confirms that the for loop is running, yet nothing is displayed.

    Which is what I find weird, the for loop is functioning since the shapes are all painted if I paint another figure and it runs the paintComponent once again. However the for loop is ran upon resizing, yet nothing is displayed until I paint another figure.

    This is my code for the paintComponent and the function I intend to use to paint everything. I do in addition have a pain function which makes new objects based on input from the users mouse actions and other settings which is configureable.

    Java Code:
    public void paintComponent(Graphics g){
    		if (g!=null){
    			super.paintComponent(g);
    			paint(g);
    		}
    	}
    	
    	public void paintAll(Graphics g){
    		Graphics2D g2 = (Graphics2D)g;
    		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    				RenderingHints.VALUE_ANTIALIAS_ON);
    		for (int i = 0; i < als.size(); i++){
    			g2.setPaint((Color)alc.get(i));
    			g2.draw((Shape)als.get(i));}
    	}
    Last edited by Cemi; 04-09-2010 at 12:56 PM.
    Carpe Diem
    Each day's a gift and not a given right

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Perhaps you will want to create a small compilable program that demonstrates your problem, an SSCCE. Please see my link on this below. Then you can post it here and we can play with working (and small) code.

  9. #9
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    I would be happy to, but sscce.org seems to be down, according to It's not just you! it's not just me.

    I've noticed that if I add the componentListener which listens to when the resize happens to the panel instead of the JFrame, the circles are repainting while I move it. But when I release the mouse they aren't there. Just as if my listener is doing the action while it is being resized instead of after as I intend.

    Java Code:
    panel.addComponentListener(new java.awt.event.ComponentAdapter() 
    		{
    			public void componentResized(ComponentEvent e)
    			{
    				System.out.println("JFrame was resized");
    				Graphics g = getGraphics();
    				tp.paintAll(g);
    			}
    		});
    However I've attached the full Eclipse project, which should be quite easy to import as far as I've experienced. In the current version it runs the for loop when the window is resized in the paintAll() function and not in the paintComponent. So now it does not repaint all the squares when you paint another figure since the for luck does not run when you do.

    I do know about other flaws and errors, like not being able to paint figures if you move your mouse in negative directions etc, as it is work in progress I'm just doing one thing at a time as I figure out the Java 2D painting stuff :)

    I hope this can be as helpful for you to help me as an SSCCE even though I don't know what that is yet.

    Thanks.
    Attached Files Attached Files
    Last edited by Cemi; 04-09-2010 at 01:46 PM.
    Carpe Diem
    Each day's a gift and not a given right

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Your painting code is all wrong (sorry to be blunt) and this is what is forcing you to create strange kluges to fix your problems. For example, you're extracting the Graphics object from the JFrame via getGraphics and drawing directly on that in your paintAll method. This has two bad effects: the Graphics object obtained from getGraphics is not stable requiring you to recall this method every time you resize, and by drawing directly on the JFrame, you lose many advantages that the Swing libraries use for doing graphics. You would do well to check out the Sun tutorials on 2D Graphics to show you how to do this right.

    Here's a simple example (which is kind of what an SSCCE is) of using paintComponent:
    Java Code:
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.Shape;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Ellipse2D;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    @SuppressWarnings("serial")
    class DrawOvals extends JPanel {
      private static final Color DRAW_OVAL_COLOR = new Color(200, 200, 255);
      private static final Color FILL_OVAL_COLOR = Color.blue;
      private static final Color OVAL_BORDER_COLOR = Color.blue.darker().darker();
      
      private boolean drawingOval = false;
      private List<Shape> ovalList = new ArrayList<Shape>();
      private int xStart = 0;
      private int yStart = 0;
      private int ovalWidth = 0;
      private int ovalHeight = 0;
      private MyMouse myMouse;
    
      public DrawOvals() {
        myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
      }
    
      @Override
      protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
        for (Shape oval : ovalList) {
          g2d.setColor(FILL_OVAL_COLOR);
          g2d.fill(oval);
    
          g2d.setColor(OVAL_BORDER_COLOR);
          g2d.draw(oval);
        }
        if (drawingOval) {
          g.setColor(DRAW_OVAL_COLOR);
          g.drawOval(xStart, yStart, ovalWidth, ovalHeight);
        }
      }
    
      private class MyMouse extends MouseAdapter {
        Point point0;
        
        @Override
        public void mousePressed(MouseEvent e) {
          drawingOval = true;
          point0 = e.getPoint();
        }
        
        @Override
        public void mouseDragged(MouseEvent e) {
          setOvalPoints(e);
          repaint();
        }
        
        @Override
        public void mouseReleased(MouseEvent e) {
          drawingOval = false;
          setOvalPoints(e);
          
          Ellipse2D oval = new Ellipse2D.Double(xStart, yStart, ovalWidth, ovalHeight);
          ovalList.add(oval);
          repaint();
        }
    
        private void setOvalPoints(MouseEvent e) {
          Point point1 = e.getPoint();
          xStart = Math.min(point0.x, point1.x);
          yStart = Math.min(point0.y, point1.y);
          ovalWidth = Math.abs(point0.x - point1.x);
          ovalHeight = Math.abs(point0.y - point1.y);
        }
    
      }
    
      private static void createAndShowUI() {
        DrawOvals drawOval = new DrawOvals();
        drawOval.setPreferredSize(new Dimension(500, 500));
        
        JFrame frame = new JFrame("Draw Oval");
        frame.getContentPane().add(drawOval);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    
      public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowUI();
          }
        });
      }
    }
    Last edited by Fubarable; 04-09-2010 at 02:28 PM.

  11. #11
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    Alright, thanks :)

    By my painting code I asume you mean the code in the class tegnePanel which contains paintComponent etc.

    I do find that weird as I've been following the book "O'Reilly - Java 2D Graphics" when it comes to painting stuff. I'll try to start over again and try to simplify my code and see if I can make it work :)

    Thank you for taking your time to help me!
    Carpe Diem
    Each day's a gift and not a given right

  12. #12
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Cemi View Post
    Alright, thanks :)
    You're welcome.


    By my painting code I asume you mean the code in the class tegnePanel which contains paintComponent etc.
    Yes.


    I do find that weird as I've been following the book "O'Reilly - Java 2D Graphics" when it comes to painting stuff.
    But does that book have you extracting the Graphics object from a JFrame via getGraphics? Does the book have you override both paint and paintComponent methods in a JPanel and then call paint from within paintComponent?

    If so, throw the book out, but I kind of doubt that it does this.

    As another example, here's one way to do the same graphics I did previously, but using a BufferedImage:
    Java Code:
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Ellipse2D;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    @SuppressWarnings("serial")
    class DrawOvalsBufferedImage extends JPanel {
      private static final Color DRAW_OVAL_COLOR = new Color(200, 200, 255);
      private static final Color FILL_OVAL_COLOR = Color.blue;
      private static final Color OVAL_BORDER_COLOR = Color.blue.darker().darker();
    
      private boolean drawingOval = false;
      private BufferedImage bImage = new BufferedImage(1200, 900, BufferedImage.TYPE_INT_RGB);
      private int xStart = 0;
      private int yStart = 0;
      private int ovalWidth = 0;
      private int ovalHeight = 0;
      private MyMouse myMouse;
    
      public DrawOvalsBufferedImage() {
        Graphics g = bImage.getGraphics();
        g.setColor(Color.white);
        g.fillRect(0, 0, bImage.getWidth(), bImage.getHeight());
        g.dispose();
    
        myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
      }
    
      @Override
      protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(bImage, 0, 0, bImage.getWidth(), bImage.getHeight(), null);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
        if (drawingOval) {
          g.setColor(DRAW_OVAL_COLOR);
          g.drawOval(xStart, yStart, ovalWidth, ovalHeight);
        }
      }
    
      private class MyMouse extends MouseAdapter {
        Point point0;
    
        @Override
        public void mousePressed(MouseEvent e) {
          drawingOval = true;
          point0 = e.getPoint();
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
          setOvalPoints(e);
          repaint();
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
          drawingOval = false;
          setOvalPoints(e);
    
          Ellipse2D oval = new Ellipse2D.Double(xStart, yStart, ovalWidth, ovalHeight);
    
          Graphics2D g2d = bImage.createGraphics();
          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g2d.setColor(FILL_OVAL_COLOR);
          g2d.fill(oval);
          g2d.setColor(OVAL_BORDER_COLOR);
          g2d.draw(oval);
          g2d.dispose();
    
          repaint();
        }
    
        private void setOvalPoints(MouseEvent e) {
          Point point1 = e.getPoint();
          xStart = Math.min(point0.x, point1.x);
          yStart = Math.min(point0.y, point1.y);
          ovalWidth = Math.abs(point0.x - point1.x);
          ovalHeight = Math.abs(point0.y - point1.y);
        }
    
      }
    
      private static void createAndShowUI() {
        DrawOvalsBufferedImage drawOval = new DrawOvalsBufferedImage();
        drawOval.setPreferredSize(new Dimension(500, 500));
    
        JFrame frame = new JFrame("Draw Oval");
        frame.getContentPane().add(drawOval);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    
      public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowUI();
          }
        });
      }
    }

  13. #13
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    Quote Originally Posted by Fubarable View Post
    But does that book have you extracting the Graphics object from a JFrame via getGraphics? Does the book have you override both paint and paintComponent methods in a JPanel and then call paint from within paintComponent?
    I asume it does not then, if it really is that dumb. Haha :rolleyes:

    I'll try to study you're examples and the examples in the book once again, I've been more concerned with making it work at all than making it work properly I guess.
    Carpe Diem
    Each day's a gift and not a given right

  14. #14
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    I have made a working program now, thanks alot! :D

    I do however find it weird to never call paintComponent, but I guess it just updates constantly? :s
    Carpe Diem
    Each day's a gift and not a given right

  15. #15
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,457
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Cemi View Post
    I have made a working program now, thanks alot! :D

    I do however find it weird to never call paintComponent, but I guess it just updates constantly? :s
    No, that method is called whenever the EDT (Event Dispatch Thread) finds it necessary that your component needs repainting. This is called 'passive painting', i.e. your component repaints itself (through the paintComponent( ... ) method) when it is asked to do so; you can only ask the EDT to repaint a component (once in the near future) by calling the repaint() method and even then the EDT may decide that it's not necessary to repaint that particular component.

    The paintComponent( ... ) method is called ever so often (e.g. when the component is resized or exposed from behind another component or moved to another position on the screen) so it should be fast; it should just repaint the component and not perform long winding program logic or install things or open files or whatever; it should paint itself, that's it.

    kind regards,

    Jos
    Last edited by JosAH; 04-09-2010 at 06:49 PM.

  16. #16
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    I see, thank you for clarifying! :)
    Carpe Diem
    Each day's a gift and not a given right

  17. #17
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Also it is always good to know that you can only suggest that it be called via repaint(). The paint manager may decide (if for example the repaint calls are right next to each other), to ignore a repaint call. And further the OS may request a call to paint the app, and this is something that you have no control over. So in other words, your paintComponent method is usually called when you request it be called (via repaint), but not always, and can be called outside of your control. One reason that this is important is that you should never place program logic in the paint or paintComponent methods.

    A very useful article that goes into greater detail on the paint manager and all the above can be found here: Painting in AWT and Swing

  18. #18
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    Thanks for the link, understand the actual painting of the graphics alot better now.

    However I do have another question, I searched google but I couldn't find an answer which could help me. Hopefully this is just a small coding error or something, and not something requiring me to post my entire new code or rewriting the program :)

    I am adding a toolbar to simplify actions instead of going through the menu bar each time the user wants to change something. I have made JTextFields for Width and Height along with a checkbox for Fixed Size if the user wants to create a fixed size Rectangle or Ellipse.

    When I am trying to add an actionlistener to the textFields I get the error that
    "Cannot refer to a non-final variable widthField inside an inner class defined in a different method"

    The code is all within the constructor, the JTextField is initiated normally and the actionlistener looks as follows:

    Java Code:
        JTextField widthField = new JTextField("10",4);
    
    ...............
    
    ActionListener widthListener = new ActionListener() {
        	        public void actionPerformed(ActionEvent e) {
        	            String nyWidth = widthField.getText();
        	            s.setWidth(Integer.parseInt(nyWidth));
        	        }
        	    };
    The error is in the line "String nyWidth = widthField.getText();".

    How can I fix this? I've checked the offical JTextField examples, and tried copying the intializing of the textField and actionListener and altering the variable names to fit mine, still I get this error.
    Carpe Diem
    Each day's a gift and not a given right

  19. #19
    iluxa is offline Senior Member
    Join Date
    Mar 2010
    Posts
    266
    Rep Power
    5

    Default

    just say
    Java Code:
    final JTextField widthField = new JTextField("10",4);
    instead of
    Java Code:
    JTextField widthField = new JTextField("10",4);

  20. #20
    Cemi's Avatar
    Cemi is offline Member
    Join Date
    Apr 2010
    Posts
    36
    Rep Power
    0

    Default

    If it's final, I can't alter the value?

    It only returns the original value of 10 regardless if I state it as final.

    Edit: It worked. :D

    I was so sure that final ment that it was a definite value, and I would not be able to alter it. So much for giving the obvious things a try :(

    Thanks!
    Last edited by Cemi; 04-09-2010 at 11:39 PM.
    Carpe Diem
    Each day's a gift and not a given right

Page 1 of 2 12 LastLast

Similar Threads

  1. variable scope between classes
    By newbie123 in forum New To Java
    Replies: 6
    Last Post: 03-03-2010, 11:20 PM
  2. Scannig for shared files
    By Falcon_minsk in forum Networking
    Replies: 0
    Last Post: 11-07-2009, 11:29 AM
  3. Replies: 1
    Last Post: 07-29-2008, 03:08 AM
  4. Shared variable mutual exclusion problem. Plz help
    By elecrobot in forum Threads and Synchronization
    Replies: 6
    Last Post: 11-25-2007, 02:43 PM
  5. Passing variable information between classes
    By zen_to_go in forum New To Java
    Replies: 1
    Last Post: 10-30-2007, 08:09 PM

Posting Permissions

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