001package csheets.ext.database.ui;
002
003import java.awt.*;
004import java.awt.event.*;
005import java.util.*;
006
007import javax.swing.*;
008import javax.swing.GroupLayout.Alignment;
009import javax.swing.LayoutStyle.ComponentPlacement;
010
011import csheets.core.Cell;
012import csheets.ext.database.controller.ControllerSync;
013import csheets.ext.database.core.*;
014
015/**
016 * Class that will implements the interface of the sync box
017 * 
018 * @author Andre
019 * 
020 */
021public class UISync extends JFrame implements Observer {
022        /** Generated ID */
023        private static final long serialVersionUID = 1L;
024        /**
025         * database available drivers stored in a string and displayed in a combobox
026         */
027        private final String[][] dbDrivers;
028        /** drivers name */
029        private final String[] driversName;
030        /** drivers list */
031        @SuppressWarnings("rawtypes")
032        private final JComboBox comboDrivers;
033
034        /** controller object for GUI-controller pattern */
035        private final ControllerSync ctrlSync;
036
037        /** button of ok */
038        private final JButton btnOk = new JButton("OK");
039        /** button of cancel */
040        private final JButton btnCancel = new JButton("Cancel");
041        /** button of get url */
042        private final JButton btnUrl = new JButton("Get URL");
043
044        /** selected cells to export in a 2D array */
045        private final Cell[][] cells;
046
047        /** textfields for username, passord, database and table name */
048        @SuppressWarnings("unused")
049        private final JTextField userTxt, dbTxt, tableTxt, urlTxt;
050        /** field for the password */
051        private final JPasswordField pwd;
052
053        /** label to display system information to the user */
054        JLabel sysMsg = new JLabel();
055
056        /** export thread */
057        ThreadSync thrSync;
058
059        /** this ui */
060        UISync sync = this;
061
062        /** return value for merge */
063        private int returnValue = -1;
064
065        /**
066         * Creates a new sync ui
067         * 
068         * @param cells
069         *            cells to be synchronized
070         * @throws Exception
071         *             if any type of exceptions occurs
072         */
073        @SuppressWarnings({ "unchecked", "rawtypes" })
074        public UISync(Cell[][] cells) throws Exception {
075                /* window title */
076                super("Sync information with database");
077
078                /* saving argument of this function is class variable */
079                this.cells = cells;
080
081                /* creating a new controller */
082                ctrlSync = new ControllerSync();
083
084                /*
085                 * getting the list of supported databases and putting it in the combo
086                 * box
087                 */
088                dbDrivers = ctrlSync.getDBlist();
089                driversName = new String[dbDrivers.length];
090                for (int i = 0; i < dbDrivers.length; i++) {
091                        driversName[i] = dbDrivers[i][0];
092                }
093                comboDrivers = new JComboBox(driversName);
094
095                /* main panel */
096                JPanel mainPanel = new JPanel(new BorderLayout());
097
098                /* defining labels */
099                JLabel lblDBdrivers = new JLabel("Database");
100                JLabel lblUser = new JLabel("Username");
101                JLabel lblPwd = new JLabel("Password");
102                JLabel lblUrl = new JLabel("URL");
103                JLabel lblTableName = new JLabel("Table name");
104
105                /* setting default system message text and color */
106                sysMsg.setText("Fill the required fields");
107                sysMsg.setForeground(Color.BLUE);
108
109                /* defining text fields */
110                dbTxt = new JTextField(30);
111                userTxt = new JTextField(30);
112                pwd = new JPasswordField("");
113                tableTxt = new JTextField(30);
114                urlTxt = new JTextField(30);
115
116                /* defining another panel */
117                JPanel anotherPanel = new JPanel(new GridLayout(7, 1));
118                anotherPanel.add(lblDBdrivers);
119                anotherPanel.add(comboDrivers);
120                anotherPanel.add(lblUser);
121                anotherPanel.add(userTxt);
122                anotherPanel.add(lblPwd);
123                anotherPanel.add(pwd);
124                anotherPanel.add(lblUrl);
125                anotherPanel.add(urlTxt);
126                anotherPanel.add(lblTableName);
127                anotherPanel.add(tableTxt);
128                anotherPanel.add(sysMsg);
129
130                /* defining panel for buttons */
131                JPanel panelBtn = new JPanel();
132                panelBtn.add(btnOk);
133                panelBtn.add(btnCancel);
134                panelBtn.add(btnUrl);
135
136                /* setting up action listeners */
137                HandlesEvent t = new HandlesEvent();
138                btnOk.addActionListener(t);
139                btnCancel.addActionListener(t);
140                btnUrl.addActionListener(t);
141
142                /* adding all object to build window */
143                Container c = getContentPane();
144                mainPanel.add(anotherPanel);
145                mainPanel.add(panelBtn, BorderLayout.SOUTH);
146                c.add(mainPanel);
147
148                /* other window settings */
149                pack();
150                setVisible(true);
151                setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
152                setLocationRelativeTo(null);
153                setResizable(false);
154        }
155
156        /**
157         * 
158         * Class that will handle the events occured in the user interface
159         * 
160         * @author Andre
161         * 
162         */
163        private class HandlesEvent implements ActionListener {
164                @Override
165                public void actionPerformed(ActionEvent e) {
166                        /* default url button */
167                        if (e.getSource() == btnUrl) {
168                                urlTxt.setText(dbDrivers[comboDrivers.getSelectedIndex()][1]);
169                        }
170
171                        /* button OK */
172                        else if (e.getSource() == btnOk) {
173                                /* checks if there's at least two rows to proceed with sync */
174                                if (cells.length < 2) {
175                                        JOptionPane
176                                                        .showMessageDialog(null,
177                                                                        "Error: you must select at least\ntwo rows to sync!");
178                                        dispose();
179                                }
180
181                                /* checks if all fields are filled */
182                                if ((userTxt.getText().trim().length() == 0)
183                                                || (pwd.getPassword().length == 0)
184                                                || (tableTxt.getText().trim().length() == 0)) {
185                                        sysMsg.setText("Username/password/tablename required!");
186                                        sysMsg.setForeground(Color.RED);
187                                }
188                                /* if all fields are filled tries to connect */
189                                else {
190                                        /* the combo index indicates which database will be used */
191                                        int index = comboDrivers.getSelectedIndex();
192
193                                        thrSync = new ThreadSync(cells, dbDrivers[index][1],
194                                                        userTxt.getText(), pwd.getSelectedText(),
195                                                        tableTxt.getText(), dbDrivers[index][0], sync);
196                                        Thread thr = new Thread(thrSync);
197                                        thr.start();
198                                        dispose();
199
200                                }
201                        }
202                        /* button cancel */
203                        else if (e.getSource() == btnCancel) {
204                                dispose();
205                        }
206                }
207        }
208
209        @Override
210        public void update(Observable o, Object arg) {
211
212                MergeWindowSync ui = new MergeWindowSync(sync, true);
213                ObserverMessages obm = (ObserverMessages) arg;
214                String message = "Database:" + obm.getDatabaseValue()
215                                + "\nApplication:" + obm.getApplicationValue()
216                                + "\nWhat do you wanna persist?";
217                ui.createWindow(message);
218                ui.setVisible(true);
219                obm.setDecision(returnValue);
220        }
221
222        /**
223         * Creates a new merge window error
224         * 
225         * @author Andre
226         * 
227         */
228        public class MergeWindowSync extends JDialog {
229                /** generated id */
230                private static final long serialVersionUID = 1L;
231                /** application button */
232                private JButton jButton1;
233                /** database button */
234                private JButton jButton2;
235                /** text area */
236                private JTextArea jLabel1;
237
238                /**
239                 * Creates new MergeWindowSync frame
240                 */
241                public MergeWindowSync(Frame parent, boolean modal) {
242                        super(parent, modal);
243                }
244
245                /**
246                 * Creates a new window to choose between application and database
247                 * 
248                 * @param text
249                 *            the text in label
250                 * @return the choosed method
251                 */
252                public void createWindow(String text) {
253                        jLabel1 = new JTextArea(text);
254                        jLabel1.setEditable(false);
255                        jButton1 = new JButton("Application");
256                        jButton1.addActionListener(new ActionListener() {
257
258                                @Override
259                                public void actionPerformed(ActionEvent e) {
260                                        returnValue = 0;
261
262                                        dispose();
263                                }
264                        });
265                        jButton2 = new JButton("Database");
266                        jButton2.addActionListener(new ActionListener() {
267
268                                @Override
269                                public void actionPerformed(ActionEvent e) {
270                                        returnValue = 1;
271
272                                        dispose();
273                                }
274                        });
275                        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
276                        GroupLayout layout = new GroupLayout(getContentPane());
277                        getContentPane().setLayout(layout);
278                        layout.setHorizontalGroup(layout
279                                        .createParallelGroup(GroupLayout.Alignment.LEADING)
280                                        .addGroup(
281                                                        layout.createSequentialGroup()
282                                                                        .addGap(35, 35, 35)
283                                                                        .addGroup(
284                                                                                        layout.createParallelGroup(
285                                                                                                        GroupLayout.Alignment.LEADING,
286                                                                                                        false)
287                                                                                                        .addGroup(
288                                                                                                                        layout.createSequentialGroup()
289                                                                                                                                        .addComponent(
290                                                                                                                                                        jButton1)
291                                                                                                                                        .addPreferredGap(
292                                                                                                                                                        ComponentPlacement.RELATED,
293                                                                                                                                                        GroupLayout.DEFAULT_SIZE,
294                                                                                                                                                        Short.MAX_VALUE)
295                                                                                                                                        .addComponent(
296                                                                                                                                                        jButton2))
297                                                                                                        .addComponent(jLabel1))
298                                                                        .addContainerGap(51, Short.MAX_VALUE)));
299                        layout.setVerticalGroup(layout.createParallelGroup(
300                                        Alignment.LEADING).addGroup(
301                                        layout.createSequentialGroup()
302                                                        .addGap(28, 28, 28)
303                                                        .addComponent(jLabel1)
304                                                        .addPreferredGap(ComponentPlacement.RELATED, 55,
305                                                                        Short.MAX_VALUE)
306                                                        .addGroup(
307                                                                        layout.createParallelGroup(
308                                                                                        Alignment.BASELINE)
309                                                                                        .addComponent(jButton1)
310                                                                                        .addComponent(jButton2))
311                                                        .addGap(22, 22, 22)));
312                        pack();
313
314                }
315        }
316}