Przeglądaj źródła

Added first shot with gui validation. Note: need improvement...

jorgen_falk 18 lat temu
rodzic
commit
ac9066c324

+ 32
- 39
register-app/pom.xml Wyświetl plik

@@ -1,32 +1,12 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<project xmlns="http://maven.apache.org/POM/4.0.0"
3
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
1
+<?xml version="1.0" encoding="UTF-8"?><project>
5 2
   <modelVersion>4.0.0</modelVersion>
6 3
   <groupId>se.citerus</groupId>
7 4
   <artifactId>register-app</artifactId>
8
-  <packaging>jar</packaging>
9 5
   <name>register-app</name>
10 6
   <version>1.0-SNAPSHOT</version>
11 7
   <url>http://maven.apache.org</url>
12
-  <repositories>
13
-    <repository>
14
-      <id>maven2-repository.dev.java.net</id>
15
-      <name>Java.net Repository for Maven</name>
16
-      <url>http://download.java.net/maven/2/</url>
17
-      <layout>default</layout>
18
-    </repository>
19
-  </repositories>
20
-  <pluginRepositories>
21
-    <pluginRepository>
22
-      <id>maven2-repository.dev.java.net</id>
23
-      <name>Java.net Repository for Maven</name>
24
-      <url>http://download.java.net/maven/2/</url>
25
-    </pluginRepository>
26
-  </pluginRepositories>
27 8
   <build>
28 9
     <plugins>
29
-      <!-- Compiler -->
30 10
       <plugin>
31 11
         <artifactId>maven-compiler-plugin</artifactId>
32 12
         <configuration>
@@ -36,7 +16,6 @@
36 16
         </configuration>
37 17
       </plugin>
38 18
       <plugin>
39
-        <groupId>org.apache.maven.plugins</groupId>
40 19
         <artifactId>maven-jar-plugin</artifactId>
41 20
         <configuration>
42 21
           <archive>
@@ -61,6 +40,20 @@
61 40
       </plugin>
62 41
     </plugins>
63 42
   </build>
43
+  <repositories>
44
+    <repository>
45
+      <id>maven2-repository.dev.java.net</id>
46
+      <name>Java.net Repository for Maven</name>
47
+      <url>http://download.java.net/maven/2/</url>
48
+    </repository>
49
+  </repositories>
50
+  <pluginRepositories>
51
+    <pluginRepository>
52
+      <id>maven2-repository.dev.java.net</id>
53
+      <name>Java.net Repository for Maven</name>
54
+      <url>http://download.java.net/maven/2/</url>
55
+    </pluginRepository>
56
+  </pluginRepositories>
64 57
   <dependencies>
65 58
     <dependency>
66 59
       <groupId>junit</groupId>
@@ -95,72 +88,72 @@
95 88
       <classifier>ws-client</classifier>
96 89
       <exclusions>
97 90
         <exclusion>
98
-          <groupId>org.springframework</groupId>
99 91
           <artifactId>spring-core</artifactId>
92
+          <groupId>org.springframework</groupId>
100 93
         </exclusion>
101 94
         <exclusion>
102
-          <groupId>org.springframework</groupId>
103 95
           <artifactId>spring-webmvc</artifactId>
96
+          <groupId>org.springframework</groupId>
104 97
         </exclusion>
105 98
         <exclusion>
106
-          <groupId>org.springframework</groupId>
107 99
           <artifactId>spring-hibernate3</artifactId>
100
+          <groupId>org.springframework</groupId>
108 101
         </exclusion>
109 102
         <exclusion>
110
-          <groupId>org.springframework</groupId>
111 103
           <artifactId>spring-jdbc</artifactId>
104
+          <groupId>org.springframework</groupId>
112 105
         </exclusion>
113 106
         <exclusion>
114
-          <groupId>org.springframework</groupId>
115 107
           <artifactId>spring-aop</artifactId>
108
+          <groupId>org.springframework</groupId>
116 109
         </exclusion>
117 110
         <exclusion>
118
-          <groupId>org.springframework</groupId>
119 111
           <artifactId>spring-mock</artifactId>
