-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainGUI.java
More file actions
517 lines (442 loc) · 22 KB
/
Copy pathMainGUI.java
File metadata and controls
517 lines (442 loc) · 22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
public class MainGUI extends JFrame {
private JTable fileTable, reminderTable;
private DefaultTableModel fileModel, reminderModel;
private JLabel statusLabel;
public MainGUI() {
setTitle("📁 Desktop Automation & Task Manager");
setSize(1000, 650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// Start reminder checker
new ReminderManager().startReminderChecker();
// Create main container
JPanel mainPanel = new JPanel(new BorderLayout());
// Create tabs with better colors
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("📁 File Organizer", createOrganizerPanel());
tabs.addTab("⏰ Reminders", createReminderPanel());
tabs.addTab("📊 View Logs", createLogsPanel());
// Status bar at bottom
statusLabel = new JLabel("✅ Ready | MySQL Connected");
statusLabel.setBorder(BorderFactory.createEtchedBorder());
statusLabel.setFont(new Font("Arial", Font.PLAIN, 11));
statusLabel.setForeground(new Color(0, 100, 0));
statusLabel.setBackground(new Color(240, 255, 240));
statusLabel.setOpaque(true);
mainPanel.add(tabs, BorderLayout.CENTER);
mainPanel.add(statusLabel, BorderLayout.SOUTH);
add(mainPanel);
// Load initial data
loadFileLogs();
loadReminders();
setVisible(true);
}
private JPanel createOrganizerPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
panel.setBackground(new Color(245, 245, 250));
// Button Panel with two buttons
JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 20, 20));
buttonPanel.setBackground(new Color(245, 245, 250));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50));
// Organize Button - GREEN background with BLACK text
JButton organizeBtn = new JButton("📁 ORGANIZE DESKTOP NOW");
organizeBtn.setFont(new Font("Arial", Font.BOLD, 22));
organizeBtn.setBackground(new Color(40, 200, 40)); // Bright Green
organizeBtn.setForeground(Color.BLACK); // Black text
organizeBtn.setFocusPainted(false);
organizeBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
organizeBtn.setBorder(BorderFactory.createLineBorder(new Color(0, 100, 0), 2));
organizeBtn.setOpaque(true);
organizeBtn.addActionListener(e -> {
statusLabel.setText("⏳ Organizing files...");
SwingUtilities.invokeLater(() -> {
FileOrganizer.organizeDesktop();
loadFileLogs();
statusLabel.setText("✅ Desktop organized successfully!");
});
});
// Undo Button - RED background with WHITE text
JButton undoBtn = new JButton("↩️ UNDO LAST ORGANIZATION");
undoBtn.setFont(new Font("Arial", Font.BOLD, 20));
undoBtn.setBackground(new Color(220, 60, 60)); // Bright Red
undoBtn.setForeground(Color.WHITE); // White text
undoBtn.setFocusPainted(false);
undoBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
undoBtn.setBorder(BorderFactory.createLineBorder(new Color(100, 0, 0), 2));
undoBtn.setOpaque(true);
undoBtn.addActionListener(e -> {
int confirm = JOptionPane.showConfirmDialog(this,
"⚠️ This will move the last 20 files back to their original locations.\n\n" +
"This action CANNOT be undone. Continue?",
"Confirm Undo",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
if (confirm == JOptionPane.YES_OPTION) {
statusLabel.setText("⏳ Undoing last organization...");
SwingUtilities.invokeLater(() -> {
FileOrganizer.undoLastOrganization();
loadFileLogs();
statusLabel.setText("✅ Undo completed successfully!");
});
}
});
buttonPanel.add(organizeBtn);
buttonPanel.add(undoBtn);
// Info Panel with better visibility
JPanel infoPanel = new JPanel(new BorderLayout());
infoPanel.setBackground(new Color(255, 255, 255));
infoPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(new Color(0, 150, 0), 2),
BorderFactory.createEmptyBorder(20, 20, 20, 20)
));
JLabel titleLabel = new JLabel("📁 Desktop File Organizer", SwingConstants.CENTER);
titleLabel.setFont(new Font("Arial", Font.BOLD, 26));
titleLabel.setForeground(new Color(0, 100, 0));
JLabel infoLabel = new JLabel("<html><center>" +
"<p style='font-size:14px; color:#333333;'>📌 Click <b style='color:#006400;'>ORGANIZE</b> to automatically sort files into folders:</p>" +
"<p style='font-size:16px; color:#006400;'>🖼️ Images | 📄 Documents | 🎬 Videos | 🎵 Music | ⚙️ Installers | 🗜️ Archives</p>" +
"<br>" +
"<p style='font-size:13px; color:#CC0000;'><b>↩️ UNDO</b> - Restores the last 20 moved files to their original locations</p>" +
"<p style='font-size:12px; color:#666666;'><i>📋 All actions are logged to MySQL database via JDBC</i></p>" +
"</center></html>");
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
infoPanel.add(titleLabel, BorderLayout.NORTH);
infoPanel.add(infoLabel, BorderLayout.CENTER);
panel.add(infoPanel, BorderLayout.NORTH);
panel.add(buttonPanel, BorderLayout.CENTER);
return panel;
}
private JPanel createReminderPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
panel.setBackground(new Color(245, 245, 250));
// Form Panel
JPanel formPanel = new JPanel(new GridBagLayout());
formPanel.setBackground(Color.WHITE);
formPanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(new Color(70, 130, 200), 2),
"➕ Add New Reminder",
TitledBorder.LEFT,
TitledBorder.TOP,
new Font("Arial", Font.BOLD, 14),
new Color(70, 130, 200)
));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
// Title field
gbc.gridx = 0; gbc.gridy = 0;
gbc.weightx = 0.2;
JLabel titleLabel = new JLabel("📝 Title:");
titleLabel.setFont(new Font("Arial", Font.BOLD, 13));
formPanel.add(titleLabel, gbc);
gbc.gridx = 1; gbc.gridy = 0;
gbc.weightx = 0.8;
JTextField titleField = new JTextField();
titleField.setFont(new Font("Arial", Font.PLAIN, 14));
titleField.setBackground(new Color(255, 255, 220));
formPanel.add(titleField, gbc);
// Date & Time field
gbc.gridx = 0; gbc.gridy = 1;
gbc.weightx = 0.2;
JLabel dateLabel = new JLabel("📅 Date & Time:");
dateLabel.setFont(new Font("Arial", Font.BOLD, 13));
formPanel.add(dateLabel, gbc);
gbc.gridx = 1; gbc.gridy = 1;
gbc.weightx = 0.8;
JTextField dateField = new JTextField();
dateField.setFont(new Font("Arial", Font.PLAIN, 14));
dateField.setBackground(new Color(255, 255, 220));
dateField.setToolTipText("Format: YYYY-MM-DD HH:MM:SS");
formPanel.add(dateField, gbc);
// Example label
gbc.gridx = 1; gbc.gridy = 2;
JLabel exampleLabel = new JLabel("Example: 2026-04-08 15:30:00");
exampleLabel.setFont(new Font("Arial", Font.ITALIC, 11));
exampleLabel.setForeground(new Color(100, 100, 100));
formPanel.add(exampleLabel, gbc);
// Message field
gbc.gridx = 0; gbc.gridy = 3;
gbc.weightx = 0.2;
gbc.anchor = GridBagConstraints.NORTH;
JLabel msgLabel = new JLabel("💬 Message:");
msgLabel.setFont(new Font("Arial", Font.BOLD, 13));
formPanel.add(msgLabel, gbc);
gbc.gridx = 1; gbc.gridy = 3;
gbc.weightx = 0.8;
gbc.fill = GridBagConstraints.BOTH;
JTextArea msgArea = new JTextArea(4, 30);
msgArea.setFont(new Font("Arial", Font.PLAIN, 14));
msgArea.setBackground(new Color(255, 255, 220));
msgArea.setLineWrap(true);
msgArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(msgArea);
formPanel.add(scrollPane, gbc);
// Add Reminder Button
gbc.gridx = 1; gbc.gridy = 4;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
JButton addBtn = new JButton("✅ ADD REMINDER");
addBtn.setFont(new Font("Arial", Font.BOLD, 16));
addBtn.setBackground(new Color(70, 130, 200));
addBtn.setForeground(Color.WHITE);
addBtn.setFocusPainted(false);
addBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
addBtn.setPreferredSize(new Dimension(250, 45));
addBtn.setOpaque(true);
addBtn.addActionListener(e -> {
String title = titleField.getText().trim();
String datetime = dateField.getText().trim();
String message = msgArea.getText().trim();
if(title.isEmpty() || datetime.isEmpty()) {
JOptionPane.showMessageDialog(this,
"❌ Please fill Title and Date & Time!",
"Missing Fields",
JOptionPane.WARNING_MESSAGE);
return;
}
if(message.isEmpty()) {
message = "No message provided";
}
if(!datetime.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
JOptionPane.showMessageDialog(this,
"❌ Invalid datetime format!\nUse: YYYY-MM-DD HH:MM:SS",
"Format Error",
JOptionPane.ERROR_MESSAGE);
return;
}
ReminderManager.addReminder(title, datetime, message);
titleField.setText("");
dateField.setText("");
msgArea.setText("");
loadReminders();
statusLabel.setText("✅ Reminder added successfully!");
});
formPanel.add(addBtn, gbc);
// Quick Reminder Examples
JPanel quickPanel = new JPanel();
quickPanel.setBackground(new Color(245, 245, 250));
quickPanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(new Color(150, 150, 150)),
"⏩ Quick Examples"
));
quickPanel.setLayout(new FlowLayout());
String[] examples = {"Tomorrow 9:00 AM", "Lunch Time", "Meeting", "Call Mom"};
for(String ex : examples) {
JButton exBtn = new JButton(ex);
exBtn.setFont(new Font("Arial", Font.PLAIN, 12));
exBtn.setBackground(new Color(200, 220, 240));
exBtn.setForeground(Color.BLACK);
exBtn.setFocusPainted(false);
exBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
exBtn.addActionListener(e -> {
JOptionPane.showMessageDialog(this,
"Example: Set datetime to current time + 5 minutes\n" +
"Format: " + getCurrentTimePlusMinutes(5),
"Quick Tip",
JOptionPane.INFORMATION_MESSAGE);
});
quickPanel.add(exBtn);
}
panel.add(formPanel, BorderLayout.NORTH);
panel.add(quickPanel, BorderLayout.CENTER);
return panel;
}
private String getCurrentTimePlusMinutes(int minutes) {
java.time.LocalDateTime now = java.time.LocalDateTime.now();
java.time.LocalDateTime future = now.plusMinutes(minutes);
return future.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
private JPanel createLogsPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.setBackground(new Color(245, 245, 250));
JTabbedPane logsTabs = new JTabbedPane();
// File logs table with enhanced columns
fileModel = new DefaultTableModel(new String[]{"ID", "File Name", "Type", "Destination", "Status", "Action"}, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return column == 5;
}
};
fileTable = new JTable(fileModel);
fileTable.setRowHeight(28);
fileTable.setFont(new Font("Arial", Font.PLAIN, 12));
fileTable.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
fileTable.getColumnModel().getColumn(0).setPreferredWidth(50);
fileTable.getColumnModel().getColumn(1).setPreferredWidth(200);
fileTable.getColumnModel().getColumn(2).setPreferredWidth(80);
fileTable.getColumnModel().getColumn(3).setPreferredWidth(300);
fileTable.getColumnModel().getColumn(4).setPreferredWidth(80);
fileTable.getColumnModel().getColumn(5).setPreferredWidth(80);
// Add mouse listener for undo button in table
fileTable.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
int column = fileTable.getColumnModel().getColumnIndexAtX(e.getX());
int row = e.getY() / fileTable.getRowHeight();
if (row < fileTable.getRowCount() && row >= 0 && column == 5) {
String action = (String) fileTable.getValueAt(row, 5);
if ("↩️ Undo".equals(action)) {
int actionId = (int) fileTable.getValueAt(row, 0);
String sourcePath = getSourcePathById(actionId);
String destPath = (String) fileTable.getValueAt(row, 3);
int confirm = JOptionPane.showConfirmDialog(MainGUI.this,
"Restore this file to its original location?",
"Confirm Undo",
JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
FileOrganizer.undoFileById(actionId, sourcePath, destPath);
loadFileLogs();
statusLabel.setText("✅ File restored successfully!");
}
}
}
}
});
logsTabs.addTab("📁 File Actions", new JScrollPane(fileTable));
// Reminders table with enhanced columns
reminderModel = new DefaultTableModel(new String[]{"ID", "Title", "Date & Time", "Message", "Status"}, 0);
reminderTable = new JTable(reminderModel);
reminderTable.setRowHeight(28);
reminderTable.setFont(new Font("Arial", Font.PLAIN, 12));
reminderTable.getTableHeader().setFont(new Font("Arial", Font.BOLD, 12));
reminderTable.getColumnModel().getColumn(0).setPreferredWidth(50);
reminderTable.getColumnModel().getColumn(1).setPreferredWidth(150);
reminderTable.getColumnModel().getColumn(2).setPreferredWidth(150);
reminderTable.getColumnModel().getColumn(3).setPreferredWidth(300);
reminderTable.getColumnModel().getColumn(4).setPreferredWidth(80);
logsTabs.addTab("⏰ Reminders", new JScrollPane(reminderTable));
// Stats Panel
JPanel statsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
statsPanel.setBackground(new Color(240, 240, 245));
statsPanel.setBorder(BorderFactory.createEtchedBorder());
JLabel statsLabel = new JLabel();
updateStatsLabel(statsLabel);
statsPanel.add(statsLabel);
// Button Panel
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.setBackground(new Color(240, 240, 245));
JButton refreshBtn = new JButton("🔄 Refresh All");
refreshBtn.setBackground(new Color(100, 100, 100));
refreshBtn.setForeground(Color.WHITE);
refreshBtn.setFocusPainted(false);
refreshBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
refreshBtn.setFont(new Font("Arial", Font.BOLD, 12));
refreshBtn.addActionListener(e -> {
loadFileLogs();
loadReminders();
updateStatsLabel(statsLabel);
statusLabel.setText("✅ Logs refreshed!");
});
JButton exportBtn = new JButton("📎 Export Logs");
exportBtn.setBackground(new Color(0, 150, 100));
exportBtn.setForeground(Color.WHITE);
exportBtn.setFocusPainted(false);
exportBtn.setCursor(new Cursor(Cursor.HAND_CURSOR));
exportBtn.setFont(new Font("Arial", Font.BOLD, 12));
exportBtn.addActionListener(e -> {
JOptionPane.showMessageDialog(this,
"Export feature coming soon!\nWill export to CSV format.",
"Coming Soon",
JOptionPane.INFORMATION_MESSAGE);
});
buttonPanel.add(refreshBtn);
buttonPanel.add(exportBtn);
JPanel bottomPanel = new JPanel(new BorderLayout());
bottomPanel.setBackground(new Color(240, 240, 245));
bottomPanel.add(statsPanel, BorderLayout.WEST);
bottomPanel.add(buttonPanel, BorderLayout.EAST);
panel.add(logsTabs, BorderLayout.CENTER);
panel.add(bottomPanel, BorderLayout.SOUTH);
return panel;
}
private String getSourcePathById(int actionId) {
String sql = "SELECT source_path FROM file_actions WHERE action_id = ?";
try (Connection conn = DatabaseConnection.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, actionId);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
return rs.getString("source_path");
}
} catch (SQLException e) {
e.printStackTrace();
}
return "";
}
private void updateStatsLabel(JLabel label) {
try (Connection conn = DatabaseConnection.getConnection();
Statement stmt = conn.createStatement()) {
ResultSet rs1 = stmt.executeQuery("SELECT COUNT(*) FROM file_actions WHERE is_undone = FALSE");
rs1.next();
int activeMoves = rs1.getInt(1);
ResultSet rs2 = stmt.executeQuery("SELECT COUNT(*) FROM reminders WHERE is_completed = FALSE");
rs2.next();
int pendingReminders = rs2.getInt(1);
label.setText("📊 Stats: " + activeMoves + " active file moves | " + pendingReminders + " pending reminders");
label.setFont(new Font("Arial", Font.PLAIN, 12));
label.setForeground(new Color(0, 80, 0));
} catch (SQLException e) {
label.setText("📊 Stats: Unable to load");
}
}
private void loadFileLogs() {
fileModel.setRowCount(0);
String sql = "SELECT action_id, file_name, file_type, dest_path, is_undone FROM file_actions ORDER BY action_id DESC";
try (Connection conn = DatabaseConnection.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
boolean isUndone = rs.getBoolean("is_undone");
String status = isUndone ? "✅ Undone" : "📁 Active";
String action = isUndone ? "✔️ Done" : "↩️ Undo";
fileModel.addRow(new Object[]{
rs.getInt("action_id"),
rs.getString("file_name"),
rs.getString("file_type"),
rs.getString("dest_path"),
status,
action
});
}
} catch (Exception e) {
System.out.println("Error loading file logs: " + e.getMessage());
}
}
private void loadReminders() {
reminderModel.setRowCount(0);
String sql = "SELECT reminder_id, title, reminder_datetime, message, is_completed FROM reminders ORDER BY reminder_id DESC";
try (Connection conn = DatabaseConnection.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
boolean isCompleted = rs.getBoolean("is_completed");
String status = isCompleted ? "✅ Completed" : "⏰ Pending";
reminderModel.addRow(new Object[]{
rs.getInt("reminder_id"),
rs.getString("title"),
rs.getString("reminder_datetime"),
rs.getString("message"),
status
});
}
} catch (Exception e) {
System.out.println("Error loading reminders: " + e.getMessage());
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(() -> new MainGUI());
}
}