Results 1 to 7 of 7

Thread: JButton Problem

  1. #1
    Join Date
    Apr 2011
    Posts
    24
    Rep Power
    0

    Default JButton Problem

    Ok so I'm trying to create a basic JFrame class that has a JPanel on the bottom half and buttons on the top half. The JPanel class uses mouse events to draw lines (similiar to Paint or a drawing program) and the Buttons on the top half are suppose to change the color of the lines drawn and to clear the JPanel screen. I keep getting NullPointerExceptions and have no idea why.
    Class 1 (JPanel + JFrame test class):
    Java Code:
    import javax.swing.JComboBox;
    import javax.swing.SwingUtilities;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.BorderFactory;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Frame;
    import java.awt.Graphics; 
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseMotionListener;
    import java.awt.event.MouseMotionAdapter; 
    
    public class Scribble extends JPanel 
    {
     
        public static void main(String[] args) 
        {
            SwingUtilities.invokeLater(new Runnable() 
            {
                public void run() 
                {
                    createAndShowGUI(); 
                }
            }
            );
        }
    
        private static void createAndShowGUI() 
        {
            MyPanel myPanel1 = new MyPanel(); 
            ColorBox f = new ColorBox(myPanel1); 
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
            f.pack();
            f.setVisible(true);
        } 
        private ColorBox f;
        private JComboBox facenameCombo;
        private String facename;
        private ActionListener listener;
        private static final int FRAME_WIDTH = 600;
        private static final int FRAME_HEIGHT=800;
       
        private Graphics2D g2;
        private JPanel panel;
        public Color color;
    }
    
    class MyPanel extends JPanel {
    
        private int last_x;
        private int last_y;
        private int x;
        private int y;
        private Graphics g;
        
        public MyPanel() 
        {
    
            setBorder(BorderFactory.createLineBorder(Color.black));
            addMouseListener(new MouseAdapter() 
            {
                public void mousePressed(MouseEvent e) 
                {
                    last_x = e.getX();
                    last_y = e.getY();
                   
                }
            }
            );
    
            addMouseMotionListener(new MouseAdapter() 
            {
                public void mouseDragged(MouseEvent e) 
                {
                    x = e.getX();
                    y = e.getY();
                    repaint();
                }
            }
            );
          
        }
       public void Clear()
       {
    	   repaint();
       }
        public Dimension getPreferredSize() 
        {
            return new Dimension(250,200);
        }
        
        protected void paintComponent(Graphics g, Color color)
        {
        	
            g.drawString("This is my custom Panel!",10,20);
            g.setColor(color);
            g.drawLine(last_x, last_y, x, y);
            last_x = x;
            last_y = y;
        }
    
        
    }
    Class 2 (Buttons):
    Java Code:
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import java.applet.*;
    import javax.swing.JPanel;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JComboBox;	
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.event.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.GridLayout;
    	
    public class ColorBox extends JFrame
    {
      
    	private MyPanel myPanel;
    	public ColorBox(MyPanel myPanel) 
          {
             this.myPanel = myPanel;  
             Color color = Color.black;
    
    		class ChoiceListener implements ActionListener 
    		{
    			public void actionPerformed (ActionEvent event) 
    			{
    				JComboBox cb = (JComboBox) event.getSource();
    				Object newItem = cb.getSelectedItem();
    				setColor((String) newItem);
    				
    			}
    		}	
    
    			listener = new ChoiceListener();
    			setLayout(new GridLayout(2,2));
    			createControlPanel();
    			setSize(FRAME_WIDTH, FRAME_HEIGHT);
    			System.out.println("Constructor " + color);
    		}
    		
    		public void createControlPanel()
    		{
    			JPanel facenamePanel = createComboBox();
    			JPanel clearPanel = createClearBox();
    			JPanel scribble = new MyPanel();
    			
    			JPanel controlPanel = new JPanel();
    			controlPanel.setLayout(new GridLayout(3,1));
    			controlPanel.add(facenamePanel);
    			controlPanel.add(clearPanel);
    			controlPanel.add(scribble);
    			add(controlPanel);		
    		}
    		
    		public JPanel createComboBox()
    		{
    			facenameCombo = new JComboBox();
    			facenameCombo.addItem("Black");
    			facenameCombo.addItem("Blue");
    			facenameCombo.addItem("Red");
    			facenameCombo.addItem("Blue");
    			facenameCombo.addItem("Green");
    			facenameCombo.addItem("Orange");
    			facenameCombo.addItem("Pink");
    			facenameCombo.addItem("Yellow");
    			facenameCombo.setEditable(true);
    			facenameCombo.addActionListener(listener);
    			
    			
    			JPanel panel = new JPanel();
    			panel.add(facenameCombo);
    			return panel;
    				
    		}
    		
    		public void setColor(String newItem)
    		{		
    			if (newItem.equals("Blue")) color = (Color.BLUE);
    				
    			else if(newItem.equals("Black")) color = (Color.BLACK);
    				
    			else if (newItem.equals("Blue")) color = (Color.BLUE);
    				
    			else if (newItem.equals("Red")) color = (Color.RED);
    				
    			else if (newItem.equals("Green")) color = (Color.GREEN);
    				
    			else if (newItem.equals("Orange")) color = (Color.ORANGE);
    				
    			else if (newItem.equals("Pink")) color = (Color.PINK);
    				
    			else if (newItem.equals("Yellow")) color = (Color.YELLOW);
    			System.out.println("setColor method " + color);
    			getColor();
    		
    			}	
    		public void getColor() 
    		{
    			System.out.println(color);
    			
    			
    		}
    	      public JPanel createClearBox()
    	      {
    	         clearButton = new JButton("Clear");
    	         clearButton.addActionListener(new ActionListener() {
    	         
    	                  public void actionPerformed(ActionEvent e)
    	                  {
    	                  myPanel.Clear();
    	                  
    	                  }
    	              });      
    	         JPanel panel = new JPanel();
    	         panel.add(clearButton);
    	         return panel;
    	         
    	      }
    
    
    		private JComboBox facenameCombo;
    		private JButton clearButton;
    		
    		private ActionListener listener;
    		private static final int FRAME_WIDTH = 600;
    		private static final int FRAME_HEIGHT=800;
    		private JPanel panel;
    		public Color color;
    		private MyPanel mypanel;
    }
    All I know is that whenever the ClearButton is clicked nothing happens (if i remove MyPanel mypanel = new MyPanel(); statement, it becomes NullPointerException) so that means it is not running the Clear method (not sure why tho) and whenever I change the color on the JComboBox the color changes in the setColor method, but whenever the getColor method is accesssed, the color is null. I'm using Java Eclipse and any help would be much appreciated =)
    Last edited by PorgrammingNoob117; 04-28-2011 at 11:46 PM.

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

    Default

    When you create a new MyPanel object in your clear button's action listener, you must understand that this is a completely new and distinct object from the MyPanel object that is being displayed, and so calling methods on the MyPanel object in the listener will have absolutely no effect on the MyPanel object that is being displayed.

    To solve this, your ColorBox class needs a reference to the MyPanel class so that it can peform actions on the MyPanel that the user sees. One way is to pass the ColorBox class a reference to the MyPanel object via a constructor parameter. Something like:

    Java Code:
        private static void createAndShowGUI() 
        {
            MyPanel myPanel = new MyPanel(); // create the MyPanel object for display
            ColorBox f = new ColorBox(myPanel); // pass it into ColorBox
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
            // f.add(new MyPanel());  // don't even need this
         
            f.pack();
            f.setVisible(true);
        }


    And you'd change your ColorBox class to allow it to accept the reference passed into its constructor and place it into your class MyPanel field that you already have:

    Java Code:
    public class ColorBox extends JFrame
    {
          public ColorBox(MyPanel myPanel) // allow constructor to accept reference to myPanel
          {
             this.myPanel = myPanel;  // set the myPanel field to hold this reference
             Color color = Color.black;
    
             // .... etc...


    Then you can use this reference in your inner class listener:

    Java Code:
          public JPanel createClearBox()
          {
             clearButton = new JButton("Clear");
             clearButton.addActionListener(new ActionListener() {
             //  MyPanel mypanel = new MyPanel();     // no need for this now as we have the reference!
                      public void actionPerformed(ActionEvent e)
                      {
                         mypanel.clear();               }
                  });      
             JPanel panel = new JPanel();
             panel.add(clearButton);
             return panel;
             
          }

  3. #3
    Join Date
    Apr 2011
    Posts
    24
    Rep Power
    0

    Default

    Ok 2 things: One I actually do need the f.add(new MyPanel()); or else the class won't be added to the JFrame and second the Statement actually runs, but doesn't clear the screen because the repaint method just runs the paintComponent() and justs draw another line at the previous location. The only thing I can thing of is adding a super.paintComponent(g) to the paintComponent method, but that will never allow me to draw lines and I could try to minimize and reopen the frame using frame.setState(FRAME.NORMAL or FRAME.ICONIFIED), but that requires me accessed the Scribble class as well....

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

    Default

    Quote Originally Posted by PorgrammingNoob117 View Post
    Ok 2 things: One I actually do need the f.add(new MyPanel()); or else the class won't be added to the JFrame
    No, in fact you don't, not if you add the JPanel to the JFrame in the JFrame-extending class's constructor. If you follow my recommendation, the ColorBox class will get an instance of MyPanel passed into its constructor and you can use this instance and add it to the JFrame's contentPane.


    and second the Statement actually runs, but doesn't clear the screen because the repaint method just runs the paintComponent() and justs draw another line at the previous location. The only thing I can thing of is adding a super.paintComponent(g) to the paintComponent method, but that will never allow me to draw lines and I could try to minimize and reopen the frame using frame.setState(FRAME.NORMAL or FRAME.ICONIFIED), but that requires me accessed the Scribble class as well....
    Adding super.paintComponent(g) is in fact a great idea and I heartily endorse it, and it should not prevent you from drawing lines if it's the first method in the paintComponent override. Your MyPanel class should hold and ArrayList of Point that is added to by the MouseListener and your paintComponent method should iterate through this list drawing the lines. Also you should not create new ColorBox object in paintComponent but rather if you need to access pass an instance of ColorBox into MyPanel. You would probably need a setter method for this in MyPanel, i.e.,

    Java Code:
    public void setColorBox(ColorBox colorBox) {
       this.colorBox = colorBox;
    }

  5. #5
    Join Date
    Apr 2011
    Posts
    24
    Rep Power
    0

    Default

    What I am saying is if I add super.paintComponent(g) to paintComponent such as this:
    Java Code:
    protected void paintComponent(Graphics g)
        {
        	super.paintComponent(g);
            g.drawString("This is my custom Panel!",10,20);
            g.drawLine(last_x, last_y, x, y);
            last_x = x;
            last_y = y;
        }
    What will happen is whenever I'm trying to draw, the lines disappear because they are being cleared when the mouseAction accesses the paintComponent method.

    Also if I add the super.paintComponent(g); in the clear method:
    Java Code:
    public void clear()
        {
        	super.paintComponent(g);
        }
    Post*
    I get the NullPointerException....
    *Edit Updated Code in First Post*
    Last edited by PorgrammingNoob117; 04-28-2011 at 11:47 PM.

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

    Default

    Quote Originally Posted by PorgrammingNoob117 View Post
    What I am saying is if I add super.paintComponent(g) to paintComponent such as this:
    Java Code:
    protected void paintComponent(Graphics g)
        {
        	super.paintComponent(g);
            g.drawString("This is my custom Panel!",10,20);
            g.drawLine(last_x, last_y, x, y);
            last_x = x;
            last_y = y;
        }
    What will happen is whenever I'm trying to draw, the lines disappear because they are being cleared when the mouseAction accesses the paintComponent method.
    Right, and that's because your paintComponent method only draws one line. If you want it to draw multiple lines, you need to do what I told you to in my post above: create an ArrayList of data, and then in paintComponent iterate through the list in a loop and draw multiple lines. Regardless, super.paintComponent(g) should be the first call of your paintComponent method.


    Also if I add the super.paintComponent(g); in the clear method:
    Java Code:
    public void clear()
        {
        	super.paintComponent(g);
        }
    I get the NullPointerException....
    Yeah, that's a very bad idea; don't do it.

  7. #7
    Join Date
    Apr 2011
    Posts
    24
    Rep Power
    0

    Default

    It works and I even got the ColorBox to half work (changes color randomly), now I just have to add an eraser tool (no idea how too)

Similar Threads

  1. Problem with JButton
    By yontan8888 in forum AWT / Swing
    Replies: 2
    Last Post: 03-09-2011, 06:10 PM
  2. Jbutton problem
    By blue50 in forum AWT / Swing
    Replies: 10
    Last Post: 12-01-2010, 05:43 AM
  3. JButton click problem
    By mine0926 in forum NetBeans
    Replies: 7
    Last Post: 06-11-2010, 04:00 AM
  4. JButton Problem
    By wassim in forum AWT / Swing
    Replies: 6
    Last Post: 02-18-2009, 11:29 PM
  5. Problem with JButton
    By Marcus in forum AWT / Swing
    Replies: 1
    Last Post: 07-05-2007, 06:56 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
  •