4 * Created on 2007/07/21, 22:37
7 package org.jent.checksmtp;
9 import java.awt.Dimension;
10 import java.awt.Point;
11 import java.awt.Toolkit;
12 import java.awt.event.ActionEvent;
13 import java.awt.event.ActionListener;
14 import javax.swing.JFrame;
18 * @author Takuya Ono <takuya-o@users.sourceforge.jp>
20 public class ApplicationUI extends javax.swing.JFrame {
22 /** Creates new form ApplicationUI */
23 public ApplicationUI() {
29 private void resetDisplay() {
30 jTextFieldReceiverPort.setText(Integer.toString(ApplicationProperties.getSmtpPort()));
31 jTextFieldServerHost.setText(ApplicationProperties.getSmtpServerHost());
32 jTextFieldServerPort.setText(Integer.toString(ApplicationProperties.getSmtpServerPort()));
33 jCheckBoxEnableRemoteConnect.setSelected(ApplicationProperties.getSmtpEnebleRemoteConnect());
35 jCheckBoxLdap.setSelected(ApplicationProperties.getLdap());
36 jTextFieldProviderUrl.setText(ApplicationProperties.getLdapProviderURL());
37 jTextFieldBaseDn.setText(ApplicationProperties.getLdapRoot());
38 jTextFieldAttribute.setText(ApplicationProperties.getLdapAttributes());
39 jCheckBoxIsSjis.setSelected(ApplicationProperties.getLdapIsSjis());
44 /** This method is called from within the constructor to
45 * initialize the form.
46 * WARNING: Do NOT modify this code. The content of this method is
47 * always regenerated by the Form Editor.
49 // <editor-fold defaultstate="collapsed" desc=" Generated Code">//GEN-BEGIN:initComponents
50 private void initComponents() {
51 jTabbedPane = new javax.swing.JTabbedPane();
52 jPanelMail = new javax.swing.JPanel();
53 jLabel1 = new javax.swing.JLabel();
54 jLabel2 = new javax.swing.JLabel();
55 jLabel3 = new javax.swing.JLabel();
56 jTextFieldReceiverPort = new javax.swing.JTextField();
57 jTextFieldServerHost = new javax.swing.JTextField();
58 jTextFieldServerPort = new javax.swing.JTextField();
59 jCheckBoxEnableRemoteConnect = new javax.swing.JCheckBox();
60 jPanelLDAP = new javax.swing.JPanel();
61 jCheckBoxLdap = new javax.swing.JCheckBox();
62 jLabel4 = new javax.swing.JLabel();
63 jLabel5 = new javax.swing.JLabel();
64 jLabel6 = new javax.swing.JLabel();
65 jTextFieldProviderUrl = new javax.swing.JTextField();
66 jTextFieldBaseDn = new javax.swing.JTextField();
67 jTextFieldAttribute = new javax.swing.JTextField();
68 jCheckBoxIsSjis = new javax.swing.JCheckBox();
69 jButtonOK = new javax.swing.JButton();
70 jButtonCancel = new javax.swing.JButton();
71 jButtonQuit = new javax.swing.JButton();
73 setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
74 setTitle("Mail Destination Confirm Properties");
75 addWindowListener(new java.awt.event.WindowAdapter() {
76 public void windowDeiconified(java.awt.event.WindowEvent evt) {
77 formWindowDeiconified(evt);
79 public void windowIconified(java.awt.event.WindowEvent evt) {
80 formWindowIconified(evt);
84 jLabel1.setText("Receiver Port:");
86 jLabel2.setText("Mail Server:");
88 jLabel3.setText("Port:");
90 jTextFieldReceiverPort.setText("8725");
91 jTextFieldReceiverPort.setToolTipText("Mail Destination Confirmer SMTP port number.");
93 jTextFieldServerHost.setText("mail");
94 jTextFieldServerHost.setToolTipText("Mail server host name or IP address.");
96 jTextFieldServerPort.setText("25");
97 jTextFieldServerPort.setToolTipText("Mail server port number.");
99 jCheckBoxEnableRemoteConnect.setText("Enable remote connect");
100 jCheckBoxEnableRemoteConnect.setToolTipText("Enable remote machine access this service. (Usually: disable)");
101 jCheckBoxEnableRemoteConnect.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
102 jCheckBoxEnableRemoteConnect.setMargin(new java.awt.Insets(0, 0, 0, 0));
104 org.jdesktop.layout.GroupLayout jPanelMailLayout = new org.jdesktop.layout.GroupLayout(jPanelMail);
105 jPanelMail.setLayout(jPanelMailLayout);
106 jPanelMailLayout.setHorizontalGroup(
107 jPanelMailLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
108 .add(jPanelMailLayout.createSequentialGroup()
110 .add(jPanelMailLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
111 .add(jPanelMailLayout.createSequentialGroup()
113 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
114 .add(jTextFieldReceiverPort, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 112, Short.MAX_VALUE)
115 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
116 .add(jCheckBoxEnableRemoteConnect))
117 .add(jPanelMailLayout.createSequentialGroup()
119 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
120 .add(jTextFieldServerHost, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE)
121 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
123 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
124 .add(jTextFieldServerPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 54, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
128 jPanelMailLayout.linkSize(new java.awt.Component[] {jLabel1, jLabel2}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
130 jPanelMailLayout.setVerticalGroup(
131 jPanelMailLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
132 .add(jPanelMailLayout.createSequentialGroup()
134 .add(jPanelMailLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
136 .add(jCheckBoxEnableRemoteConnect)
137 .add(jTextFieldReceiverPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
138 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
139 .add(jPanelMailLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
142 .add(jTextFieldServerHost, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
143 .add(jTextFieldServerPort, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
144 .addContainerGap(74, Short.MAX_VALUE))
146 jTabbedPane.addTab("Mail", jPanelMail);
148 jCheckBoxLdap.setText("Enable LDAP search");
149 jCheckBoxLdap.setToolTipText("Enable LDAP configration.");
150 jCheckBoxLdap.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
151 jCheckBoxLdap.setMargin(new java.awt.Insets(0, 0, 0, 0));
152 jCheckBoxLdap.addChangeListener(new javax.swing.event.ChangeListener() {
153 public void stateChanged(javax.swing.event.ChangeEvent evt) {
154 jCheckBoxLdapStateChanged(evt);
158 jLabel4.setText("URL:");
160 jLabel5.setText("Root DN:");
162 jLabel6.setText("Attribute:");
164 jTextFieldProviderUrl.setText("ldap://localhost:389/");
165 jTextFieldProviderUrl.setToolTipText("LDAP server URL.");
166 jTextFieldProviderUrl.setEnabled(false);
168 jTextFieldBaseDn.setText("C=JP");
169 jTextFieldBaseDn.setToolTipText("LDAP search start DN.");
170 jTextFieldBaseDn.setEnabled(false);
172 jTextFieldAttribute.setText("cn");
173 jTextFieldAttribute.setToolTipText("Display Attribuite. Example: cn title;lang-ja-jp");
174 jTextFieldAttribute.setEnabled(false);
176 jCheckBoxIsSjis.setText("Force SJIS");
177 jCheckBoxIsSjis.setToolTipText("Check this, when LDAP server use Shift JIS on network.");
178 jCheckBoxIsSjis.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
179 jCheckBoxIsSjis.setEnabled(false);
180 jCheckBoxIsSjis.setMargin(new java.awt.Insets(0, 0, 0, 0));
182 org.jdesktop.layout.GroupLayout jPanelLDAPLayout = new org.jdesktop.layout.GroupLayout(jPanelLDAP);
183 jPanelLDAP.setLayout(jPanelLDAPLayout);
184 jPanelLDAPLayout.setHorizontalGroup(
185 jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
186 .add(jPanelLDAPLayout.createSequentialGroup()
187 .add(jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
188 .add(jPanelLDAPLayout.createSequentialGroup()
190 .add(jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
191 .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel6)
192 .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel5)
193 .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel4))
194 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
195 .add(jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
196 .add(jTextFieldAttribute, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
197 .add(jTextFieldBaseDn, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
198 .add(jPanelLDAPLayout.createSequentialGroup()
199 .add(jTextFieldProviderUrl, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE)
200 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
201 .add(jCheckBoxIsSjis))))
202 .add(jPanelLDAPLayout.createSequentialGroup()
204 .add(jCheckBoxLdap)))
208 jPanelLDAPLayout.linkSize(new java.awt.Component[] {jLabel4, jLabel5, jLabel6}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
210 jPanelLDAPLayout.setVerticalGroup(
211 jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
212 .add(jPanelLDAPLayout.createSequentialGroup()
215 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
216 .add(jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
218 .add(jTextFieldProviderUrl, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
219 .add(jCheckBoxIsSjis))
220 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
221 .add(jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
223 .add(jTextFieldBaseDn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
224 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
225 .add(jPanelLDAPLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
227 .add(jTextFieldAttribute, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
228 .addContainerGap(28, Short.MAX_VALUE))
230 jTabbedPane.addTab("LDAP", jPanelLDAP);
232 jButtonOK.setText("OK");
233 jButtonOK.addActionListener(new java.awt.event.ActionListener() {
234 public void actionPerformed(java.awt.event.ActionEvent evt) {
235 jButtonOKActionPerformed(evt);
239 jButtonCancel.setText("Cancel");
240 jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
241 public void actionPerformed(java.awt.event.ActionEvent evt) {
242 jButtonCancelActionPerformed(evt);
246 jButtonQuit.setText("Quit");
247 jButtonQuit.addActionListener(new java.awt.event.ActionListener() {
248 public void actionPerformed(java.awt.event.ActionEvent evt) {
249 jButtonQuitActionPerformed(evt);
253 org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
254 getContentPane().setLayout(layout);
255 layout.setHorizontalGroup(
256 layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
258 .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
261 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 145, Short.MAX_VALUE)
263 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
268 layout.linkSize(new java.awt.Component[] {jButtonCancel, jButtonOK, jButtonQuit}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
270 layout.setVerticalGroup(
271 layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
272 .add(layout.createSequentialGroup()
274 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
275 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
282 }// </editor-fold>//GEN-END:initComponents
284 private void formWindowDeiconified(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowDeiconified
285 setTitle("Mail Destination Confirm Properties");
286 }//GEN-LAST:event_formWindowDeiconified
288 private void formWindowIconified(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowIconified
290 }//GEN-LAST:event_formWindowIconified
292 private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed
295 port = Integer.parseInt(jTextFieldReceiverPort.getText());
296 } catch (NumberFormatException ex) {
297 ex.printStackTrace();
298 port = ApplicationProperties.getSmtpPort(); //last saved value.
299 jTextFieldReceiverPort.setText(Integer.toString(port));
301 String serverHost = jTextFieldServerHost.getText();
304 serverPort = Integer.parseInt(jTextFieldServerPort.getText());
305 } catch (NumberFormatException ex) {
306 ex.printStackTrace();
307 serverPort = ApplicationProperties.getSmtpServerPort(); //last saved value.
308 jTextFieldServerPort.setText(Integer.toString(serverPort));
310 boolean enableRemoteConnect = jCheckBoxEnableRemoteConnect.isSelected();
312 boolean enableLdap = jCheckBoxLdap.isSelected();
313 String ldapUrl = jTextFieldProviderUrl.getText();
314 String rootDn = jTextFieldBaseDn.getText();
315 String attribute = jTextFieldAttribute.getText();
316 boolean isSjis = jCheckBoxIsSjis.isSelected();
318 if ( port != ApplicationProperties.getSmtpPort()
319 || !serverHost.equals(ApplicationProperties.getSmtpServerHost())
320 || serverPort != ApplicationProperties.getSmtpServerPort()
321 || enableRemoteConnect != ApplicationProperties.getSmtpEnebleRemoteConnect()
323 || enableLdap != ApplicationProperties.getLdap()
324 || !ldapUrl.equals(ApplicationProperties.getLdapProviderURL())
325 || !rootDn.equals(ApplicationProperties.getLdapRoot())
326 || !attribute.equals(ApplicationProperties.getLdapAttributes())
327 || isSjis != ApplicationProperties.getLdapIsSjis()
328 || isModifiedPotition()
330 // When modify data, save properries file.
331 ApplicationProperties.setSmtpPort(port);
332 ApplicationProperties.setSmtpServerHost(serverHost);
333 ApplicationProperties.setSmtpServerPort(serverPort);
334 ApplicationProperties.setSmtpEnableRemoteConnect(enableRemoteConnect);
336 ApplicationProperties.setLdap(enableLdap);
337 ApplicationProperties.setLdapProviderURL(ldapUrl);
338 ApplicationProperties.setLdapRoot(rootDn);
339 ApplicationProperties.setLdapAttributes(attribute);
340 ApplicationProperties.setLdapIsSjis(isSjis);
342 smtpClient.configChangeNotify();
343 if ( !ApplicationProperties.save() ) {
344 //TODO: Display Save error Dialog.
349 }//GEN-LAST:event_jButtonOKActionPerformed
351 private void jButtonQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonQuitActionPerformed
353 }//GEN-LAST:event_jButtonQuitActionPerformed
355 private void jCheckBoxLdapStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jCheckBoxLdapStateChanged
356 // TODO add your handling code here:
357 boolean check = jCheckBoxLdap.isSelected();
358 jTextFieldProviderUrl.setEnabled(check);
359 jTextFieldBaseDn.setEnabled(check);
360 jTextFieldAttribute.setEnabled(check);
361 jCheckBoxIsSjis.setEnabled(check);
362 }//GEN-LAST:event_jCheckBoxLdapStateChanged
364 private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
365 // TODO add your handling code here:
366 //this.setVisible(false);
369 }//GEN-LAST:event_jButtonCancelActionPerformed
371 private boolean isModifiedPotition() {
374 if ( getExtendedState() == JFrame.NORMAL ) {
375 Point locationPoint = getLocationOnScreen(); //TODO: IllegalComponentStateException
379 //Unexpect logic. Because this method call from pushed "OK" button.
383 int h = this.getHeight();
384 int w = this.getWidth();
385 boolean modified = false;
387 if ( x != ApplicationProperties.getConfigDialogPosX()
388 || y != ApplicationProperties.getConfigDialogPosY()
389 || h != ApplicationProperties.getConfigDialogPosH()
390 || w != ApplicationProperties.getConfigDialogPosW()
393 ApplicationProperties.setConfigDialogPosX(x);
394 ApplicationProperties.setConfigDialogPosY(y);
395 ApplicationProperties.setConfigDialogPosH(h);
396 ApplicationProperties.setConfigDialogPosW(w);
402 private boolean initSystemTray() {
403 boolean useSystemTray = false;
405 Class.forName("java.awt.SystemTray");
406 /* TODO: SystemTray suuport
407 java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray();
408 if(tray.isSupported()){
409 java.awt.TrayIcon trayIcon = new java.awt.TrayIcon(
410 new javax.swing.ImageIcon(
411 SystemTrayTest.class.getResource("images/mdc.gif")).getImage());
412 trayIcon.setImageAutoSize(true);
414 // create a action listener to listen for default action executed on the tray icon
415 ActionListener listener = new ActionListener() {
416 public void actionPerformed(ActionEvent e) {
417 // execute default action of the application
418 if ( e.paramString().equal("Quit")) {
422 if ( this.getExtendedState() == ICONIFIED ) {
423 this.setExtendedState(NORMAL);
428 java.awt.PopupMenu popup = new java.awt.PopupMenu();
429 popup.addActionListener(listener);
432 trayIcon.setPopupMenu(popup);
434 useSystemTray = true;
437 } catch (ClassNotFoundException ex) {
438 // Do not support SystemTray on this VM.
440 return useSystemTray;
443 private void iconified() {
444 if ( useSystemTray ) {
445 this.setVisible(false);
447 this.setExtendedState(ICONIFIED);
452 * @param args the command line arguments
454 public static void main(String args[]) {
457 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
458 } catch (Exception e) {
464 java.awt.EventQueue.invokeLater(new Runnable() {
466 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
467 ApplicationUI applicationUI = new ApplicationUI();
468 applicationUI.setVisible(true);
470 applicationUI.useSystemTray = applicationUI.initSystemTray();
472 //If exsist configuration file, iconise at start up.
473 if ( ApplicationProperties.isFileLoaded() ) {
474 int x = ApplicationProperties.getConfigDialogPosX();
475 int y = ApplicationProperties.getConfigDialogPosY();
476 int w = ApplicationProperties.getConfigDialogPosW();
477 int h = ApplicationProperties.getConfigDialogPosH();
479 if ( x > screenSize.width ) {
480 x = screenSize.width - w;
481 if ( x < 0 ) { x = 0; };
483 if ( y > screenSize.height ) {
484 y = screenSize.height - h;
485 if ( y < 0 ) { y = 0; };
487 applicationUI.setBounds(x, y, w, h);
488 applicationUI.iconified();
490 //No Configuration file.
491 Dimension frameSize = ApplicationProperties.getConfigurationDialogSize();
492 if (frameSize.height > screenSize.height) {
493 frameSize.height = screenSize.height;
495 if (frameSize.width > screenSize.width) {
496 frameSize.width = screenSize.width;
499 applicationUI.setBounds(
500 (screenSize.width - frameSize.width) / 2,
501 (screenSize.height - frameSize.height) / 2,
502 frameSize.width, frameSize.height );
507 smtpClient = new SMTPclient();
509 private static SMTPclient smtpClient = null;
510 private boolean useSystemTray = false;
512 // Variables declaration - do not modify//GEN-BEGIN:variables
513 private javax.swing.JButton jButtonCancel;
514 private javax.swing.JButton jButtonOK;
515 private javax.swing.JButton jButtonQuit;
516 private javax.swing.JCheckBox jCheckBoxEnableRemoteConnect;
517 private javax.swing.JCheckBox jCheckBoxIsSjis;
518 private javax.swing.JCheckBox jCheckBoxLdap;
519 private javax.swing.JLabel jLabel1;
520 private javax.swing.JLabel jLabel2;
521 private javax.swing.JLabel jLabel3;
522 private javax.swing.JLabel jLabel4;
523 private javax.swing.JLabel jLabel5;
524 private javax.swing.JLabel jLabel6;
525 private javax.swing.JPanel jPanelLDAP;
526 private javax.swing.JPanel jPanelMail;
527 private javax.swing.JTabbedPane jTabbedPane;
528 private javax.swing.JTextField jTextFieldAttribute;
529 private javax.swing.JTextField jTextFieldBaseDn;
530 private javax.swing.JTextField jTextFieldProviderUrl;
531 private javax.swing.JTextField jTextFieldReceiverPort;
532 private javax.swing.JTextField jTextFieldServerHost;
533 private javax.swing.JTextField jTextFieldServerPort;
534 // End of variables declaration//GEN-END:variables