- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPinDialog.java
More file actions
Latest commit
135 lines (112 loc) · 6.19 KB
/
Copy pathPinDialog.java
File metadata and controls
135 lines (112 loc) · 6.19 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
/*
* PinDialog.java — Modal PIN entry dialog shown before the request flow.
*
* Verifies the entered PIN against the stored SHA-256 hash via Start.verifyPin().
* After setVisible(true) returns, callers check dialog.verified to decide whether
* to proceed.
*
* Mirrors Python PinDialog(tk.Toplevel).
*/
importjava.awt.Color;
importjava.awt.Component;
importjava.awt.Dimension;
importjava.awt.FlowLayout;
importjava.awt.Font;
importjavax.swing.BorderFactory;
importjavax.swing.Box;
importjavax.swing.BoxLayout;
importjavax.swing.JButton;
importjavax.swing.JDialog;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
importjavax.swing.JPasswordField;
importjavax.swing.SwingUtilities;
publicclassPinDialogextendsJDialog {
// ── Result flag — read by caller after dialog closes ─────────────────────
// True only if the correct PIN was entered and confirmed.
publicbooleanverified = false;
// ── Constructor ───────────────────────────────────────────────────────────
PinDialog(JFrameparent) {
super(parent, "Enter Passcode", true); // true = modal — blocks parent
setResizable(false);
getContentPane().setBackground(Start.BG_COLOR);
buildUI();
pack();
setLocationRelativeTo(parent); // Centre over the launcher window
}
// ── UI construction ───────────────────────────────────────────────────────
privatevoidbuildUI() {
JPanelpanel = newJPanel();
panel.setLayout(newBoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBackground(Start.BG_COLOR);
panel.setBorder(BorderFactory.createEmptyBorder(24, 30, 20, 30));
// ── Heading ───────────────────────────────────────────────────────────
JLabelheading = newJLabel("🔒 Enter Passcode to Request a Game");
heading.setFont(newFont("Georgia", Font.BOLD, 14));
heading.setForeground(Start.TEXT_COLOR);
heading.setAlignmentX(Component.CENTER_ALIGNMENT);
panel.add(heading);
panel.add(Box.createVerticalStrut(6));
// ── Sub-label ─────────────────────────────────────────────────────────
JLabelsub = newJLabel("Ask a parent if you don't know the Passcode.");
sub.setFont(Start.FONT_SMALL);
sub.setForeground(Start.SUBTEXT_COLOR);
sub.setAlignmentX(Component.CENTER_ALIGNMENT);
panel.add(sub);
panel.add(Box.createVerticalStrut(14));
// ── PIN field — masked with ● ─────────────────────────────────────────
// JPasswordField handles secure char[] storage; getPassword() preferred over getText()
JPasswordFieldpinField = newJPasswordField(12);
pinField.setFont(newFont("Georgia", Font.PLAIN, 18));
pinField.setBackground(Color.decode("#252540"));
pinField.setForeground(Start.TEXT_COLOR);
pinField.setCaretColor(Start.TEXT_COLOR);
pinField.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
pinField.setEchoChar('●'); // Mask characters — mirrors Python show="●"
pinField.setAlignmentX(Component.CENTER_ALIGNMENT);
pinField.setMaximumSize(newDimension(200, 44));
panel.add(pinField);
panel.add(Box.createVerticalStrut(6));
// ── Error label — hidden until a wrong PIN is entered ─────────────────
JLabelerrorLbl = newJLabel(" "); // Non-empty to reserve layout space
errorLbl.setFont(Start.FONT_SMALL);
errorLbl.setForeground(Start.ACCENT_COLOR);
errorLbl.setAlignmentX(Component.CENTER_ALIGNMENT);
panel.add(errorLbl);
panel.add(Box.createVerticalStrut(12));
// ── Buttons ───────────────────────────────────────────────────────────
JPanelbtnRow = newJPanel(newFlowLayout(FlowLayout.CENTER, 8, 0));
btnRow.setBackground(Start.BG_COLOR);
JButtonconfirmBtn = Start.makeButton("Confirm", Start.REQUEST_COLOR);
JButtoncancelBtn = Start.makeButton("Cancel", Color.decode("#333333"));
btnRow.add(confirmBtn);
btnRow.add(cancelBtn);
panel.add(btnRow);
add(panel);
// ── Event handling ────────────────────────────────────────────────────
// Shared submit logic — used by both the button and the Enter key binding
RunnableonSubmit = () -> {
Stringpin = newString(pinField.getPassword()).strip();
if (pin.isEmpty()) {
errorLbl.setText("⚠️ Please enter a PIN.");
return;
}
if (Start.verifyPin(pin)) {
verified = true; // Correct — signal success to the caller
dispose(); // Close dialog; setVisible() returns to caller
} else {
// Wrong PIN — clear field and let the child try again
pinField.setText("");
errorLbl.setText("❌ Incorrect PIN. Try again.");
pinField.requestFocus();
}
};
confirmBtn.addActionListener(e -> onSubmit.run());
cancelBtn.addActionListener(e -> dispose()); // Cancel leaves verified=false
// Enter key submits — mirrors Python self.bind("<Return>", ...)
pinField.addActionListener(e -> onSubmit.run());
// Auto-focus the PIN field when the dialog appears
SwingUtilities.invokeLater(pinField::requestFocusInWindow);
}
}