Swing application to compute the area and perimeter of shapes











up vote
4
down vote

favorite












I am a beginner programmer. How would you refactor this code to abide by good coding practices? As it stands the program has 4 classes and its aim is to compute the area and perimeter of a specific shape by inputting its length from a JSlider. The MyFrame, MyShape, MyTriangle, MyCircle and MySquare. The initComponents() method is autogenerated by NetBeans autobuilder so I didn't include it below. Also the program is fully functionable as of now, just want to know how to better refactor the code, splitting it in different classes etc..



package mainpackage;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.swing.JFrame;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class MyFrame extends JFrame
{

MyShape myShape;
int value;

public MyFrame()
{

// Create frame, panels and items within
initComponents();
shapeSlider.setEnabled(false);

// Create instances of shapes when chosen in Menu
initShapes();

// Adds Changelistener to slider and updates dimensionOutputField
linkEventHandler();

exitButton2.addActionListener(new CloseListener());

}

private void initShapes()
{
ShapeHandler shapeHandler = new ShapeHandler();
squareMenuItem.addActionListener(shapeHandler);
circleMenuItem.addActionListener(shapeHandler);
triangleMenuItem.addActionListener(shapeHandler);

}

public class ShapeHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{

if(e.getSource() == squareMenuItem)
{

myShape = new MySquare();

} else if (e.getSource() == circleMenuItem)
{

myShape = new MyCircle();

} else if (e.getSource() == triangleMenuItem)
{

myShape = new MyTriangle();

}

shapeSlider.setEnabled(true);

}

}

public class MyChangeAction implements ChangeListener
{

public void stateChanged(ChangeEvent e)
{

int currentValue = shapeSlider.getValue() ;
dimensionOutputField.setText(String.valueOf(currentValue));

DecimalFormat numberFormat = new DecimalFormat("#.00");

double bLength = myShape.calculatePerimeter(currentValue);
String bLengthString = numberFormat.format(bLength);
bLengthOutputField.setText(bLengthString);

double bArea = myShape.calculateArea(currentValue);
String areaString = numberFormat.format(bArea);
areaOutputField1.setText(areaString);

}

}

private void linkEventHandler()
{

MyChangeAction sliderAction = new MyChangeAction() ;
shapeSlider.addChangeListener(sliderAction);

}

private class CloseListener implements ActionListener
{

@Override
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}

private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {

}

public static void main(String args)
{
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try
{
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
{
if ("Nimbus".equals(info.getName()))
{
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex)
{
java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex)
{
java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex)
{
java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex)
{
java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
//</editor-fold>

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run() {
new MyFrame().setVisible(true);
}
});
}

// Variables declaration - do not modify
private javax.swing.JPanel MyControlPanel;
private javax.swing.JLabel areaLabel1;
private javax.swing.JTextField areaOutputField1;
private javax.swing.JLabel bLengthLabel;
private javax.swing.JTextField bLengthOutputField;
private javax.swing.JMenuItem circleMenuItem;
private javax.swing.JLabel dimensionLabel;
private javax.swing.JTextField dimensionOutputField;
private javax.swing.JButton exitButton2;
private javax.swing.JPanel mainPanel2;
private javax.swing.JLabel mainTitle;
private javax.swing.JMenu shapeMenu;
private javax.swing.JMenuBar shapeMenuBar;
private javax.swing.JSlider shapeSlider;
private javax.swing.JMenuItem squareMenuItem;
private javax.swing.JMenuItem triangleMenuItem;
private org.jdesktop.beansbinding.BindingGroup bindingGroup;
// End of variables declaration
}









