Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>JavaRunner — Learn & Run Java Online</title> | |
| <meta name="description" content="JavaRunner is a mobile-friendly online Java IDE. Write, run, save, and download Java code. Perfect for beginners like Ragini Didi."> | |
| <meta name="keywords" content="Java IDE, Online Java compiler, JavaRunner, Learn Java, Java code editor, mobile-friendly IDE, Ragini Didi"> | |
| <meta name="author" content="Saksham Pathak"> | |
| <meta name="robots" content="index, follow"> | |
| <!-- Open Graph for SEO & social --> | |
| <meta property="og:title" content="JavaRunner — Learn & Run Java Online"> | |
| <meta property="og:description" content="JavaRunner is a mobile-friendly online Java IDE. Write, run, save, and download Java code. Perfect for beginners like Ragini Didi."> | |
| <meta property="og:type" content="website"> | |
| <!-- Font --> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet"> | |
| <!-- Font Awesome --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> | |
| <!-- CodeMirror --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.css"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/clike/clike.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/edit/closebrackets.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/edit/matchbrackets.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/edit/indentation.min.js"></script> | |
| <style> | |
| :root { | |
| --bg:#0b1b2b; | |
| --glass: rgba(255,255,255,0.05); | |
| --glass-hover: rgba(255,255,255,0.08); | |
| --accent:#6c8cff; | |
| --accent-light:#8be5d0; | |
| --text:#e6eef8; | |
| --muted:#9aa4b2; | |
| --radius:14px; | |
| --shadow:0 8px 30px rgba(2,6,23,0.6); | |
| } | |
| *{box-sizing:border-box;} | |
| body{ | |
| margin:0; | |
| font-family: 'Inter', sans-serif; | |
| background: linear-gradient(180deg, #071227, #0d1a2b); | |
| color:var(--text); | |
| min-height:100vh; | |
| display:flex; | |
| flex-direction:column; | |
| align-items:center; | |
| padding:10px; | |
| } | |
| h1,h2,h3,h4,h5{margin:0;padding:0;} | |
| a{text-decoration:none;color:var(--accent);} | |
| a:hover{color:var(--accent-light);} | |
| /* App container */ | |
| .app{ | |
| display:flex; | |
| flex-direction:row; | |
| gap:12px; | |
| width:100%; | |
| max-width:1200px; | |
| flex:1; | |
| } | |
| .panel{ | |
| background: var(--glass); | |
| backdrop-filter: blur(12px) saturate(1.1); | |
| border-radius: var(--radius); | |
| padding:12px; | |
| box-shadow: var(--shadow); | |
| border:1px solid rgba(255,255,255,0.08); | |
| transition: transform .2s ease, box-shadow .2s ease; | |
| } | |
| .panel:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(8,14,40,0.5);} | |
| /* Sidebar */ | |
| .sidebar{ | |
| flex:0 0 240px; | |
| display:flex; | |
| flex-direction:column; | |
| gap:10px; | |
| height:calc(100vh - 40px); | |
| } | |
| .sidebar-header{ | |
| display:flex; | |
| justify-content:space-between; | |
| align-items:center; | |
| margin-bottom:8px; | |
| } | |
| .brand{ | |
| font-weight:700; | |
| font-size:18px; | |
| color:var(--accent); | |
| display:flex; | |
| align-items:center; | |
| gap:8px; | |
| } | |
| .brand i{font-size:20px;} | |
| .file-list{ | |
| flex:1; | |
| overflow-y:auto; | |
| display:flex; | |
| flex-direction:column; | |
| gap:6px; | |
| } | |
| .file-item{ | |
| display:flex; | |
| justify-content:space-between; | |
| align-items:center; | |
| padding:6px 8px; | |
| border-radius:10px; | |
| cursor:pointer; | |
| background: rgba(255,255,255,0.02); | |
| transition:0.15s ease; | |
| } | |
| .file-item:hover{background:var(--glass-hover);} | |
| .file-item.active{background:rgba(108,140,255,0.12);color:#fff;} | |
| .file-actions{display:flex;gap:6px;align-items:center;} | |
| /* Editor area */ | |
| .editor-area{ | |
| flex:1; | |
| display:flex; | |
| flex-direction:column; | |
| gap:8px; | |
| min-height:400px; | |
| } | |
| .cm-wrap{border-radius:12px;overflow:hidden;border:1px solid rgba(255,255,255,0.04);} | |
| .CodeMirror{height:calc(100vh - 240px);background: rgba(2,6,23,0.7); color:#e8f1ff; font-size:13px;} | |
| /* Buttons */ | |
| .btn{ | |
| background: rgba(255,255,255,0.03); | |
| border:1px solid rgba(255,255,255,0.08); | |
| color:var(--muted); | |
| padding:6px 10px; | |
| border-radius:10px; | |
| cursor:pointer; | |
| display:inline-flex; | |
| align-items:center; | |
| gap:6px; | |
| transition:all .15s ease; | |
| } | |
| .btn:hover{color:#fff;transform:translateY(-2px);background:var(--glass-hover);} | |
| .btn-primary{ | |
| background: linear-gradient(90deg,var(--accent),var(--accent-light)); | |
| color:#04253b; | |
| padding:10px 14px; | |
| font-weight:700; | |
| border:none; | |
| } | |
| .console{ | |
| margin-top:6px; | |
| background: rgba(0,0,0,0.5); | |
| border-radius:10px; | |
| padding:12px; | |
| font-family:monospace; | |
| color:#cfe7ff; | |
| min-height:120px; | |
| overflow:auto; | |
| } | |
| /* Footer */ | |
| footer{ | |
| text-align:center; | |
| color:var(--muted); | |
| font-size:14px; | |
| padding:12px 0 4px 0; | |
| } | |
| footer .note{color:#c7d7ff;font-weight:600;} | |
| /* Responsive */ | |
| @media (max-width:900px){ | |
| .app{flex-direction:column;} | |
| .sidebar{width:100%;height:auto;order:2;} | |
| .editor-area{order:1;} | |
| .CodeMirror{height:300px;} | |
| } | |
| @media (max-width:480px){ | |
| body{padding:6px;} | |
| .brand{font-size:16px;} | |
| .btn{padding:5px 8px;font-size:13px;} | |
| .btn-primary{padding:8px 10px;font-size:14px;} | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header class="sidebar-header"> | |
| <div class="brand"><i class="fa-solid fa-rocket"></i> JavaRunner</div> | |
| </header> | |
| <div class="app"> | |
| <!-- Sidebar --> | |
| <div class="panel sidebar"> | |
| <div class="sidebar-header"> | |
| <button class="btn" id="newBtn"><i class="fa-solid fa-file-circle-plus"></i> New</button> | |
| <button class="btn" id="importBtn"><i class="fa-solid fa-file-import"></i> Import</button> | |
| </div> | |
| <input type="text" placeholder="Search files..." id="searchFile" style="width:100%;padding:6px;border-radius:8px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.08);color:var(--muted);margin-bottom:6px;"> | |
| <div class="file-list" id="fileList"></div> | |
| </div> | |
| <!-- Editor --> | |
| <div class="panel editor-area"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;"> | |
| <div>Active File: <span id="activeFile">—</span></div> | |
| <div style="display:flex;gap:6px;flex-wrap:wrap;"> | |
| <button class="btn-primary" id="runBtn"><i class="fa-solid fa-play"></i> Run</button> | |
| <button class="btn" id="saveBtn"><i class="fa-solid fa-floppy-disk"></i> Save</button> | |
| <button class="btn" id="downloadBtn"><i class="fa-solid fa-download"></i> Download</button> | |
| <button class="btn" id="formatBtn"><i class="fa-solid fa-align-left"></i> Format</button> | |
| <button class="btn" id="cutBtn"><i class="fa-solid fa-cut"></i></button> | |
| <button class="btn" id="copyBtn"><i class="fa-solid fa-copy"></i></button> | |
| <button class="btn" id="pasteBtn"><i class="fa-solid fa-clipboard"></i></button> | |
| <button class="btn" id="deleteBtn"><i class="fa-solid fa-trash"></i></button> | |
| </div> | |
| </div> | |
| <div class="cm-wrap" id="cmWrap"><div id="editor"></div></div> | |
| <div class="console" id="console">Console output will appear here.</div> | |
| </div> | |
| </div> | |
| <footer> | |
| Made with ❤️ for <span class="note">Ragini Didi</span> | |
| </footer> | |
| <input type="file" id="fileInput" accept=".java" style="display:none"> | |
| <script> | |
| // ---------- Editor setup ---------- | |
| const editor = CodeMirror(document.getElementById('editor'),{ | |
| mode:"text/x-java", | |
| lineNumbers:true, | |
| tabSize:4, | |
| indentUnit:4, | |
| autoCloseBrackets:true, | |
| matchBrackets:true, | |
| value:"class Main {\n public static void main(String[] args) {\n System.out.println(\"Hello Ragini!\");\n }\n}" | |
| }); | |
| // Resize editor for mobile | |
| function resizeEditor(){ | |
| const wrap=document.querySelector('.CodeMirror'); | |
| if(!wrap) return; | |
| let vh=window.innerHeight; | |
| wrap.style.height=(vh - 280)+'px'; | |
| editor.refresh(); | |
| } | |
| window.addEventListener('resize',resizeEditor); | |
| setTimeout(resizeEditor,200); | |
| // ---------- Local storage ---------- | |
| let files=JSON.parse(localStorage.getItem('javaRunner_files')||'{}'); | |
| let active=localStorage.getItem('javaRunner_active')||null; | |
| const fileListEl=document.getElementById('fileList'); | |
| const activeFileEl=document.getElementById('activeFile'); | |
| const consoleEl=document.getElementById('console'); | |
| function saveToStorage(){localStorage.setItem('javaRunner_files',JSON.stringify(files));} | |
| function setActive(name){ | |
| active=name; | |
| localStorage.setItem('javaRunner_active',active); | |
| activeFileEl.innerText=name||'—'; | |
| renderFiles(); | |
| if(active && files[active]) editor.setValue(files[active]); | |
| } | |
| function renderFiles(filter=''){ | |
| fileListEl.innerHTML=''; | |
| const names=Object.keys(files).filter(n=>n.toLowerCase().includes(filter.toLowerCase())).sort(); | |
| if(names.length===0){fileListEl.innerHTML='<div style="color:'+ 'var(--muted)' +';padding:10px;font-size:13px">No files yet.</div>';return;} | |
| names.forEach(name=>{ | |
| const div=document.createElement('div'); | |
| div.className='file-item'+(name===active?' active':''); | |
| div.innerHTML=`<div>${name}</div><div style="display:flex;gap:6px;"> | |
| <button class="btn" onclick="openFile('${name}')"><i class="fa-solid fa-folder-open"></i></button></div>`; | |
| fileListEl.appendChild(div); | |
| }); | |
| } | |
| function newFile(){ | |
| let name=prompt('Filename (end with .java)','Main.java'); | |
| if(!name) return;if(!name.endsWith('.java')){alert('Filename must end with .java');return;} | |
| if(files[name]){alert('File exists');return;} | |
| const classname=name.replace('.java','').replace(/[^A-Za-z0-9_]/g,'')||'Main'; | |
| files[name]=`class ${classname} {\n public static void main(String[] args) {\ |