Skip to content

Commit ece49ec

Browse files
committed
try to add a dynamic java scanner request
1 parent 9ecac64 commit ece49ec

File tree

8 files changed

+1059
-64
lines changed

8 files changed

+1059
-64
lines changed

assets/css/terminal.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,23 @@
152152
z-index: 9999;
153153
color: #fff;
154154
box-shadow: 0 0 16px #ff5555cc;
155+
border: 2px solid #ff5555;
155156
}
156157

157158
.java-input-prompt {
158159
margin-bottom: 12px;
160+
font-family: 'Fira Mono', monospace;
161+
color: #ff7777;
159162
}
160163

161164
.java-input-field {
162165
width: 220px;
163166
padding: 8px;
164167
font-size: 1em;
168+
background: #333;
169+
color: #fff;
170+
border: 1px solid #ff5555;
171+
border-radius: 4px;
165172
}
166173

167174
.java-input-btn {
@@ -172,6 +179,7 @@
172179
color: white;
173180
border-radius: 4px;
174181
cursor: pointer;
182+
font-weight: bold;
175183
}
176184

177185
/* Terminal Menu Enhancements */
@@ -245,3 +253,15 @@
245253
content: '';
246254
}
247255
}
256+
257+
/* Input indicator for Java terminal */
258+
.input-indicator {
259+
display: inline-block;
260+
color: #ff9999;
261+
font-weight: bold;
262+
animation: blink 1s step-end infinite;
263+
}
264+
265+
@keyframes blink {
266+
50% { opacity: 0; }
267+
}