share|improve this question




























    up vote
    4
    down vote

    favorite












    I am a beginner programmer. How would you refactor this code to abide by good coding practices? As it stands the program has 4 classes and its aim is to compute the area and perimeter of a specific shape by inputting its length from a JSlider. The MyFrame, MyShape, MyTriangle, MyCircle and MySquare. The initComponents() method is autogenerated by NetBeans autobuilder so I didn't include it below. Also the program is fully functionable as of now, just want to know how to better refactor the code, splitting it in different classes etc..



    package mainpackage;


    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.DecimalFormat;
    import javax.swing.JFrame;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;

    public class MyFrame extends JFrame
    {

    MyShape myShape;
    int value;

    public MyFrame()
    {

    // Create frame, panels and items within
    initComponents();
    shapeSlider.setEnabled(false);

    // Create instances of shapes when chosen in Menu
    initShapes();

    // Adds Changelistener to slider and updates dimensionOutputField
    linkEventHandler();

    exitButton2.addActionListener(new CloseListener());

    }

    private void initShapes()
    {
    ShapeHandler shapeHandler = new ShapeHandler();
    squareMenuItem.addActionListener(shapeHandler);
    circleMenuItem.addActionListener(shapeHandler);
    triangleMenuItem.addActionListener(shapeHandler);

    }

    public class ShapeHandler implements ActionListener
    {
    public void actionPerformed(ActionEvent e)
    {

    if(e.getSource() == squareMenuItem)
    {

    myShape = new MySquare();

    } else if (e.getSource() == circleMenuItem)
    {

    myShape = new MyCircle();

    } else if (e.getSource() == triangleMenuItem)
    {

    myShape = new MyTriangle();

    }

    shapeSlider.setEnabled(true);

    }

    }

    public class MyChangeAction implements ChangeListener
    {

    public void stateChanged(ChangeEvent e)
    {

    int currentValue = shapeSlider.getValue() ;
    dimensionOutputField.setText(String.valueOf(currentValue));

    DecimalFormat numberFormat = new DecimalFormat("#.00");

    double bLength = myShape.calculatePerimeter(currentValue);
    String bLengthString = numberFormat.format(bLength);
    bLengthOutputField.setText(bLengthString);

    double bArea = myShape.calculateArea(currentValue);
    String areaString = numberFormat.format(bArea);
    areaOutputField1.setText(areaString);

    }

    }

    private void linkEventHandler()
    {

    MyChangeAction sliderAction = new MyChangeAction() ;
    shapeSlider.addChangeListener(sliderAction);

    }

    private class CloseListener implements ActionListener
    {

    @Override
    public void actionPerformed(ActionEvent e)
    {
    System.exit(0);
    }
    }

    private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {

    }

    public static void main(String args)
    {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
    * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
    */
    try
    {
    for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
    {
    if ("Nimbus".equals(info.getName()))
    {
    javax.swing.UIManager.setLookAndFeel(info.getClassName());
    break;
    }
    }
    } catch (ClassNotFoundException ex)
    {
    java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex)
    {
    java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex)
    {
    java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex)
    {
    java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable()
    {
    public void run() {
    new MyFrame().setVisible(true);
    }
    });
    }

    // Variables declaration - do not modify
    private javax.swing.JPanel MyControlPanel;
    private javax.swing.JLabel areaLabel1;
    private javax.swing.JTextField areaOutputField1;
    private javax.swing.JLabel bLengthLabel;
    private javax.swing.JTextField bLengthOutputField;
    private javax.swing.JMenuItem circleMenuItem;
    private javax.swing.JLabel dimensionLabel;
    private javax.swing.JTextField dimensionOutputField;
    private javax.swing.JButton exitButton2;
    private javax.swing.JPanel mainPanel2;
    private javax.swing.JLabel mainTitle;
    private javax.swing.JMenu shapeMenu;
    private javax.swing.JMenuBar shapeMenuBar;
    private javax.swing.JSlider shapeSlider;
    private javax.swing.JMenuItem squareMenuItem;
    private javax.swing.JMenuItem triangleMenuItem;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration
    }









    share|improve this question


























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I am a beginner programmer. How would you refactor this code to abide by good coding practices? As it stands the program has 4 classes and its aim is to compute the area and perimeter of a specific shape by inputting its length from a JSlider. The MyFrame, MyShape, MyTriangle, MyCircle and MySquare. The initComponents() method is autogenerated by NetBeans autobuilder so I didn't include it below. Also the program is fully functionable as of now, just want to know how to better refactor the code, splitting it in different classes etc..



      package mainpackage;


      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.text.DecimalFormat;
      import javax.swing.JFrame;
      import javax.swing.event.ChangeEvent;
      import javax.swing.event.ChangeListener;

      public class MyFrame extends JFrame
      {

      MyShape myShape;
      int value;

      public MyFrame()
      {

      // Create frame, panels and items within
      initComponents();
      shapeSlider.setEnabled(false);

      // Create instances of shapes when chosen in Menu
      initShapes();

      // Adds Changelistener to slider and updates dimensionOutputField
      linkEventHandler();

      exitButton2.addActionListener(new CloseListener());

      }

      private void initShapes()
      {
      ShapeHandler shapeHandler = new ShapeHandler();
      squareMenuItem.addActionListener(shapeHandler);
      circleMenuItem.addActionListener(shapeHandler);
      triangleMenuItem.addActionListener(shapeHandler);

      }

      public class ShapeHandler implements ActionListener
      {
      public void actionPerformed(ActionEvent e)
      {

      if(e.getSource() == squareMenuItem)
      {

      myShape = new MySquare();

      } else if (e.getSource() == circleMenuItem)
      {

      myShape = new MyCircle();

      } else if (e.getSource() == triangleMenuItem)
      {

      myShape = new MyTriangle();

      }

      shapeSlider.setEnabled(true);

      }

      }

      public class MyChangeAction implements ChangeListener
      {

      public void stateChanged(ChangeEvent e)
      {

      int currentValue = shapeSlider.getValue() ;
      dimensionOutputField.setText(String.valueOf(currentValue));

      DecimalFormat numberFormat = new DecimalFormat("#.00");

      double bLength = myShape.calculatePerimeter(currentValue);
      String bLengthString = numberFormat.format(bLength);
      bLengthOutputField.setText(bLengthString);

      double bArea = myShape.calculateArea(currentValue);
      String areaString = numberFormat.format(bArea);
      areaOutputField1.setText(areaString);

      }

      }

      private void linkEventHandler()
      {

      MyChangeAction sliderAction = new MyChangeAction() ;
      shapeSlider.addChangeListener(sliderAction);

      }

      private class CloseListener implements ActionListener
      {

      @Override
      public void actionPerformed(ActionEvent e)
      {
      System.exit(0);
      }
      }

      private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {

      }

      public static void main(String args)
      {
      /* Set the Nimbus look and feel */
      //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
      /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
      * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
      */
      try
      {
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
      {
      if ("Nimbus".equals(info.getName()))
      {
      javax.swing.UIManager.setLookAndFeel(info.getClassName());
      break;
      }
      }
      } catch (ClassNotFoundException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      } catch (InstantiationException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      } catch (IllegalAccessException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      } catch (javax.swing.UnsupportedLookAndFeelException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      }
      //</editor-fold>
      //</editor-fold>

      /* Create and display the form */
      java.awt.EventQueue.invokeLater(new Runnable()
      {
      public void run() {
      new MyFrame().setVisible(true);
      }
      });
      }

      // Variables declaration - do not modify
      private javax.swing.JPanel MyControlPanel;
      private javax.swing.JLabel areaLabel1;
      private javax.swing.JTextField areaOutputField1;
      private javax.swing.JLabel bLengthLabel;
      private javax.swing.JTextField bLengthOutputField;
      private javax.swing.JMenuItem circleMenuItem;
      private javax.swing.JLabel dimensionLabel;
      private javax.swing.JTextField dimensionOutputField;
      private javax.swing.JButton exitButton2;
      private javax.swing.JPanel mainPanel2;
      private javax.swing.JLabel mainTitle;
      private javax.swing.JMenu shapeMenu;
      private javax.swing.JMenuBar shapeMenuBar;
      private javax.swing.JSlider shapeSlider;
      private javax.swing.JMenuItem squareMenuItem;
      private javax.swing.JMenuItem triangleMenuItem;
      private org.jdesktop.beansbinding.BindingGroup bindingGroup;
      // End of variables declaration
      }









      share|improve this question















      I am a beginner programmer. How would you refactor this code to abide by good coding practices? As it stands the program has 4 classes and its aim is to compute the area and perimeter of a specific shape by inputting its length from a JSlider. The MyFrame, MyShape, MyTriangle, MyCircle and MySquare. The initComponents() method is autogenerated by NetBeans autobuilder so I didn't include it below. Also the program is fully functionable as of now, just want to know how to better refactor the code, splitting it in different classes etc..



      package mainpackage;


      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.text.DecimalFormat;
      import javax.swing.JFrame;
      import javax.swing.event.ChangeEvent;
      import javax.swing.event.ChangeListener;

      public class MyFrame extends JFrame
      {

      MyShape myShape;
      int value;

      public MyFrame()
      {

      // Create frame, panels and items within
      initComponents();
      shapeSlider.setEnabled(false);

      // Create instances of shapes when chosen in Menu
      initShapes();

      // Adds Changelistener to slider and updates dimensionOutputField
      linkEventHandler();

      exitButton2.addActionListener(new CloseListener());

      }

      private void initShapes()
      {
      ShapeHandler shapeHandler = new ShapeHandler();
      squareMenuItem.addActionListener(shapeHandler);
      circleMenuItem.addActionListener(shapeHandler);
      triangleMenuItem.addActionListener(shapeHandler);

      }

      public class ShapeHandler implements ActionListener
      {
      public void actionPerformed(ActionEvent e)
      {

      if(e.getSource() == squareMenuItem)
      {

      myShape = new MySquare();

      } else if (e.getSource() == circleMenuItem)
      {

      myShape = new MyCircle();

      } else if (e.getSource() == triangleMenuItem)
      {

      myShape = new MyTriangle();

      }

      shapeSlider.setEnabled(true);

      }

      }

      public class MyChangeAction implements ChangeListener
      {

      public void stateChanged(ChangeEvent e)
      {

      int currentValue = shapeSlider.getValue() ;
      dimensionOutputField.setText(String.valueOf(currentValue));

      DecimalFormat numberFormat = new DecimalFormat("#.00");

      double bLength = myShape.calculatePerimeter(currentValue);
      String bLengthString = numberFormat.format(bLength);
      bLengthOutputField.setText(bLengthString);

      double bArea = myShape.calculateArea(currentValue);
      String areaString = numberFormat.format(bArea);
      areaOutputField1.setText(areaString);

      }

      }

      private void linkEventHandler()
      {

      MyChangeAction sliderAction = new MyChangeAction() ;
      shapeSlider.addChangeListener(sliderAction);

      }

      private class CloseListener implements ActionListener
      {

      @Override
      public void actionPerformed(ActionEvent e)
      {
      System.exit(0);
      }
      }

      private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {

      }

      public static void main(String args)
      {
      /* Set the Nimbus look and feel */
      //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
      /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
      * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
      */
      try
      {
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
      {
      if ("Nimbus".equals(info.getName()))
      {
      javax.swing.UIManager.setLookAndFeel(info.getClassName());
      break;
      }
      }
      } catch (ClassNotFoundException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      } catch (InstantiationException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      } catch (IllegalAccessException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      } catch (javax.swing.UnsupportedLookAndFeelException ex)
      {
      java.util.logging.Logger.getLogger(MyFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
      }
      //</editor-fold>
      //</editor-fold>

      /* Create and display the form */
      java.awt.EventQueue.invokeLater(new Runnable()
      {
      public void run() {
      new MyFrame().setVisible(true);
      }
      });
      }

      // Variables declaration - do not modify
      private javax.swing.JPanel MyControlPanel;
      private javax.swing.JLabel areaLabel1;
      private javax.swing.JTextField areaOutputField1;
      private javax.swing.JLabel bLengthLabel;
      private javax.swing.JTextField bLengthOutputField;
      private javax.swing.JMenuItem circleMenuItem;
      private javax.swing.JLabel dimensionLabel;
      private javax.swing.JTextField dimensionOutputField;
      private javax.swing.JButton exitButton2;
      private javax.swing.JPanel mainPanel2;
      private javax.swing.JLabel mainTitle;
      private javax.swing.JMenu shapeMenu;
      private javax.swing.JMenuBar shapeMenuBar;
      private javax.swing.JSlider shapeSlider;
      private javax.swing.JMenuItem squareMenuItem;
      private javax.swing.JMenuItem triangleMenuItem;
      private org.jdesktop.beansbinding.BindingGroup bindingGroup;
      // End of variables declaration
      }






      java beginner object-oriented calculator swing






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 8 '17 at 6:38









      200_success

      127k15149412




      127k15149412










      asked Nov 7 '17 at 11:35









      Danielmt

      212




      212






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          2
          down vote













          For Java the Code style conventions are quite rigorous. I would adhere to the code style that is followed by 99% of the community. The firms you will be working for will determine the coding style.




          When Java was launched, C++/C generally had an indentation of 3. And the
          code had often a large number of nested { }.
          It was decided to opt for more Methods (academic style) and indent to 4 in order to support "good style." The alternative explanation is that 4 is the half of 8, the normal tab size.




          The NetBeans IDE's GUI builder let's set properties and code Fragments. You can use that to disable the slider, add Action listeners and such.



          Since Java 8 one can use lambas, representations of anonymous functions, that under the hood will become an interface implementation. This abbreviates the Code, introducing parameter names:



          component.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent evt) {
          myShape = new MyCircle();
          }
          });


          can be shortened to



          component.addActionListener(evt -> myShape = new MyCircle());


          If not, always use @Override on overriden Methods. Should the method have a typo, that would be reported with a compile error.



          The fields may be private.



              private MyShape myShape;
          private int value;

          public MyFrame() {

          // Create frame, panels and items within
          initComponents();
          shapeSlider.setEnabled(false);

          // Create instances of shapes when chosen in Menu
          initShapes();

          // Adds Changelistener to slider and updates dimensionOutputField
          shapeSlider.addChangeListener(new MyChangeAction());

          exitButton2.addActionListener(actionEvent -> MyFrame.this.dispose());
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }


          The ShapeHandler could not use if-else-if chains but be object-oriented:



              public class ShapeHandler implements ActionListener {
          private final Supplier<MyShape> shapeCreator;

          public ShapeHandler(Supplier<MyShape> shapeCreator) {
          this.shapeCreator = shapeCreator;
          }

          public void actionPerformed(ActionEvent e) {
          myShape = shapeCreator.get();
          shapeSlider.setEnabled(true);
          }
          }

          private void initShapes() {
          squareMenuItem.addActionListener(new ShapeHandler(MySquare::new));
          circleMenuItem.addActionListener(new ShapeHandler(MyCircle::new));
          triangleMenuItem.addActionListener(new ShapeHandler(MyTriangle::new));

          // Or:
          squareMenuItem.addActionListener(evt -> myShape = new MySquare());
          circleMenuItem.addActionListener(evt -> myShape = new MyCircle());
          triangleMenuItem.addActionListener(evt -> myShape = new MyTriangle());
          }


          But as you see, the class is not really needed. Though nice to not "repeat one self".



          I would use @Override and possible an other Name, as Action is a known interface in swing.



              public class MyChangeAction implements ChangeListener {
          @Override
          public void stateChanged(ChangeEvent e) {


          The generated main method is conservative: compilable for very old versions of Java < 7. Shorter would be:



          public static void main(String args) {
          try {
          for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
          if ("Nimbus".equals(info.getName())) {
          UIManager.setLookAndFeel(info.getClassName());
          break;
          }
          }
          } catch (ClassNotFoundException | InstantiationException
          | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          Logger.getLogger(MyFrame.class.getName()).log(Level.SEVERE,
          "Error setting theme", ex);
          }

          EventQueue.invokeLater(() -> new MyFrame().setVisible(true));
          }





          share|improve this answer



















          • 1




            This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
            – Marco13
            yesterday










          • @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
            – Joop Eggen
            21 hours ago


















          up vote
          1
          down vote













          Create CalculateCallback which is responsible for managing the action after the calculation is done. So perform any calculations there necessary once calculation is done.



             @FunctionalInterface
          public interface CalculateCallback {
          public void perform(double value);
          }


          AreaCalculator is responsible for doing calculations and performing the calculate call back. Once the slider changes the calculation should go through AreaCalculator.



          public class AreaCalculator {

          private CalculateCallback perimeterCalculatorCallback;
          private CalculateCallback areaCalculatorCallback;
          private MyShape myShape;

          public AreaCalculator(CalculateCallback perimeterCalculatorCallback, CalculateCallback areaCalculatorCallback) {
          this.perimeterCalculatorCallback = perimeterCalculatorCallback;
          this.areaCalculatorCallback = areaCalculatorCallback;
          }

          public void doCalculate(int currentValue) {
          if (null != myShape) {

          double bLength = myShape.calculatePerimeter(currentValue);
          perimeterCalculatorCallback.perform(bLength);

          double bArea = myShape.calculateArea(currentValue);
          areaCalculatorCallback.perform(bArea);
          }
          }

          public void setMyShape(MyShape myShape) {
          this.myShape = myShape;
          }
          }


          ShapeFactory is responsible to provide MyShape according to parameter. I didn't implement that. Please makes sure to implement this.



          public class ShapeFactory {

          public static MyShape getMyShape(String item) {

          //Here you have to return MyShape according to parameter.
          }
          }


          ShapeHandler is responsible for handling change. It will perform calculation through AreaCalculator by providing MyShape according to action.



          public class ShapeHandler implements ActionListener {

          private AreaCalculator areaCalculator;
          private ActionDoneCallback actionDoneCallback;

          public ShapeHandler(AreaCalculator areaCalculator, ActionDoneCallback doneCallback) {
          this.areaCalculator = areaCalculator;
          this.actionDoneCallback = doneCallback;
          }

          @Override
          public void actionPerformed(ActionEvent e) {
          MyShape shape = ShapeFactory.getMyShape(e.getActionCommand());
          areaCalculator.setMyShape(shape);
          actionDoneCallback.perform();
          }
          }


          Your MyFrame constructor should like below.



          Its responsible to create callback since its the owner of component and this need to modify according to requirement.



          public MyFrame() {

          // Create frame, panels and items within

          DecimalFormat numberFormat = new DecimalFormat("#.00");
          AreaCalculator areaCalculator = new AreaCalculator(
          (value) -> bLengthOutputField.setText(numberFormat.format(value)),
          (value -> areaOutputField1.setText(numberFormat.format(value))));

          ShapeHandler shapeHandler = new ShapeHandler(areaCalculator, () -> shapeSlider.setEnabled(true));
          squareMenuItem.addActionListener(shapeHandler);
          triangleMenuItem.addActionListener(shapeHandler);
          circleMenuItem.addActionListener(shapeHandler);

          shapeSlider.setEnabled(false);
          shapeSlider.addChangeListener(e -> areaCalculator.doCalculate(shapeSlider.getValue()));

          exitButton2.addActionListener(new CloseListener());

          }


          Once a shape is selected ShapeHandler will set MyShape in AreaCalculator.



          Once the Jslider is changed it will do the calculation base on the value.



          I design this under SOLID principles and base on TDD.
          so you can write unit test easy for this design.



          Let me to know if you need some clarification.






          share|improve this answer























          • Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
            – Danielmt
            Nov 9 '17 at 10:08










          • Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
            – Chamly Idunil
            Nov 10 '17 at 4:19











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f179810%2fswing-application-to-compute-the-area-and-perimeter-of-shapes%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote













          For Java the Code style conventions are quite rigorous. I would adhere to the code style that is followed by 99% of the community. The firms you will be working for will determine the coding style.




          When Java was launched, C++/C generally had an indentation of 3. And the
          code had often a large number of nested { }.
          It was decided to opt for more Methods (academic style) and indent to 4 in order to support "good style." The alternative explanation is that 4 is the half of 8, the normal tab size.




          The NetBeans IDE's GUI builder let's set properties and code Fragments. You can use that to disable the slider, add Action listeners and such.



          Since Java 8 one can use lambas, representations of anonymous functions, that under the hood will become an interface implementation. This abbreviates the Code, introducing parameter names:



          component.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent evt) {
          myShape = new MyCircle();
          }
          });


          can be shortened to



          component.addActionListener(evt -> myShape = new MyCircle());


          If not, always use @Override on overriden Methods. Should the method have a typo, that would be reported with a compile error.



          The fields may be private.



              private MyShape myShape;
          private int value;

          public MyFrame() {

          // Create frame, panels and items within
          initComponents();
          shapeSlider.setEnabled(false);

          // Create instances of shapes when chosen in Menu
          initShapes();

          // Adds Changelistener to slider and updates dimensionOutputField
          shapeSlider.addChangeListener(new MyChangeAction());

          exitButton2.addActionListener(actionEvent -> MyFrame.this.dispose());
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }


          The ShapeHandler could not use if-else-if chains but be object-oriented:



              public class ShapeHandler implements ActionListener {
          private final Supplier<MyShape> shapeCreator;

          public ShapeHandler(Supplier<MyShape> shapeCreator) {
          this.shapeCreator = shapeCreator;
          }

          public void actionPerformed(ActionEvent e) {
          myShape = shapeCreator.get();
          shapeSlider.setEnabled(true);
          }
          }

          private void initShapes() {
          squareMenuItem.addActionListener(new ShapeHandler(MySquare::new));
          circleMenuItem.addActionListener(new ShapeHandler(MyCircle::new));
          triangleMenuItem.addActionListener(new ShapeHandler(MyTriangle::new));

          // Or:
          squareMenuItem.addActionListener(evt -> myShape = new MySquare());
          circleMenuItem.addActionListener(evt -> myShape = new MyCircle());
          triangleMenuItem.addActionListener(evt -> myShape = new MyTriangle());
          }


          But as you see, the class is not really needed. Though nice to not "repeat one self".



          I would use @Override and possible an other Name, as Action is a known interface in swing.



              public class MyChangeAction implements ChangeListener {
          @Override
          public void stateChanged(ChangeEvent e) {


          The generated main method is conservative: compilable for very old versions of Java < 7. Shorter would be:



          public static void main(String args) {
          try {
          for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
          if ("Nimbus".equals(info.getName())) {
          UIManager.setLookAndFeel(info.getClassName());
          break;
          }
          }
          } catch (ClassNotFoundException | InstantiationException
          | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          Logger.getLogger(MyFrame.class.getName()).log(Level.SEVERE,
          "Error setting theme", ex);
          }

          EventQueue.invokeLater(() -> new MyFrame().setVisible(true));
          }





          share|improve this answer



















          • 1




            This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
            – Marco13
            yesterday










          • @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
            – Joop Eggen
            21 hours ago















          up vote
          2
          down vote













          For Java the Code style conventions are quite rigorous. I would adhere to the code style that is followed by 99% of the community. The firms you will be working for will determine the coding style.




          When Java was launched, C++/C generally had an indentation of 3. And the
          code had often a large number of nested { }.
          It was decided to opt for more Methods (academic style) and indent to 4 in order to support "good style." The alternative explanation is that 4 is the half of 8, the normal tab size.




          The NetBeans IDE's GUI builder let's set properties and code Fragments. You can use that to disable the slider, add Action listeners and such.



          Since Java 8 one can use lambas, representations of anonymous functions, that under the hood will become an interface implementation. This abbreviates the Code, introducing parameter names:



          component.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent evt) {
          myShape = new MyCircle();
          }
          });


          can be shortened to



          component.addActionListener(evt -> myShape = new MyCircle());


          If not, always use @Override on overriden Methods. Should the method have a typo, that would be reported with a compile error.



          The fields may be private.



              private MyShape myShape;
          private int value;

          public MyFrame() {

          // Create frame, panels and items within
          initComponents();
          shapeSlider.setEnabled(false);

          // Create instances of shapes when chosen in Menu
          initShapes();

          // Adds Changelistener to slider and updates dimensionOutputField
          shapeSlider.addChangeListener(new MyChangeAction());

          exitButton2.addActionListener(actionEvent -> MyFrame.this.dispose());
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }


          The ShapeHandler could not use if-else-if chains but be object-oriented:



              public class ShapeHandler implements ActionListener {
          private final Supplier<MyShape> shapeCreator;

          public ShapeHandler(Supplier<MyShape> shapeCreator) {
          this.shapeCreator = shapeCreator;
          }

          public void actionPerformed(ActionEvent e) {
          myShape = shapeCreator.get();
          shapeSlider.setEnabled(true);
          }
          }

          private void initShapes() {
          squareMenuItem.addActionListener(new ShapeHandler(MySquare::new));
          circleMenuItem.addActionListener(new ShapeHandler(MyCircle::new));
          triangleMenuItem.addActionListener(new ShapeHandler(MyTriangle::new));

          // Or:
          squareMenuItem.addActionListener(evt -> myShape = new MySquare());
          circleMenuItem.addActionListener(evt -> myShape = new MyCircle());
          triangleMenuItem.addActionListener(evt -> myShape = new MyTriangle());
          }


          But as you see, the class is not really needed. Though nice to not "repeat one self".



          I would use @Override and possible an other Name, as Action is a known interface in swing.



              public class MyChangeAction implements ChangeListener {
          @Override
          public void stateChanged(ChangeEvent e) {


          The generated main method is conservative: compilable for very old versions of Java < 7. Shorter would be:



          public static void main(String args) {
          try {
          for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
          if ("Nimbus".equals(info.getName())) {
          UIManager.setLookAndFeel(info.getClassName());
          break;
          }
          }
          } catch (ClassNotFoundException | InstantiationException
          | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          Logger.getLogger(MyFrame.class.getName()).log(Level.SEVERE,
          "Error setting theme", ex);
          }

          EventQueue.invokeLater(() -> new MyFrame().setVisible(true));
          }





          share|improve this answer



















          • 1




            This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
            – Marco13
            yesterday










          • @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
            – Joop Eggen
            21 hours ago













          up vote
          2
          down vote










          up vote
          2
          down vote









          For Java the Code style conventions are quite rigorous. I would adhere to the code style that is followed by 99% of the community. The firms you will be working for will determine the coding style.




          When Java was launched, C++/C generally had an indentation of 3. And the
          code had often a large number of nested { }.
          It was decided to opt for more Methods (academic style) and indent to 4 in order to support "good style." The alternative explanation is that 4 is the half of 8, the normal tab size.




          The NetBeans IDE's GUI builder let's set properties and code Fragments. You can use that to disable the slider, add Action listeners and such.



          Since Java 8 one can use lambas, representations of anonymous functions, that under the hood will become an interface implementation. This abbreviates the Code, introducing parameter names:



          component.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent evt) {
          myShape = new MyCircle();
          }
          });


          can be shortened to



          component.addActionListener(evt -> myShape = new MyCircle());


          If not, always use @Override on overriden Methods. Should the method have a typo, that would be reported with a compile error.



          The fields may be private.



              private MyShape myShape;
          private int value;

          public MyFrame() {

          // Create frame, panels and items within
          initComponents();
          shapeSlider.setEnabled(false);

          // Create instances of shapes when chosen in Menu
          initShapes();

          // Adds Changelistener to slider and updates dimensionOutputField
          shapeSlider.addChangeListener(new MyChangeAction());

          exitButton2.addActionListener(actionEvent -> MyFrame.this.dispose());
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }


          The ShapeHandler could not use if-else-if chains but be object-oriented:



              public class ShapeHandler implements ActionListener {
          private final Supplier<MyShape> shapeCreator;

          public ShapeHandler(Supplier<MyShape> shapeCreator) {
          this.shapeCreator = shapeCreator;
          }

          public void actionPerformed(ActionEvent e) {
          myShape = shapeCreator.get();
          shapeSlider.setEnabled(true);
          }
          }

          private void initShapes() {
          squareMenuItem.addActionListener(new ShapeHandler(MySquare::new));
          circleMenuItem.addActionListener(new ShapeHandler(MyCircle::new));
          triangleMenuItem.addActionListener(new ShapeHandler(MyTriangle::new));

          // Or:
          squareMenuItem.addActionListener(evt -> myShape = new MySquare());
          circleMenuItem.addActionListener(evt -> myShape = new MyCircle());
          triangleMenuItem.addActionListener(evt -> myShape = new MyTriangle());
          }


          But as you see, the class is not really needed. Though nice to not "repeat one self".



          I would use @Override and possible an other Name, as Action is a known interface in swing.



              public class MyChangeAction implements ChangeListener {
          @Override
          public void stateChanged(ChangeEvent e) {


          The generated main method is conservative: compilable for very old versions of Java < 7. Shorter would be:



          public static void main(String args) {
          try {
          for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
          if ("Nimbus".equals(info.getName())) {
          UIManager.setLookAndFeel(info.getClassName());
          break;
          }
          }
          } catch (ClassNotFoundException | InstantiationException
          | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          Logger.getLogger(MyFrame.class.getName()).log(Level.SEVERE,
          "Error setting theme", ex);
          }

          EventQueue.invokeLater(() -> new MyFrame().setVisible(true));
          }





          share|improve this answer














          For Java the Code style conventions are quite rigorous. I would adhere to the code style that is followed by 99% of the community. The firms you will be working for will determine the coding style.




          When Java was launched, C++/C generally had an indentation of 3. And the
          code had often a large number of nested { }.
          It was decided to opt for more Methods (academic style) and indent to 4 in order to support "good style." The alternative explanation is that 4 is the half of 8, the normal tab size.




          The NetBeans IDE's GUI builder let's set properties and code Fragments. You can use that to disable the slider, add Action listeners and such.



          Since Java 8 one can use lambas, representations of anonymous functions, that under the hood will become an interface implementation. This abbreviates the Code, introducing parameter names:



          component.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent evt) {
          myShape = new MyCircle();
          }
          });


          can be shortened to



          component.addActionListener(evt -> myShape = new MyCircle());


          If not, always use @Override on overriden Methods. Should the method have a typo, that would be reported with a compile error.



          The fields may be private.



              private MyShape myShape;
          private int value;

          public MyFrame() {

          // Create frame, panels and items within
          initComponents();
          shapeSlider.setEnabled(false);

          // Create instances of shapes when chosen in Menu
          initShapes();

          // Adds Changelistener to slider and updates dimensionOutputField
          shapeSlider.addChangeListener(new MyChangeAction());

          exitButton2.addActionListener(actionEvent -> MyFrame.this.dispose());
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }


          The ShapeHandler could not use if-else-if chains but be object-oriented:



              public class ShapeHandler implements ActionListener {
          private final Supplier<MyShape> shapeCreator;

          public ShapeHandler(Supplier<MyShape> shapeCreator) {
          this.shapeCreator = shapeCreator;
          }

          public void actionPerformed(ActionEvent e) {
          myShape = shapeCreator.get();
          shapeSlider.setEnabled(true);
          }
          }

          private void initShapes() {
          squareMenuItem.addActionListener(new ShapeHandler(MySquare::new));
          circleMenuItem.addActionListener(new ShapeHandler(MyCircle::new));
          triangleMenuItem.addActionListener(new ShapeHandler(MyTriangle::new));

          // Or:
          squareMenuItem.addActionListener(evt -> myShape = new MySquare());
          circleMenuItem.addActionListener(evt -> myShape = new MyCircle());
          triangleMenuItem.addActionListener(evt -> myShape = new MyTriangle());
          }


          But as you see, the class is not really needed. Though nice to not "repeat one self".



          I would use @Override and possible an other Name, as Action is a known interface in swing.



              public class MyChangeAction implements ChangeListener {
          @Override
          public void stateChanged(ChangeEvent e) {


          The generated main method is conservative: compilable for very old versions of Java < 7. Shorter would be:



          public static void main(String args) {
          try {
          for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
          if ("Nimbus".equals(info.getName())) {
          UIManager.setLookAndFeel(info.getClassName());
          break;
          }
          }
          } catch (ClassNotFoundException | InstantiationException
          | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          Logger.getLogger(MyFrame.class.getName()).log(Level.SEVERE,
          "Error setting theme", ex);
          }

          EventQueue.invokeLater(() -> new MyFrame().setVisible(true));
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited yesterday

























          answered yesterday









          Joop Eggen

          1,137713




          1,137713








          • 1




            This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
            – Marco13
            yesterday










          • @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
            – Joop Eggen
            21 hours ago














          • 1




            This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
            – Marco13
            yesterday










          • @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
            – Joop Eggen
            21 hours ago








          1




          1




          This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
          – Marco13
          yesterday




          This covers nearly everything that I could say, so just a comment and not an answer: Pulling the work of what e.g. a ChangeListener does into an own (private) method often leads to a cleaner structure, and allows using a addListener(this::somethingChanged) method reference as well. IMHO, listener methods should usually be as short as possible.
          – Marco13
          yesterday












          @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
          – Joop Eggen
          21 hours ago




          @Marco13 indeed the nicest solution. I wanted to express the OO-way of not having an if-else-if/switch, and to Show that one can immediately use lambdas. eliminating an internal class. Thus the nicest: a method, passing a method handle did not reach the answer. Thanks
          – Joop Eggen
          21 hours ago












          up vote
          1
          down vote













          Create CalculateCallback which is responsible for managing the action after the calculation is done. So perform any calculations there necessary once calculation is done.



             @FunctionalInterface
          public interface CalculateCallback {
          public void perform(double value);
          }


          AreaCalculator is responsible for doing calculations and performing the calculate call back. Once the slider changes the calculation should go through AreaCalculator.



          public class AreaCalculator {

          private CalculateCallback perimeterCalculatorCallback;
          private CalculateCallback areaCalculatorCallback;
          private MyShape myShape;

          public AreaCalculator(CalculateCallback perimeterCalculatorCallback, CalculateCallback areaCalculatorCallback) {
          this.perimeterCalculatorCallback = perimeterCalculatorCallback;
          this.areaCalculatorCallback = areaCalculatorCallback;
          }

          public void doCalculate(int currentValue) {
          if (null != myShape) {

          double bLength = myShape.calculatePerimeter(currentValue);
          perimeterCalculatorCallback.perform(bLength);

          double bArea = myShape.calculateArea(currentValue);
          areaCalculatorCallback.perform(bArea);
          }
          }

          public void setMyShape(MyShape myShape) {
          this.myShape = myShape;
          }
          }


          ShapeFactory is responsible to provide MyShape according to parameter. I didn't implement that. Please makes sure to implement this.



          public class ShapeFactory {

          public static MyShape getMyShape(String item) {

          //Here you have to return MyShape according to parameter.
          }
          }


          ShapeHandler is responsible for handling change. It will perform calculation through AreaCalculator by providing MyShape according to action.



          public class ShapeHandler implements ActionListener {

          private AreaCalculator areaCalculator;
          private ActionDoneCallback actionDoneCallback;

          public ShapeHandler(AreaCalculator areaCalculator, ActionDoneCallback doneCallback) {
          this.areaCalculator = areaCalculator;
          this.actionDoneCallback = doneCallback;
          }

          @Override
          public void actionPerformed(ActionEvent e) {
          MyShape shape = ShapeFactory.getMyShape(e.getActionCommand());
          areaCalculator.setMyShape(shape);
          actionDoneCallback.perform();
          }
          }


          Your MyFrame constructor should like below.



          Its responsible to create callback since its the owner of component and this need to modify according to requirement.



          public MyFrame() {

          // Create frame, panels and items within

          DecimalFormat numberFormat = new DecimalFormat("#.00");
          AreaCalculator areaCalculator = new AreaCalculator(
          (value) -> bLengthOutputField.setText(numberFormat.format(value)),
          (value -> areaOutputField1.setText(numberFormat.format(value))));

          ShapeHandler shapeHandler = new ShapeHandler(areaCalculator, () -> shapeSlider.setEnabled(true));
          squareMenuItem.addActionListener(shapeHandler);
          triangleMenuItem.addActionListener(shapeHandler);
          circleMenuItem.addActionListener(shapeHandler);

          shapeSlider.setEnabled(false);
          shapeSlider.addChangeListener(e -> areaCalculator.doCalculate(shapeSlider.getValue()));

          exitButton2.addActionListener(new CloseListener());

          }


          Once a shape is selected ShapeHandler will set MyShape in AreaCalculator.



          Once the Jslider is changed it will do the calculation base on the value.



          I design this under SOLID principles and base on TDD.
          so you can write unit test easy for this design.



          Let me to know if you need some clarification.






          share|improve this answer























          • Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
            – Danielmt
            Nov 9 '17 at 10:08










          • Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
            – Chamly Idunil
            Nov 10 '17 at 4:19















          up vote
          1
          down vote













          Create CalculateCallback which is responsible for managing the action after the calculation is done. So perform any calculations there necessary once calculation is done.



             @FunctionalInterface
          public interface CalculateCallback {
          public void perform(double value);
          }


          AreaCalculator is responsible for doing calculations and performing the calculate call back. Once the slider changes the calculation should go through AreaCalculator.



          public class AreaCalculator {

          private CalculateCallback perimeterCalculatorCallback;
          private CalculateCallback areaCalculatorCallback;
          private MyShape myShape;

          public AreaCalculator(CalculateCallback perimeterCalculatorCallback, CalculateCallback areaCalculatorCallback) {
          this.perimeterCalculatorCallback = perimeterCalculatorCallback;
          this.areaCalculatorCallback = areaCalculatorCallback;
          }

          public void doCalculate(int currentValue) {
          if (null != myShape) {

          double bLength = myShape.calculatePerimeter(currentValue);
          perimeterCalculatorCallback.perform(bLength);

          double bArea = myShape.calculateArea(currentValue);
          areaCalculatorCallback.perform(bArea);
          }
          }

          public void setMyShape(MyShape myShape) {
          this.myShape = myShape;
          }
          }


          ShapeFactory is responsible to provide MyShape according to parameter. I didn't implement that. Please makes sure to implement this.



          public class ShapeFactory {

          public static MyShape getMyShape(String item) {

          //Here you have to return MyShape according to parameter.
          }
          }


          ShapeHandler is responsible for handling change. It will perform calculation through AreaCalculator by providing MyShape according to action.



          public class ShapeHandler implements ActionListener {

          private AreaCalculator areaCalculator;
          private ActionDoneCallback actionDoneCallback;

          public ShapeHandler(AreaCalculator areaCalculator, ActionDoneCallback doneCallback) {
          this.areaCalculator = areaCalculator;
          this.actionDoneCallback = doneCallback;
          }

          @Override
          public void actionPerformed(ActionEvent e) {
          MyShape shape = ShapeFactory.getMyShape(e.getActionCommand());
          areaCalculator.setMyShape(shape);
          actionDoneCallback.perform();
          }
          }


          Your MyFrame constructor should like below.



          Its responsible to create callback since its the owner of component and this need to modify according to requirement.



          public MyFrame() {

          // Create frame, panels and items within

          DecimalFormat numberFormat = new DecimalFormat("#.00");
          AreaCalculator areaCalculator = new AreaCalculator(
          (value) -> bLengthOutputField.setText(numberFormat.format(value)),
          (value -> areaOutputField1.setText(numberFormat.format(value))));

          ShapeHandler shapeHandler = new ShapeHandler(areaCalculator, () -> shapeSlider.setEnabled(true));
          squareMenuItem.addActionListener(shapeHandler);
          triangleMenuItem.addActionListener(shapeHandler);
          circleMenuItem.addActionListener(shapeHandler);

          shapeSlider.setEnabled(false);
          shapeSlider.addChangeListener(e -> areaCalculator.doCalculate(shapeSlider.getValue()));

          exitButton2.addActionListener(new CloseListener());

          }


          Once a shape is selected ShapeHandler will set MyShape in AreaCalculator.



          Once the Jslider is changed it will do the calculation base on the value.



          I design this under SOLID principles and base on TDD.
          so you can write unit test easy for this design.



          Let me to know if you need some clarification.






          share|improve this answer























          • Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
            – Danielmt
            Nov 9 '17 at 10:08










          • Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
            – Chamly Idunil
            Nov 10 '17 at 4:19













          up vote
          1
          down vote










          up vote
          1
          down vote









          Create CalculateCallback which is responsible for managing the action after the calculation is done. So perform any calculations there necessary once calculation is done.



             @FunctionalInterface
          public interface CalculateCallback {
          public void perform(double value);
          }


          AreaCalculator is responsible for doing calculations and performing the calculate call back. Once the slider changes the calculation should go through AreaCalculator.



          public class AreaCalculator {

          private CalculateCallback perimeterCalculatorCallback;
          private CalculateCallback areaCalculatorCallback;
          private MyShape myShape;

          public AreaCalculator(CalculateCallback perimeterCalculatorCallback, CalculateCallback areaCalculatorCallback) {
          this.perimeterCalculatorCallback = perimeterCalculatorCallback;
          this.areaCalculatorCallback = areaCalculatorCallback;
          }

          public void doCalculate(int currentValue) {
          if (null != myShape) {

          double bLength = myShape.calculatePerimeter(currentValue);
          perimeterCalculatorCallback.perform(bLength);

          double bArea = myShape.calculateArea(currentValue);
          areaCalculatorCallback.perform(bArea);
          }
          }

          public void setMyShape(MyShape myShape) {
          this.myShape = myShape;
          }
          }


          ShapeFactory is responsible to provide MyShape according to parameter. I didn't implement that. Please makes sure to implement this.



          public class ShapeFactory {

          public static MyShape getMyShape(String item) {

          //Here you have to return MyShape according to parameter.
          }
          }


          ShapeHandler is responsible for handling change. It will perform calculation through AreaCalculator by providing MyShape according to action.



          public class ShapeHandler implements ActionListener {

          private AreaCalculator areaCalculator;
          private ActionDoneCallback actionDoneCallback;

          public ShapeHandler(AreaCalculator areaCalculator, ActionDoneCallback doneCallback) {
          this.areaCalculator = areaCalculator;
          this.actionDoneCallback = doneCallback;
          }

          @Override
          public void actionPerformed(ActionEvent e) {
          MyShape shape = ShapeFactory.getMyShape(e.getActionCommand());
          areaCalculator.setMyShape(shape);
          actionDoneCallback.perform();
          }
          }


          Your MyFrame constructor should like below.



          Its responsible to create callback since its the owner of component and this need to modify according to requirement.



          public MyFrame() {

          // Create frame, panels and items within

          DecimalFormat numberFormat = new DecimalFormat("#.00");
          AreaCalculator areaCalculator = new AreaCalculator(
          (value) -> bLengthOutputField.setText(numberFormat.format(value)),
          (value -> areaOutputField1.setText(numberFormat.format(value))));

          ShapeHandler shapeHandler = new ShapeHandler(areaCalculator, () -> shapeSlider.setEnabled(true));
          squareMenuItem.addActionListener(shapeHandler);
          triangleMenuItem.addActionListener(shapeHandler);
          circleMenuItem.addActionListener(shapeHandler);

          shapeSlider.setEnabled(false);
          shapeSlider.addChangeListener(e -> areaCalculator.doCalculate(shapeSlider.getValue()));

          exitButton2.addActionListener(new CloseListener());

          }


          Once a shape is selected ShapeHandler will set MyShape in AreaCalculator.



          Once the Jslider is changed it will do the calculation base on the value.



          I design this under SOLID principles and base on TDD.
          so you can write unit test easy for this design.



          Let me to know if you need some clarification.






          share|improve this answer














          Create CalculateCallback which is responsible for managing the action after the calculation is done. So perform any calculations there necessary once calculation is done.



             @FunctionalInterface
          public interface CalculateCallback {
          public void perform(double value);
          }


          AreaCalculator is responsible for doing calculations and performing the calculate call back. Once the slider changes the calculation should go through AreaCalculator.



          public class AreaCalculator {

          private CalculateCallback perimeterCalculatorCallback;
          private CalculateCallback areaCalculatorCallback;
          private MyShape myShape;

          public AreaCalculator(CalculateCallback perimeterCalculatorCallback, CalculateCallback areaCalculatorCallback) {
          this.perimeterCalculatorCallback = perimeterCalculatorCallback;
          this.areaCalculatorCallback = areaCalculatorCallback;
          }

          public void doCalculate(int currentValue) {
          if (null != myShape) {

          double bLength = myShape.calculatePerimeter(currentValue);
          perimeterCalculatorCallback.perform(bLength);

          double bArea = myShape.calculateArea(currentValue);
          areaCalculatorCallback.perform(bArea);
          }
          }

          public void setMyShape(MyShape myShape) {
          this.myShape = myShape;
          }
          }


          ShapeFactory is responsible to provide MyShape according to parameter. I didn't implement that. Please makes sure to implement this.



          public class ShapeFactory {

          public static MyShape getMyShape(String item) {

          //Here you have to return MyShape according to parameter.
          }
          }


          ShapeHandler is responsible for handling change. It will perform calculation through AreaCalculator by providing MyShape according to action.



          public class ShapeHandler implements ActionListener {

          private AreaCalculator areaCalculator;
          private ActionDoneCallback actionDoneCallback;

          public ShapeHandler(AreaCalculator areaCalculator, ActionDoneCallback doneCallback) {
          this.areaCalculator = areaCalculator;
          this.actionDoneCallback = doneCallback;
          }

          @Override
          public void actionPerformed(ActionEvent e) {
          MyShape shape = ShapeFactory.getMyShape(e.getActionCommand());
          areaCalculator.setMyShape(shape);
          actionDoneCallback.perform();
          }
          }


          Your MyFrame constructor should like below.



          Its responsible to create callback since its the owner of component and this need to modify according to requirement.



          public MyFrame() {

          // Create frame, panels and items within

          DecimalFormat numberFormat = new DecimalFormat("#.00");
          AreaCalculator areaCalculator = new AreaCalculator(
          (value) -> bLengthOutputField.setText(numberFormat.format(value)),
          (value -> areaOutputField1.setText(numberFormat.format(value))));

          ShapeHandler shapeHandler = new ShapeHandler(areaCalculator, () -> shapeSlider.setEnabled(true));
          squareMenuItem.addActionListener(shapeHandler);
          triangleMenuItem.addActionListener(shapeHandler);
          circleMenuItem.addActionListener(shapeHandler);

          shapeSlider.setEnabled(false);
          shapeSlider.addChangeListener(e -> areaCalculator.doCalculate(shapeSlider.getValue()));

          exitButton2.addActionListener(new CloseListener());

          }


          Once a shape is selected ShapeHandler will set MyShape in AreaCalculator.



          Once the Jslider is changed it will do the calculation base on the value.



          I design this under SOLID principles and base on TDD.
          so you can write unit test easy for this design.



          Let me to know if you need some clarification.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 8 '17 at 5:25

























          answered Nov 8 '17 at 4:48









          Chamly Idunil

          1114




          1114












          • Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
            – Danielmt
            Nov 9 '17 at 10:08










          • Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
            – Chamly Idunil
            Nov 10 '17 at 4:19


















          • Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
            – Danielmt
            Nov 9 '17 at 10:08










          • Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
            – Chamly Idunil
            Nov 10 '17 at 4:19
















          Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
          – Danielmt
          Nov 9 '17 at 10:08




          Thank you so much for your time. What are the ActionDoneCallBack class and the CalculateCallBack class please? I have never used these classes before.
          – Danielmt
          Nov 9 '17 at 10:08












          Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
          – Chamly Idunil
          Nov 10 '17 at 4:19




          Update the text field is responsible by MyFrame after the calculation. Calculation responsible by AreaCalculator. What I have done is separate responsible. (Please read about SOLID principle) The process after calculation, provided by outside. so if we want to use this calculator in another frame you can just provide callback implementation.
          – Chamly Idunil
          Nov 10 '17 at 4:19


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f179810%2fswing-application-to-compute-the-area-and-perimeter-of-shapes%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Quarter-circle Tiles

          build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

          Mont Emei