0

So basically I have a main (DrawDriver) where I create 2 objects at the top.

 public class DrawDriver {

  public static void main(String[] args) {

    final GraphicPanel pannel1 = new GraphicPanel();        
   final Frame2UserInput pannel2 = new Frame2UserInput();

    TitledBorder border = new TitledBorder("Input");
    border.setTitleColor(Color.BLACK);      
   pannel2.setBorder(border);

    JFrame frame = new JFrame("DrawGoGo!");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(500, 500));
   frame.setLayout(new GridLayout(2, 0)); 
    frame.pack();       
   frame.setVisible(true);      
   frame.setResizable(false);

            // Creating the MENU BAR

            JMenuBar menubar = new JMenuBar(); 
           frame.setJMenuBar(menubar); 
            JMenu file = new JMenu("File"); 
        menubar.add(file); 
        JMenuItem New = new
           JMenuItem("New"); // Creates the jmenu item      
           file.add(New); // adds
           JMenuItem Load = new JMenuItem("Load");
            file.add(Load);         
           JMenuItem Save = new JMenuItem("Save");
            file.add(Save);         
           JMenuItem Exit = new JMenuItem("Exit");
            file.add(Exit);
            JMenu help = new JMenu("Help");     
            menubar.add(help);      

           JMenuItem about = new JMenuItem("About");        
           help.add(about);

            frame.getContentPane().add(pannel1);        
           frame.getContentPane().add(pannel2);



 }

In Frame2UserInput I want to access the GraphicPanel instance through the DrawDriver (main) class. This will be a canvas where I can type commands in & click the button & then the canvas will draw accordingly. You can see I've attempted to access it already in my ActionListener but can't because it makes a new instance of the class & not changes anything in the program (gui) I run.

So how would I access the object I created for GraphicPanel in the main but through a different class ? Any help would be appreciated thank you!

    public class Frame2UserInput extends JPanel {

    private static JTextArea input;     
       private static JButton draw;

        Frame2UserInput() {

                   input = new JTextArea(2,35);         
                  add(input);
                   draw = new JButton("Draw!");         
                  draw.addActionListener(new DrawListener());       
                  add(draw);    
   }        

   private static class DrawListener implements ActionListener {

            private String userInput;
            GraphicPanel pannel1 = new GraphicPanel();

            public void actionPerformed(ActionEvent event)  {


           if (event.getSource()==draw) {

            userInput = input.getText();
            System.out.println(userInput);

            if (userInput.equalsIgnoreCase("penup")) {

            }

            if (userInput.equalsIgnoreCase("pendown")) {

            }

            if (userInput.equalsIgnoreCase("turnleft")) {

            }

            if (userInput.equalsIgnoreCase("turnright")) {

            }
            if (userInput.equalsIgnoreCase("black")) {

            }

            if (userInput.equalsIgnoreCase("green")) {

            }

            if (userInput.equalsIgnoreCase("red")) {
                pannel1.drawLine(Color.RED,0,0,100,100);
            }

            if (userInput.equalsIgnoreCase("reset")) {
                pannel1.clear();
            }

                        }
                }   }    }
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1. Swing isn't thread safe, all of this code needs to be executed on the EDT. 2. Normally you'd supply a reference of the class you want to call methods on, try adding a parameter of the class to the ctor of `Frame2UserInput`. – markspace Mar 22 '16 at 01:13
  • This kind of stuff is OOP 101 that should be sorted out long before attempting GUIs. – Andrew Thompson Mar 22 '16 at 01:14
  • @WreckTangle You can use Observer pattern. For example: [updating change to another class](http://stackoverflow.com/questions/35876982/updating-change-to-another-class/35877451#35877451) – user3437460 Mar 22 '16 at 07:12

4 Answers4

2

Take it as a parameter.

final GraphicPanel pannel1 = new GraphicPanel();        
final Frame2UserInput pannel2 = new Frame2UserInput(pannel1 );

New Frame2UserInput constructor:

Frame2UserInput(GraphicPanel pannel1) {
   .
   .
   draw.addActionListener(new DrawListener(pannel1));    
}

And new DrawListener constructor

DrawListener(GraphicPanel pannel1) {
    .
    .
    //Don't need this just use pannel1 
    //GraphicPanel pannel1 = new GraphicPanel();
}
rdonuk
  • 3,921
  • 21
  • 39
  • 1
    While this works (and conceptually I don't have an issue), it does expose `GraphicPanel` to unwanted change (what stops `Frame2UserInput` from adding/removing content or changing other properties) as well as tightly couples the code. These are just things that the OP needs to know when balancing their choices ;) – MadProgrammer Mar 22 '16 at 01:22
  • Agree, this is not the best design. I prefer Observer pattern as you mentioned in your answer. Here I just find a workaround with minimum change. – rdonuk Mar 22 '16 at 01:30
2

Basically, you want to start by setting an Observer Pattern, where DrawDriver listens to events from Frame2UserInput and makes changes to the instance of GraphicPanel.

This is also a conceptual example of the Model-View-Controller paragdigm.

The idea here is, neither GraphicPanel or Frame2UserInput have any idea of each other (and shouldn't really know about DrawDriver either). DrawDriver is the bridge between the two, passing information between them as needed.

This will decouple your code and make it easier to modify and expand in the future, as changing one part shouldn't change how the other parts work. To this end, you should make heavy use of interfaces to define the core contractual logic between these classes.

Also, don't rely on static, it's not helping you and you should learn to work without it

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

The dot operator

object.objectMethod();

the method must be public, or protected if there is a level of inheritance & polymorphism going on

For your case, few pointers:

  • firstly your spelling of panel is wrong.
  • MEANINGFUL NAMES for your variable names is so very important

panel1 or panel2 are awful names for variables.

Next, you'd need to have an object in DrawDriver class to call an objects method from

mewc
  • 1,253
  • 1
  • 15
  • 24
1

You can

  1. make it as a parameter of your class
  2. make it as a static class member(Not recommend). But it save your time in some degree if you operate on the same canvas.
Adam Lyu
  • 431
  • 1
  • 5
  • 17