assets/js/jvm-streams.js

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// assets/js/jvm-streams.js
2+
// Handles Java VM standard input/output interception
3+
4+
/**
5+
* JavaStreamManager - Manages Java standard input/output streams
6+
*
7+
* This class creates a virtual implementation of Java's standard I/O streams
8+
* to allow web applications to interact with Java programs that use
9+
* System.in, System.out, and Scanner for console I/O.
10+
*/
11+
class JavaStreamManager {
12+
constructor() {
13+
// Stream buffers
14+
this.stdout = ""; // Output buffer
15+
this.stderr = ""; // Error buffer
16+
17+
// Event listeners
18+
this.inputListeners = []; // Listeners for input requests
19+
this.outputListeners = []; // Listeners for output events
20+
this.errorListeners = []; // Listeners for error events
21+
22+
// Input request state
23+
this.inputRequested = false;
24+
this.inputResolver = null;
25+
this.inputPrompt = "";
26+
27+
// Flags
28+
this.isInitialized = false;
29+
}
30+
31+
/**
32+
* Initialize the stream manager and register event handlers
33+
* @param {Object} options Configuration options
34+
*/
35+
initialize(options = {}) {
36+
if (this.isInitialized) return this;
37+
38+
// Register event handlers if provided
39+
if (options.onInputRequest && typeof options.onInputRequest === 'function') {
40+
this.addInputListener(options.onInputRequest);
41+
}
42+
43+
if (options.onOutput && typeof options.onOutput === 'function') {
44+
this.addOutputListener(options.onOutput);
45+
}
46+
47+
if (options.onError && typeof options.onError === 'function') {
48+
this.addErrorListener(options.onError);
49+
}
50+
51+
this.isInitialized = true;
52+
return this;
53+
}
54+
55+
/**
56+
* Add a listener for input requests (when Java code needs user input)
57+
* @param {Function} listener Callback function that handles input requests
58+
*/
59+
addInputListener(listener) {
60+
if (typeof listener === 'function') {
61+
this.inputListeners.push(listener);
62+
}
63+
return this;
64+
}
65+
66+
/**
67+
* Add a listener for output events (when Java code writes to stdout)
68+
* @param {Function} listener Callback function that handles output
69+
*/
70+
addOutputListener(listener) {
71+
if (typeof listener === 'function') {
72+
this.outputListeners.push(listener);
73+
}
74+
return this;
75+
}
76+
77+
/**
78+
* Add a listener for error events (when Java code writes to stderr)
79+
* @param {Function} listener Callback function that handles errors
80+
*/
81+
addErrorListener(listener) {
82+
if (typeof listener === 'function') {
83+
this.errorListeners.push(listener);
84+
}
85+
return this;
86+
}
87+
88+
/**
89+
* Write to the standard output stream (simulates System.out.print in Java)
90+
* @param {string} text Text to write to stdout
91+
*/
92+
writeOutput(text) {
93+
this.stdout += text;
94+
95+
// Notify all output listeners
96+
for (const listener of this.outputListeners) {
97+
listener(text);
98+
}
99+
100+
return this;
101+
}
102+
103+
/**
104+
* Write to the error output stream (simulates System.err.print in Java)
105+
* @param {string} text Text to write to stderr
106+
*/
107+
writeError(text) {
108+
this.stderr += text;
109+
110+
// Notify all error listeners
111+
for (const listener of this.errorListeners) {
112+
listener(text);
113+
}
114+
115+
return this;
116+
}
117+
118+
/**
119+
* Request input from the user (simulates Scanner.nextLine() in Java)
120+
* @param {string} prompt Prompt to display to the user
121+
* @returns {Promise<string>} Promise that resolves with user input
122+
*/
123+
requestInput(prompt = "") {
124+
this.inputRequested = true;
125+
this.inputPrompt = prompt;
126+
127+
return new Promise((resolve) => {
128+
this.inputResolver = resolve;
129+
130+
// Notify all input request listeners
131+
const promises = this.inputListeners.map(listener => listener(prompt));
132+
133+
// If we have listeners, use their response
134+
if (promises.length > 0) {
135+
Promise.all(promises)
136+
.then(results => {
137+
// Use the first non-undefined result
138+
const input = results.find(result => result !== undefined);
139+
if (input !== undefined) {
140+
this.inputRequested = false;
141+
this.inputResolver = null;
142+
resolve(input);
143+
}
144+
});
145+
} else if (window.requestJavaInput) {
146+
// Fallback to global requestJavaInput if available
147+
window.requestJavaInput(prompt)
148+
.then(input => {
149+
this.inputRequested = false;
150+
this.inputResolver = null;
151+
resolve(input);
152+
});
153+
} else {
154+
// If no input handlers are available, log an error and return a default
155+
console.error("No input handlers registered and no global requestJavaInput function found");
156+
this.inputRequested = false;
157+
this.inputResolver = null;
158+
resolve("default\n");
159+
}
160+
});
161+
}
162+
163+
/**
164+
* Provide input to resolve a pending input request
165+
* @param {string} input Input text from the user
166+
*/
167+
provideInput(input) {
168+
if (this.inputRequested && this.inputResolver) {
169+
const resolver = this.inputResolver;
170+
this.inputRequested = false;
171+
this.inputResolver = null;
172+
resolver(input);
173+
}
174+
return this;
175+
}
176+
177+
/**
178+
* Get the current contents of the standard output buffer
179+
* @returns {string} Current stdout content
180+
*/
181+
getOutput() {
182+
return this.stdout;
183+
}
184+
185+
/**
186+
* Get the current contents of the error output buffer
187+
* @returns {string} Current stderr content
188+
*/
189+
getError() {
190+
return this.stderr;
191+
}
192+
193+
/**
194+
* Clear all stream buffers
195+
*/
196+
clearBuffers() {
197+
this.stdout = "";
198+
this.stderr = "";
199+
return this;
200+
}
201+
202+
/**
203+
* Reset the stream manager to its initial state
204+
*/
205+
reset() {
206+
this.clearBuffers();
207+
this.inputRequested = false;
208+
this.inputResolver = null;
209+
this.inputPrompt = "";
210+
return this;
211+
}
212+
}
213+
214+
// Create a singleton instance
215+
const javaStreams = new JavaStreamManager();
216+
217+
export { javaStreams };

0 commit comments

Comments
 (0)