112
+          <groupId>org.springframework</groupId>
120 113
         </exclusion>
121 114
         <exclusion>
122
-          <groupId>org.springframework</groupId>
123 115
           <artifactId>spring-context</artifactId>
116
+          <groupId>org.springframework</groupId>
124 117
         </exclusion>
125 118
         <exclusion>
126
-          <groupId>org.springframework</groupId>
127 119
           <artifactId>spring-beans</artifactId>
120
+          <groupId>org.springframework</groupId>
128 121
         </exclusion>
129 122
         <exclusion>
130
-          <groupId>org.hibernate</groupId>
131 123
           <artifactId>hibernate</artifactId>
124
+          <groupId>org.hibernate</groupId>
132 125
         </exclusion>
133 126
         <exclusion>
134
-          <groupId>org.hibernate</groupId>
135 127
           <artifactId>hibernate-annotations</artifactId>
128
+          <groupId>org.hibernate</groupId>
136 129
         </exclusion>
137 130
         <exclusion>
138
-          <groupId>org.hibernate</groupId>
139 131
           <artifactId>hibernate-commons-annotations</artifactId>
132
+          <groupId>org.hibernate</groupId>
140 133
         </exclusion>
141 134
         <exclusion>
142
-          <groupId>commons-dbcp</groupId>
143 135
           <artifactId>commons-dbcp</artifactId>
136
+          <groupId>commons-dbcp</groupId>
144 137
         </exclusion>
145 138
         <exclusion>
146
-          <groupId>hsqldb</groupId>
147 139
           <artifactId>hsqldb</artifactId>
140
+          <groupId>hsqldb</groupId>
148 141
         </exclusion>
149 142
         <exclusion>
150
-          <groupId>javax.servlet</groupId>
151 143
           <artifactId>servlet-api</artifactId>
144
+          <groupId>javax.servlet</groupId>
152 145
         </exclusion>
153 146
         <exclusion>
154
-          <groupId>taglibs</groupId>
155 147
           <artifactId>standard</artifactId>
148
+          <groupId>taglibs</groupId>
156 149
         </exclusion>
157 150
         <exclusion>
158
-          <groupId>javax.servlet</groupId>
159 151
           <artifactId>jstl</artifactId>
152
+          <groupId>javax.servlet</groupId>
160 153
         </exclusion>
161 154
         <exclusion>
162
-          <groupId>opensymphony</groupId>
163 155
           <artifactId>sitemesh</artifactId>
156
+          <groupId>opensymphony</groupId>
164 157
         </exclusion>
165 158
       </exclusions>
166 159
     </dependency>

+ 56
- 9
register-app/src/main/java/se/citerus/registerapp/RegisterApp.java Wyświetl plik

@@ -1,5 +1,8 @@
1 1
 package se.citerus.registerapp;
2 2
 
3
+import java.awt.Color;
4
+import java.awt.Component;
5
+import java.awt.Dimension;
3 6
 import java.awt.event.ActionEvent;
4 7
 import java.awt.event.ActionListener;
5 8
 import java.text.SimpleDateFormat;
@@ -11,12 +14,20 @@ import javax.swing.JFormattedTextField;
11 14
 import javax.swing.JFrame;
12 15
 import javax.swing.UIManager;
13 16
 import javax.swing.WindowConstants;
17
+import javax.swing.border.Border;
18
+import javax.swing.border.CompoundBorder;
19
+import javax.swing.border.LineBorder;
20
+import javax.swing.plaf.basic.BasicBorders;
14 21
 import javax.swing.text.DefaultFormatter;
15 22
 
16 23
 import se.citerus.registerapp.service.HandlingEventService;
24
+import se.citerus.registerapp.validation.FormValidationDecorator;
25
+import se.citerus.registerapp.validation.FormValidationSwingDecorator;
26
+import se.citerus.registerapp.validation.MandatoryTextFieldValidator;
17 27
 
18 28
 import com.jgoodies.forms.builder.DefaultFormBuilder;
19 29
 import com.jgoodies.forms.debug.FormDebugPanel;
