-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAttendanceGUI.java
More file actions
314 lines (269 loc) · 12.6 KB
/
Copy pathAttendanceGUI.java
File metadata and controls
314 lines (269 loc) · 12.6 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
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
public class AttendanceGUI extends JFrame {
private JTextField txtTotal;
private JTextField txtAttended;
private JLabel lblPercentage;
private JLabel lblMarks;
private JLabel lblZone;
private JLabel lblCurrentInsight;
private JLabel lblNextInsight;
public AttendanceGUI() {
setTitle("Attendance Optimization Engine - Pro UI");
setSize(850, 550);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null); // Center on screen
// Layer 1: Gradient Background Panel
GradientBackgroundPanel bgPanel = new GradientBackgroundPanel();
bgPanel.setLayout(new GridBagLayout());
setContentPane(bgPanel);
// Layer 2: Main Glass Card Container
GlassCardPanel mainCard = new GlassCardPanel();
mainCard.setLayout(new BorderLayout(20, 20));
mainCard.setBorder(new EmptyBorder(30, 30, 30, 30));
// Title
JLabel title = new JLabel("Optimization Engine", SwingConstants.CENTER);
title.setFont(new Font("SansSerif", Font.BOLD, 32));
title.setForeground(Color.WHITE);
mainCard.add(title, BorderLayout.NORTH);
// Center Content (Inputs on left, Outcomes on right)
JPanel centerPanel = new JPanel(new GridLayout(1, 2, 40, 0));
centerPanel.setOpaque(false);
// Input Section
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
inputPanel.setOpaque(false);
inputPanel.setBorder(new EmptyBorder(20, 0, 0, 0));
JLabel lblTotal = new JLabel("Total Classes Conducted:");
lblTotal.setForeground(new Color(230, 230, 250));
lblTotal.setFont(new Font("SansSerif", Font.BOLD, 15));
txtTotal = createTextField();
JLabel lblAtt = new JLabel("Total Classes Attended:");
lblAtt.setForeground(new Color(230, 230, 250));
lblAtt.setFont(new Font("SansSerif", Font.BOLD, 15));
txtAttended = createTextField();
inputPanel.add(lblTotal);
inputPanel.add(Box.createVerticalStrut(10));
inputPanel.add(txtTotal);
inputPanel.add(Box.createVerticalStrut(30));
inputPanel.add(lblAtt);
inputPanel.add(Box.createVerticalStrut(10));
inputPanel.add(txtAttended);
// Output Section
JPanel outputPanel = new JPanel();
outputPanel.setLayout(new BoxLayout(outputPanel, BoxLayout.Y_AXIS));
outputPanel.setOpaque(false);
outputPanel.setBorder(new EmptyBorder(20, 0, 0, 0));
lblPercentage = createOutputLabel("Percentage: --");
lblPercentage.setFont(new Font("SansSerif", Font.BOLD, 22));
lblMarks = createOutputLabel("Marks: --");
lblZone = createOutputLabel("Status: --");
outputPanel.add(lblPercentage);
outputPanel.add(Box.createVerticalStrut(20));
outputPanel.add(lblMarks);
outputPanel.add(Box.createVerticalStrut(20));
outputPanel.add(lblZone);
centerPanel.add(inputPanel);
centerPanel.add(outputPanel);
mainCard.add(centerPanel, BorderLayout.CENTER);
// Insights Section (Bottom)
JPanel insightsPanel = new JPanel(new GridLayout(2, 1, 5, 5));
insightsPanel.setOpaque(false);
insightsPanel.setBorder(new EmptyBorder(20, 0, 0, 0));
lblCurrentInsight = new JLabel("Safety Buffer: --");
lblCurrentInsight.setForeground(Color.WHITE);
lblCurrentInsight.setFont(new Font("SansSerif", Font.PLAIN, 15));
lblNextInsight = new JLabel("Next Goal: --");
lblNextInsight.setForeground(Color.WHITE);
lblNextInsight.setFont(new Font("SansSerif", Font.PLAIN, 15));
insightsPanel.add(lblCurrentInsight);
insightsPanel.add(lblNextInsight);
mainCard.add(insightsPanel, BorderLayout.SOUTH);
bgPanel.add(mainCard);
setupListeners();
}
private JLabel createOutputLabel(String text) {
JLabel lbl = new JLabel(text);
lbl.setForeground(Color.WHITE);
lbl.setFont(new Font("SansSerif", Font.BOLD, 18));
return lbl;
}
private JTextField createTextField() {
JTextField tf = new JTextField();
tf.setFont(new Font("SansSerif", Font.BOLD, 20));
tf.setOpaque(false); // Translucent text box
tf.setForeground(Color.WHITE);
tf.setCaretColor(Color.WHITE);
tf.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(new Color(255, 255, 255, 100), 2, true),
BorderFactory.createEmptyBorder(5, 10, 5, 10)
));
tf.setMaximumSize(new Dimension(Integer.MAX_VALUE, 40));
return tf;
}
private void setupListeners() {
DocumentListener dl = new DocumentListener() {
public void insertUpdate(DocumentEvent e) { calculate(); }
public void removeUpdate(DocumentEvent e) { calculate(); }
public void changedUpdate(DocumentEvent e) { calculate(); }
};
txtTotal.getDocument().addDocumentListener(dl);
txtAttended.getDocument().addDocumentListener(dl);
}
private void calculate() {
try {
int total = Integer.parseInt(txtTotal.getText().trim());
int attended = Integer.parseInt(txtAttended.getText().trim());
if (total <= 0 || attended < 0 || attended > total) {
resetOutputs();
return;
}
double percentage = AttendanceLogic.calculatePercentage(total, attended);
int marks = AttendanceLogic.calculateMarks(percentage);
String zone = AttendanceLogic.determineZone(percentage);
lblPercentage.setText(String.format("Percentage: %.2f%%", percentage));
lblMarks.setText("Marks Details: " + marks + " Marks Secured");
lblZone.setText("Current Status: " + zone);
if (zone.equals("Defaulter Zone")) {
lblZone.setForeground(new Color(255, 120, 120)); // Soft Red
int neededFor75 = AttendanceLogic.calculateRecovery(total, attended, 75.0);
lblCurrentInsight.setText(String.format("Recovery: Need %d consecutive classes to reach 75%% (Safe).", neededFor75));
} else {
if (zone.equals("Safe Zone")) {
lblZone.setForeground(new Color(120, 255, 120)); // Soft Green
} else {
lblZone.setForeground(new Color(255, 210, 100)); // Warm Orange
}
double currentTarget = AttendanceLogic.getCurrentTarget(percentage);
int safeLeaves = AttendanceLogic.calculateLeaves(total, attended, currentTarget);
lblCurrentInsight.setText(String.format("Safety Buffer: Can miss %d upcoming classes without dropping below %d marks.", safeLeaves, marks));
}
double nextTarget = AttendanceLogic.getNextTarget(percentage);
if (nextTarget > 0) {
int targetMarks = AttendanceLogic.calculateMarks(nextTarget);
int neededForNext = AttendanceLogic.calculateRecovery(total, attended, nextTarget);
lblNextInsight.setText(String.format("Next Goal: Attend %d more consecutive classes to reach %.0f%% (%d marks).", neededForNext, nextTarget, targetMarks));
} else {
lblNextInsight.setText("Next Goal: You are already in the maximum marks bracket!");
}
} catch (NumberFormatException ex) {
resetOutputs();
}
}
private void resetOutputs() {
lblPercentage.setText("Percentage: --");
lblMarks.setText("Marks: --");
lblZone.setText("Status: --");
lblZone.setForeground(Color.WHITE);
lblCurrentInsight.setText("Safety Buffer: --");
lblNextInsight.setText("Next Goal: --");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
new AttendanceGUI().setVisible(true);
});
}
// --- GLASSMORPHISM COMPONENTS ---
class GradientBackgroundPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Diagonal primary mesh background
GradientPaint gp = new GradientPaint(
0, 0, new Color(43, 88, 118),
getWidth(), getHeight(), new Color(78, 67, 118));
g2d.setPaint(gp);
g2d.fillRect(0, 0, getWidth(), getHeight());
// Bright glowing orb Top Right
RadialGradientPaint rgp1 = new RadialGradientPaint(
getWidth() * 0.85f, getHeight() * 0.15f, getWidth() * 0.5f,
new float[]{0f, 1f}, new Color[]{new Color(255, 117, 140, 180), new Color(255, 117, 140, 0)});
g2d.setPaint(rgp1);
g2d.fillRect(0, 0, getWidth(), getHeight());
// Cyan glowing orb Bottom Left
RadialGradientPaint rgp2 = new RadialGradientPaint(
getWidth() * 0.15f, getHeight() * 0.85f, getWidth() * 0.5f,
new float[]{0f, 1f}, new Color[]{new Color(55, 236, 186, 140), new Color(55, 236, 186, 0)});
g2d.setPaint(rgp2);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
}
}
class GlassCardPanel extends JPanel {
public GlassCardPanel() {
setOpaque(false);
setPreferredSize(new Dimension(700, 420));
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Translucent white foreground panel (Frosted Glass simulation)
g2d.setColor(new Color(255, 255, 255, 30));
g2d.fill(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 40, 40));
// Semi-transparent border outline for the "glass edge" specular highlight
g2d.setColor(new Color(255, 255, 255, 90));
g2d.setStroke(new BasicStroke(1.5f));
g2d.draw(new RoundRectangle2D.Double(1, 1, getWidth() - 2, getHeight() - 2, 40, 40));
g2d.dispose();
super.paintComponent(g);
}
}
}
class AttendanceLogic {
public static double calculatePercentage(int total, int attended) {
if (total == 0) return 0.0;
return ((double) attended / total) * 100.0;
}
public static int calculateMarks(double percentage) {
if (percentage >= 95.0) return 5;
if (percentage >= 90.0) return 4;
if (percentage >= 85.0) return 3;
if (percentage >= 80.0) return 2;
if (percentage >= 75.0) return 1;
return 0; // Defaulter
}
public static String determineZone(double percentage) {
if (percentage < 75.0) return "Defaulter Zone";
if (percentage < 80.0) return "Risk Zone";
return "Safe Zone";
}
public static double getCurrentTarget(double percentage) {
if (percentage >= 95.0) return 95.0;
if (percentage >= 90.0) return 90.0;
if (percentage >= 85.0) return 85.0;
if (percentage >= 80.0) return 80.0;
if (percentage >= 75.0) return 75.0;
return 0.0;
}
public static double getNextTarget(double percentage) {
if (percentage < 75.0) return 75.0;
if (percentage < 80.0) return 80.0;
if (percentage < 85.0) return 85.0;
if (percentage < 90.0) return 90.0;
if (percentage < 95.0) return 95.0;
return -1.0;
}
public static int calculateLeaves(int total, int attended, double target) {
if (target == 0.0) return 0;
double l = (100.0 * attended / target) - total;
return (int) Math.floor(l);
}
public static int calculateRecovery(int total, int attended, double target) {
if (target >= 100.0) return -1;
double r = ((target * total) - (100.0 * attended)) / (100.0 - target);
if (r < 0) return 0;
return (int) Math.ceil(r);
}
}