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}