Skip to content

Introducing Cinch and MVC

arigesher edited this page Dec 13, 2011 · 5 revisions

Disclaimer: Palantir Technologies is not affiliated with, endorsed or sponsored by Palantir.net, Inc. Palantir.net's website is http://palantir.net

Palantir Logo

Introduction

Cinch allows you to use dramatically less code to implement a Java GUI, and the code that exists is very maintainable. Let's do a quick comparision:

Program Lines of code Anonymous Listeners Description
IntroNoMVC.java 148 3 Has no model - values are stored in JComponents.
IntroLegacyMVC.java 270 6 Uses MVC as first described for Java. Model class requires two lines of boilerplate for every set method.
IntroCinchMVC.java 186 0 Uses very clean MVC. 71 lines of mostly auto-generated boilerplate for Model and Controller.

Believe it or not, this is a complete Swing program (note the lack of anonymous listener objects) - full source is available in IntroCinchMVC.java:

public class IntroCinchMVC {

    public static class IntroModel extends DefaultBindableModel {
        private String to = "";
        private String subject = "";
        private String body = "";
        
        public String getBody() {
            return body;
        }
        
        public void setBody(String body) {
            this.body = body;
            update();
        }
        
        public String getSubject() {
            return subject;
        }
        
        public void setSubject(String subject) {
            this.subject = subject;
            update();
        }
        
        public String getTo() {
            return to;
        }
        
        public void setTo(String to) {
            this.to = to;
            update();
        }
        
        public String getCurrentMessage() {
            if (Strings.isNullOrEmpty(to)) {
                return "Fill out 'To' field.";
            } 
            if (Strings.isNullOrEmpty(subject)) {
                return "Fill out 'Subject' field.";
            } 
            if (Strings.isNullOrEmpty(body)) {
                return "Fill out 'Body'.";
            } 
            return "Ready to send.";
        }
        
        public boolean isReady() {
            return !Strings.isNullOrEmpty(to) && !Strings.isNullOrEmpty(subject) && !Strings.isNullOrEmpty(body);
        }
        
        @Override
        public String toString() {
            return "IntroModel [to=" + to + ", subject=" + subject + ", body=" + body + "]";
        }
    }
    
    public static class IntroController {
        private final IntroModel model;
        
        public IntroController(IntroModel model) {
            this.model = model;
        }

        public void sendEmail() {
            System.out.println("Send: " + model);
        }
        
        public void yell() {
            model.setBody(model.getBody().toUpperCase());
        }
    }
    
    private final JPanel panel = new JPanel();

    private final Bindings bindings = new Bindings();
    
    private final IntroModel model = new IntroModel();
    
    @SuppressWarnings("unused")
    @Bindable
    private final IntroController controller = new IntroController(model);
    
    @Bound(to = "to")
    private final JTextField toField = new JTextField();
    
    @Bound(to = "subject")
    private final JTextField subjectField = new JTextField();
    
    @Bound(to = "body")
    private final JTextArea bodyArea = new JTextArea();
    
    @Action(call = "yell")
    private final JButton yellButton = new JButton("YELL!");
    
    @Action(call = "sendEmail")
    @EnabledIf(to = "ready")
    private final JButton sendButton = new JButton("Send");
    

    @Bound(to = "currentMessage")
    private final JLabel messageLabel = new JLabel("");
    
    public IntroCinchMVC() {
        initializeInterface();
        bindings.bind(this);
    }

    private void initializeInterface() {
        // swing layout code cut for brevity
        // ...
    }

    public JComponent getDisplayComponent() {
        return panel;
    }
    
    public static void main(String[] args) throws InterruptedException, InvocationTargetException {
        EventQueue.invokeAndWait(new Runnable() {
            public void run() {
                IntroCinchMVC example = new IntroCinchMVC();
                JFrame frame = Examples.getFrameFor("Cinch Email Example", example.panel);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Clone this wiki locally