30
+import com.jgoodies.forms.factories.ButtonBarFactory;
20 31
 import com.jgoodies.forms.layout.FormLayout;
21 32
 
22 33
 public class RegisterApp {
@@ -33,13 +44,14 @@ public class RegisterApp {
33 44
   
34 45
   private HandlingEventService handlingEventService;
35 46
   private boolean debugUI;
47
+  private FormValidationDecorator validator;
36 48
 
37 49
 
38 50
 
39 51
   /////////////////////////////////////////////////////////////////////////////
40 52
   // GUI EVENT HANDLING
41 53
   /////////////////////////////////////////////////////////////////////////////
42
-  protected void onRegister() {
54
+  protected void onRegister(){
43 55
     assert handlingEventService != null : "No HandlingEventService available";
44 56
     
45 57
     handlingEventService.register(ISO8601_DATE_FORMAT.format(completionTimeField.getValue()), 
@@ -65,8 +77,13 @@ public class RegisterApp {
65 77
     initComponents();
66 78
     JComponent panel = createMainPanel();
67 79
     
80
+    
68 81
     frame = createFrame(panel);
69 82
     frame.pack();
83
+    centerOnScreen(frame);
84
+    
85
+    initValidation(frame);
86
+    
70 87
     frame.setVisible(true);
71 88
     
72 89
     clearForm();
@@ -91,6 +108,10 @@ public class RegisterApp {
91 108
     locationField.setText("");
92 109
     eventTypeField.setText("");
93 110
   }
111
+
112
+  public static Border getMandatoryBorder() {
113
+    return new CompoundBorder(new LineBorder(Color.RED), new BasicBorders.MarginBorder());
114
+  }
94 115
   
95 116
   private void initComponents(){
96 117
     completionTimeField = new JFormattedTextField(ISO8601_DATE_FORMAT);
@@ -102,11 +123,41 @@ public class RegisterApp {
102 123
     registerButton = new JButton("Register");
103 124
     registerButton.addActionListener(new ActionListener(){
104 125
       public void actionPerformed(ActionEvent e) {
105
-        onRegister();
126
+        if (validator.validate()){
127
+          onRegister();
128
+        }
106 129
       }
107 130
     });
108 131
   }
109 132
 
133
+  /**
134
+   * We need to do initialization of validators after the components and their parent frame has been initialized.
135
+   * @param frame 
136
+   * 
137
+   */
138
+  private void initValidation(JFrame frame){
139
+    validator = new FormValidationSwingDecorator(frame);
140
+    
141
+    validator.add(eventTypeField, new MandatoryTextFieldValidator("Event type can't be empty"));
142
+    validator.add(trackingIdField, new MandatoryTextFieldValidator("Tracking id can't be empty"));
143
+  }
144
+  
145
+  
146
+  /**
147
+   * Center a component on the screen.
148
+   * 
149
+   * @param component the component to be centered
150
+   */
151
+
152
+  public static void centerOnScreen(Component component) {
153
+      Dimension componentSize = component.getSize();
154
+      Dimension screenSize = component.getToolkit().getScreenSize();
155
+
156
+      component.setLocation(
157
+          (screenSize.width  - componentSize.width)  / 2,
158
+          (int) ((screenSize.height - componentSize.height) *0.45));
159
+
160
+  }
110 161
 
111 162
   private JFrame createFrame(JComponent panel) {
112 163
     JFrame f = new JFrame();
@@ -121,7 +172,7 @@ public class RegisterApp {
121 172
     JComponent fieldPanel = createFieldPanel();
122 173
     JComponent buttonPanel = createButtonPanel();
123 174
     
124
-    DefaultFormBuilder mainBuilder = createBuilder("right:pref");
175
+    DefaultFormBuilder mainBuilder = createBuilder("p");
125 176
     mainBuilder.append(fieldPanel);
126 177
     mainBuilder.append(buttonPanel);
127 178
     
@@ -130,16 +181,12 @@ public class RegisterApp {
130 181
 
131 182
 
132 183
   private JComponent createButtonPanel() {
133
-    DefaultFormBuilder builder = createBuilder("right:pref, 3dlu");
134
-    
135
-    builder.append(registerButton);
136
-    
137
-    return builder.getPanel();
184
+    return ButtonBarFactory.buildRightAlignedBar(registerButton);
138 185
   }
139 186
 
140 187
 
141 188
   private JComponent createFieldPanel() {
142
-    DefaultFormBuilder builder = createBuilder("right:pref, 3dlu, 100dlu, 3dlu, p");
189
+    DefaultFormBuilder builder = createBuilder("right:pref, 3dlu, 100dlu");
143 190
     
144 191
     builder.appendSeparator("Completion");
145 192
     builder.append("Completion Time", completionTimeField); builder.nextLine();

+ 39
- 0
register-app/src/main/java/se/citerus/registerapp/validation/AbstractFormValidationDecorator.java Wyświetl plik

@@ -0,0 +1,39 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import java.awt.event.KeyEvent;
4
+import java.awt.event.KeyListener;
5
+import java.util.HashMap;
6
+import java.util.Map.Entry;
7
+
8
+import javax.swing.JComponent;
9
+
10
+public abstract class AbstractFormValidationDecorator implements FormValidationDecorator{
11
+  private HashMap<JComponent, ComponentValidator> validators = new HashMap<JComponent, ComponentValidator>();
12
+
13
+  public void add(final JComponent component, ComponentValidator validator) {
14
+    this.validators.put(component, validator);
15
+
16
+    component.addKeyListener(new KeyListener(){
17
+      public void keyPressed(KeyEvent e) {
18
+        undecorate(component);
19
+      }
20
+
21
+      public void keyReleased(KeyEvent e) {}
22
+      public void keyTyped(KeyEvent e) {}
23
+    });
24
+  }
25
+
26
+  public boolean validate() {
27
+    boolean allValidated = true;
28
+    for (final Entry<JComponent, ComponentValidator> entry : validators.entrySet()) {
29
+      if (!entry.getValue().validate(entry.getKey())){
30
+        decorate(entry.getKey(), entry.getValue());
31
+        allValidated = false;
32
+      }
33
+    }
34
+    return allValidated;
35
+  }
36
+  
37
+  public abstract void decorate(JComponent component, ComponentValidator validator);
38
+  public abstract void undecorate(JComponent component);
39
+}

+ 96
- 0
register-app/src/main/java/se/citerus/registerapp/validation/AbstractValidator.java Wyświetl plik

@@ -0,0 +1,96 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import java.awt.Color;
4
+import java.awt.FlowLayout;
5
+import java.awt.event.KeyEvent;
6
+import java.awt.event.KeyListener;
7
+
8
+import javax.swing.ImageIcon;
9
+import javax.swing.InputVerifier;
10
+import javax.swing.JComponent;
11
+import javax.swing.JFrame;
12
+import javax.swing.JLabel;
13
+import javax.swing.JPanel;
14
+
15
+public abstract class AbstractValidator extends InputVerifier implements KeyListener{
16
+  private static final Color ERROR_COMPONENT_COLOR = Color.PINK;
17
+  private static final Color POPUP_COLOR = new Color(243, 255, 159);
18
+  private JPanel popup;
19
+  private JLabel messageLabel = new JLabel();;
20
+  private JLabel image = new JLabel();
21
+  private JFrame parent;
22
+  private String message;;
23
+
24
+  
25
+  
26
+  public AbstractValidator(String message) {
27
+    this.message = message;
28
+  }
29
+  
30
+  public String getMessage(){
31
+    return message;
32
+  }
33
+
34
+  public AbstractValidator(JFrame parent, JComponent c, String message) {
35
+    c.addKeyListener(this);
36
+    popup = new JPanel();
37
+    this.parent = parent;
38
+    messageLabel = new JLabel(message + " ");
39
+    image = new JLabel(new ImageIcon("/icon/error_16x16.png"));
40
+    initComponents();
41
+  }
42
+
43
+  /**
44
+   * Implement the actual validation logic in this method. The method should
45
+   * return false if data is invalid and true if it is valid.
46
+   * 
47
+   * @param c The JComponent to be validated.
48
+   * @return false if data is invalid. true if it is valid.
49
+   */
50
+  protected abstract boolean validate(JComponent c);
51
+
52
+  @Override
53
+  public boolean verify(JComponent component) {
54
+    if (!validate(component)) {
55
+
56
+//      
57
+//      Dimension compSize = component.getSize();
58
+//      Point compPos = popup.getLocation();
59
+//      
60
+//      component.setBackground(ERROR_COMPONENT_COLOR);
61
+//
62
+//      popup.setLocation(
63
+//          compPos.x - (int) compSize.getWidth() / 2, 
64
+//          compPos.y + (int) compSize.getHeight() / 2);
65
+      
66
+      parent.setGlassPane(popup);
67
+      component.setBackground(ERROR_COMPONENT_COLOR);
68
+      popup.setVisible(true);
69
+      return false;
70
+    } else {
71
+      component.setBackground(Color.WHITE);
72
+      return true;
73
+    }
74
+  }
75
+
76
+  public void keyPressed(KeyEvent e) {
77
+    popup.setVisible(false);    
78
+  }
79
+
80
+  public void keyReleased(KeyEvent e) {}
81
+
82
+  public void keyTyped(KeyEvent e) {}
83
+  
84
+  
85
+  private void initComponents() {
86
+    popup.setLayout(new FlowLayout());
87
+//    popup.setUndecorated(true);
88
+    popup.setBackground(POPUP_COLOR);
89
+    popup.add(image);
90
+    popup.add(messageLabel);
91
+//    popup.setOpaque(false);
92
+//    popup.setFocusableWindowState(false);
93
+  }
94
+
95
+
96
+}

+ 8
- 0
register-app/src/main/java/se/citerus/registerapp/validation/ComponentValidator.java Wyświetl plik

@@ -0,0 +1,8 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import javax.swing.JComponent;
4
+
5
+public interface ComponentValidator {
6
+  boolean validate(JComponent c);
7
+  String getMessage();
8
+}

+ 13
- 0
register-app/src/main/java/se/citerus/registerapp/validation/FormValidationDecorator.java Wyświetl plik

@@ -0,0 +1,13 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import javax.swing.JComponent;
4
+
5
+
6
+public interface FormValidationDecorator {
7
+
8
+  void add(final JComponent component, ComponentValidator validator);
9
+
10
+  boolean validate();
11
+
12
+  
13
+}

+ 114
- 0
register-app/src/main/java/se/citerus/registerapp/validation/FormValidationSwingDecorator.java Wyświetl plik

@@ -0,0 +1,114 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import java.awt.Color;
4
+import java.awt.Dimension;
5
+import java.awt.FlowLayout;
6
+import java.awt.Point;
7
+import java.util.HashMap;
8
+
9
+import javax.swing.ImageIcon;
10
+import javax.swing.JComponent;
11
+import javax.swing.JFrame;
12
+import javax.swing.JLabel;
13
+import javax.swing.JPanel;
14
+
15
+public class FormValidationSwingDecorator extends AbstractFormValidationDecorator{
16
+
17
+  private static final int POPUP_Y_OFFSET = 4;
18
+  private static final int POPUP_X_OFFSET = 12;
19
+  private Color oldColor = Color.WHITE;
20
+  private JFrame form;
21
+  private String message;
22
+  private HashMap<JComponent, JPanel> popups = new HashMap<JComponent, JPanel>();
23
+  private JPanel glassPane = new JPanel();
24
+
25
+  public FormValidationSwingDecorator(JFrame form) {
26
+    assert form != null : "Can't decorate null frame";
27
+    
28
+    this.form = form;
29
+    glassPane.setOpaque(false);
30
+    glassPane.setVisible(false);
31
+    glassPane.setLayout(null);
32
+//    glassPane.setPreferredSize(form.getPreferredSize());
33
+    glassPane.setSize(form.getSize());
34
+    form.setGlassPane(glassPane);
35
+  }
36
+
37
+  public FormValidationSwingDecorator(JFrame form, String message) {
38
+    this(form);
39
+    
40
+    this.message = message;
41
+  }
42
+
43
+  private JPanel createPopupRelativeTo(JComponent component) {
44
+    JPanel popupPane = null;
45
+    
46
+    if (popups.containsKey(component)){
47
+      popupPane = popups.get(component);
48
+    } else {
49
+      popupPane = new JPanel(new FlowLayout());
50
+      glassPane.add(popupPane);
51
+      
52
+      popupPane.add(getIconLabel());
53
+      popupPane.add(getMessageLabel());
54
+      popupPane.setLocation(getPopupPositionRelativeTo(component));
55
+      popupPane.setVisible(true);
56
+      popupPane.setOpaque(false);
57
+      popupPane.validate();
58
+      popupPane.setSize(popupPane.getPreferredSize());
59
+     
60
+    }
61
+    
62
+    return popupPane;
63
+  }
64
+
65
+  private Point getPopupPositionRelativeTo(JComponent component) {
66
+    Point compPos = component.getLocation();
67
+    Dimension compDim = component.getSize();
68
+    Point popupPos = new Point(compPos.x + POPUP_X_OFFSET, compPos.y + compDim.height + POPUP_Y_OFFSET);
69
+    
70
+    System.out.println("Comp pos: " + compPos + " - Popup pos: " + popupPos);
71
+    return popupPos;
72
+  }
73
+
74
+  private JLabel getMessageLabel() {
75
+    JLabel label = new JLabel(message != null ? message : "");
76
+    label.setOpaque(false);
77
+    return label;
78
+  }
79
+
80
+  private JLabel getIconLabel() {
81
+    JLabel label = new JLabel();
82
+    
83
+    java.net.URL imageURL = this.getClass().getResource("/icon/error_16x16.png");
84
+    if (imageURL != null){
85
+      ImageIcon icon = new ImageIcon(imageURL);
86
+      label.setIcon(icon);
87
+    } else {
88
+      System.out.println("No icon found");
89
+    }
90
+    
91
+    
92
+    label.setOpaque(false);
93
+    return label;
94
+  }
95
+  
96
+  @Override
97
+  public void decorate(JComponent component, ComponentValidator validator) {
98
+    this.message = validator.getMessage();
99
+    this.oldColor = component.getBackground();
100
+    component.setBackground(Color.PINK);
101
+    popups.put(component, createPopupRelativeTo(component));
102
+    glassPane.setVisible(true);
103
+  }
104
+
105
+  @Override
106
+  public void undecorate(JComponent component) {
107
+    component.setBackground(oldColor);
108
+    JPanel panel = popups.get(component);
109
+    if (panel != null){
110
+      panel.setVisible(false);
111
+    }
112
+    glassPane.setVisible(false);
113
+  }
114
+}

+ 25
- 0
register-app/src/main/java/se/citerus/registerapp/validation/MandatoryTextFieldValidator.java Wyświetl plik

@@ -0,0 +1,25 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import javax.swing.JComponent;
4
+import javax.swing.JTextField;
5
+
6
+public class MandatoryTextFieldValidator implements ComponentValidator {
7
+  private String message;
8
+
9
+  public MandatoryTextFieldValidator(String message) {
10
+    this.message = message;
11
+  }
12
+
13
+  public boolean validate(JComponent c) {
14
+    JTextField field = (JTextField) c;
15
+    
16
+    boolean valid = !"".equals(field.getText());
17
+    
18
+    return valid;
19
+  }
20
+
21
+  public String getMessage() {
22
+    return message;
23
+  }
24
+
25
+}

BIN
register-app/src/main/resources/icon/error_16x16.png Wyświetl plik


+ 120
- 0
register-app/src/test/java/se/citerus/registerapp/validation/ValidationTest.java Wyświetl plik

@@ -0,0 +1,120 @@
1
+package se.citerus.registerapp.validation;
2
+
3
+import java.awt.event.ActionEvent;
4
+import java.awt.event.ActionListener;
5
+
6
+import javax.swing.JButton;
7
+import javax.swing.JComponent;
8
+import javax.swing.JFrame;
9
+import javax.swing.JTextField;
10
+
11
+import junit.framework.TestCase;
12
+
13
+public class ValidationTest extends TestCase {
14
+  private boolean actionPerformed;
15
+
16
+  public void testValidationScenario() throws Exception {
17
+    JFrame frame = new JFrame();
18
+    
19
+    final FormValidationDecorator validationDecorator = new FormValidationSwingDecorator(frame);
20
+    
21
+    JTextField field1 = new JTextField();
22
+    JTextField field2 = new JTextField();
23
+    JButton button = new JButton();
24
+    frame.add(field1);
25
+    frame.add(field2);
26
+    frame.add(button);
27
+    
28
+    
29
+    ValidatorMock validator1 = createValidator("No Way!", true);
30
+    validationDecorator.add(field1, validator1);
31
+    
32
+    ValidatorMock validator2 = createValidator("My Way!", true);
33
+    validationDecorator.add(field2, validator2);
34
+    
35
+   button.addActionListener(new ActionListener(){
36
+    public void actionPerformed(ActionEvent e) {
37
+      if (validationDecorator.validate()){
38
+        onAction();
39
+      }
40
+    }
41
+   });
42
+   
43
+   
44
+   
45
+   field1.setText("Field1");
46
+   field2.setText("");
47
+   button.doClick();
48
+   assertTrue("Field1 not validated", validator1.isValidated());
49
+   assertTrue("Field2 not validated", validator2.isValidated());
50
+   assertTrue("Button action not performed", actionPerformed);
51
+  }
52
+  
53
+  public void testValidationFailure() throws Exception {
54
+    JFrame frame = new JFrame();
55
+    final FormValidationDecorator validator = new FormValidationSwingDecorator(frame);
56
+    
57
+    JTextField field1 = new JTextField();
58
+    JTextField field2 = new JTextField();
59
+    JButton button = new JButton();
60
+    frame.add(field1);
61
+    frame.add(field2);
62
+    frame.add(button);
63
+    
64
+    ValidatorMock validator1 = createValidator("No Way!", true);
65
+    validator.add(field1, validator1);
66
+    
67
+    ValidatorMock validator2 = createValidator("My Way!", false);
68
+    validator.add(field2, validator2);
69
+    
70
+   button.addActionListener(new ActionListener(){
71
+    public void actionPerformed(ActionEvent e) {
72
+      if (validator.validate()){
73
+        onAction();
74
+      }
75
+    }
76
+   });
77
+   
78
+   field1.setText("Field1");
79
+   field2.setText("");
80
+   button.doClick();
81
+   assertTrue("Field1 not validated", validator1.isValidated());
82
+   assertTrue("Field2 not validated", validator2.isValidated());
83
+   assertFalse("Button action should not be performed", actionPerformed);
84
+  }
85
+  
86
+
87
+  private ValidatorMock createValidator(String message, boolean result) {
88
+    return new ValidatorMock(message, result);
89
+  }
90
+
91
+  protected void onAction() {
92
+    this.actionPerformed = true;
93
+    // Do some action...
94
+  }
95
+  
96
+  private static final class ValidatorMock implements ComponentValidator{
97
+    private final boolean result;
98
+    private boolean validated;
99
+    private String message;
100
+    
101
+    public ValidatorMock(String message, boolean result) {
102
+      this.message = message;
103
+      this.result = result;
104
+    }
105
+
106
+    public boolean validate(JComponent c) {
107
+      validated = true;
108
+      return result;
109
+    }
110
+
111
+    public boolean isValidated() {
112
+      return validated;
113
+    }
114
+
115
+    public String getMessage() {
116
+      return message;
117
+    }
118
+    
119
+  }
120
+}

+ 1
- 2
register-app/startApp.sh Wyświetl plik

@@ -1,3 +1,2 @@
1 1
 #!/bin/sh
2
-
3
-java -cp target/register-app-1.0-SNAPSHOT-jar-with-dependencies.jar se.citerus.App
2
+java -cp target/register-app-1.0-SNAPSHOT-jar-with-dependencies.jar se.citerus.App