Results 1 to 5 of 5
  1. #1
    Join Date
    Aug 2014
    Location
    South Africa
    Posts
    19
    Rep Power
    0

    Default MVC and Java Swing

    I am rather confused. After extensive research. I am now lead to believe that there are several views (no pun intended) on how MVC should be implemented with regards to Swing.

    The main difference between the various "implementations" is the role of the controller, in some the Controller is responsible for implementing the ActionListeners, well others implement the ActionListener as inner class within the view..

    As of this moment I am using the former approach. I am still a bit unsure whether this is the correct approach.

    If it is, I also would appreciate advice on the following:

    I am busy building the interface for a Lambda calculus calculator. As you may well be aware of lambda calculus can reduced in normal or applicative order .

    I currently using Radio buttons to allow select the order. However inline with MVC, I want allow for the possible of alternative component to be used for selection

  2. #2
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,991
    Rep Power
    8

    Default Re: MVC and Java Swing

    You can (and probably should) use an intermediate interface, so the controller has no clue what components the view has. I cooked up an example of what I think demonstrates this. As you can see, the OrderSelector is an interface with one method (you can do fun stuff with this with Java 8 as well). This method hides the implementation of the radiobutton and can be called by any component, as long as the View has a reference to the OrderSelector.

    I used one ActionListener for all the radios and used the ClientProperty map to get what I want, but you can use three different ActionListeners, each with a different implementation. When you run this, the Controller wil show a message of what order is selected, without ActionListeners in the Controller. Also, I used an anonymous inner class in v.setOrderSelector(...), but you can also implement the interface on your Controller, so you have the method at class level. It's just preference, I think.

    Java Code:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    enum Order {
        ORDER_ONE, ORDER_TWO, ORDER_THREE
    }
    
    interface OrderSelector {
        public void orderSelected(Order order);
    }
    
    class Controller {
    
        public void go() {
            Model m = new Model();
            View v = new View(m);
            v.setOrderSelector(new OrderSelector() {
                @Override
                public void orderSelected(Order order) {
                    JOptionPane.showMessageDialog(null, "Order selected: " + order.name());
                }
            });
            v.setVisible(true);
        }
    
    }
    
    class View extends JFrame {
        OrderSelector orderSelector;
        Model model;
    
        View(Model m) {
            this.model = m;
    
            setLocationRelativeTo(null);
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            JPanel buttons = new JPanel(new GridLayout(3, 1));
    
            JRadioButton b1 = new JRadioButton("Type 1");
            b1.putClientProperty("ORDER", Order.ORDER_ONE);
            JRadioButton b2 = new JRadioButton("Type 2");
            b2.putClientProperty("ORDER", Order.ORDER_TWO);
            JRadioButton b3 = new JRadioButton("Type 3");
            b3.putClientProperty("ORDER", Order.ORDER_THREE);
    
            ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Order order = (Order) ((JRadioButton) e.getSource()).getClientProperty("ORDER");
                    orderSelector.orderSelected(order);
                }
            };
    
            b1.addActionListener(al);
            b2.addActionListener(al);
            b3.addActionListener(al);
    
            ButtonGroup bg = new ButtonGroup();
            bg.add(b1);
            bg.add(b2);
            bg.add(b3);
    
    
            buttons.add(b1);
            buttons.add(b2);
            buttons.add(b3);
    
            add(buttons);
            pack();
    
        }
    
        void setOrderSelector(OrderSelector orderSelector) {
            this.orderSelector = orderSelector;
        }
    }
    
    class Model {
    
    }
    
    public class MVC {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    Controller c = new Controller();
                    c.go();
                }
            });
        }
    }
    Last edited by SurfMan; 09-06-2014 at 12:37 PM.
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  3. #3
    Join Date
    Aug 2014
    Location
    South Africa
    Posts
    19
    Rep Power
    0

    Default Re: MVC and Java Swing

    Quote Originally Posted by SurfMan View Post
    You can (and probably should) use an intermediate interface, so the controller has no clue what components the view has. I cooked up an example of what I think demonstrates this. As you can see, the OrderSelector is an interface with one method (you can do fun stuff with this with Java 8 as well). This method hides the implementation of the radiobutton and can be called by any component, as long as the View has a reference to the OrderSelector.

    I used one ActionListener for all the radios and used the ClientProperty map to get what I want, but you can use three different ActionListeners, each with a different implementation. When you run this, the Controller wil show a message of what order is selected, without ActionListeners in the Controller. Also, I used an anonymous inner class in v.setOrderSelector(...), but you can also implement the interface on your Controller, so you have the method at class level. It's just preference, I think.

    Java Code:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    enum Order {
        ORDER_ONE, ORDER_TWO, ORDER_THREE
    }
    
    interface OrderSelector {
        public void orderSelected(Order order);
    }
    
    class Controller {
    
        public void go() {
            Model m = new Model();
            View v = new View(m);
            v.setOrderSelector(new OrderSelector() {
                @Override
                public void orderSelected(Order order) {
                    JOptionPane.showMessageDialog(null, "Order selected: " + order.name());
                }
            });
            v.setVisible(true);
        }
    
    }
    
    class View extends JFrame {
        OrderSelector orderSelector;
        Model model;
    
        View(Model m) {
            this.model = m;
    
            setLocationRelativeTo(null);
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            JPanel buttons = new JPanel(new GridLayout(3, 1));
    
            JRadioButton b1 = new JRadioButton("Type 1");
            b1.putClientProperty("ORDER", Order.ORDER_ONE);
            JRadioButton b2 = new JRadioButton("Type 2");
            b2.putClientProperty("ORDER", Order.ORDER_TWO);
            JRadioButton b3 = new JRadioButton("Type 3");
            b3.putClientProperty("ORDER", Order.ORDER_THREE);
    
            ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Order order = (Order) ((JRadioButton) e.getSource()).getClientProperty("ORDER");
                    orderSelector.orderSelected(order);
                }
            };
    
            b1.addActionListener(al);
            b2.addActionListener(al);
            b3.addActionListener(al);
    
            ButtonGroup bg = new ButtonGroup();
            bg.add(b1);
            bg.add(b2);
            bg.add(b3);
    
    
            buttons.add(b1);
            buttons.add(b2);
            buttons.add(b3);
    
            add(buttons);
            pack();
    
        }
    
        void setOrderSelector(OrderSelector orderSelector) {
            this.orderSelector = orderSelector;
        }
    }
    
    class Model {
    
    }
    
    public class MVC {
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    Controller c = new Controller();
                    c.go();
                }
            });
        }
    }
    What exactly does ClientProperty do?

  4. #4
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,991
    Rep Power
    8

    Default Re: MVC and Java Swing

    Quote Originally Posted by Matthew John Dunk View Post
    What exactly does ClientProperty do?
    Adds an arbitrary key/value "client property" to this component.

    The get/putClientProperty methods provide access to a small per-instance hashtable. Callers can use get/putClientProperty to annotate components that were created by another module. For example, a layout manager might store per child constraints this way.

    An alternative way may be:
    Java Code:
     ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (e.getSource() == b1) {
                        orderSelector.orderSelected(Order.ORDER_ONE);
                    }
                    else if (e.getSource() == b2) {
                        orderSelector.orderSelected(Order.ORDER_TWO);
                    }
                    else if (e.getSource() == b3) {
                        orderSelector.orderSelected(Order.ORDER_THREE);
                    }
    
                }
            };
    
            b1.addActionListener(al);
            b2.addActionListener(al);
            b3.addActionListener(al);
    Or:
    Java Code:
            b1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    orderSelector.orderSelected(Order.ORDER_ONE);
                }
            });
            b2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    orderSelector.orderSelected(Order.ORDER_TWO);
                }
            });
            b3.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    orderSelector.orderSelected(Order.ORDER_THREE);
                }
            });

    All depends on your preferences.
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  5. #5
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,991
    Rep Power
    8

    Default Re: MVC and Java Swing

    Besides the clientProperty thing, what do you think of the possible answer for your question? Have you tried a construction like this before?
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

Similar Threads

  1. Java Swing application + Database on server (Java EE?)
    By twist900 in forum Advanced Java
    Replies: 5
    Last Post: 12-20-2013, 02:04 PM
  2. Java swing - help with GUI
    By adjit in forum New To Java
    Replies: 6
    Last Post: 03-16-2012, 11:21 PM
  3. Is this right!! Java Swing
    By Nifras in forum AWT / Swing
    Replies: 4
    Last Post: 05-28-2010, 07:20 PM
  4. [swing] Java and sql
    By ezee in forum AWT / Swing
    Replies: 1
    Last Post: 03-27-2009, 05:55 PM
  5. Java Swing
    By RAMYA in forum New To Java
    Replies: 3
    Last Post: 11-12-2008, 07:00 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
  •