Rendering und Lua working, need to work on request method via custom URL implementation
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
package org.openautonomousconnection.webclient.ui;
|
||||
|
||||
import org.openautonomousconnection.oacswing.component.OACButton;
|
||||
import org.openautonomousconnection.oacswing.component.OACFrame;
|
||||
import org.openautonomousconnection.oacswing.component.OACPanel;
|
||||
import org.openautonomousconnection.oacswing.component.OACTextField;
|
||||
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A simple multi-tab browser UI:
|
||||
* - Tab headers live in the custom title bar (OACTitleBar / OACTabbedPane).
|
||||
* - Tab content (JavaFX WebView) lives in the frame content area.
|
||||
* - Address bar controls the currently selected tab.
|
||||
*/
|
||||
public class BrowserUI extends OACFrame {
|
||||
|
||||
private static final int TITLE_BAR_HEIGHT = 42;
|
||||
|
||||
private final OACTextField addressField;
|
||||
private final OACButton goButton;
|
||||
private final OACButton newTabButton;
|
||||
private final OACButton closeTabButton;
|
||||
private final OACButton backButton;
|
||||
private final OACButton forwardButton;
|
||||
private final OACButton reloadButton;
|
||||
|
||||
private final CardLayout cardLayout;
|
||||
private final OACPanel pageHost;
|
||||
|
||||
private final Map<String, BrowserTab> tabsByKey = new LinkedHashMap<>();
|
||||
private int tabCounter = 0;
|
||||
|
||||
/**
|
||||
* Creates the browser UI and wires tab selection and address bar to tab content.
|
||||
*/
|
||||
public BrowserUI() {
|
||||
super("OAC Browser");
|
||||
|
||||
// Content pane must be offset because your title bar is an overlay in the layered pane.
|
||||
JComponent content = (JComponent) getContentPane();
|
||||
content.setLayout(new BorderLayout());
|
||||
content.setBorder(BorderFactory.createEmptyBorder(TITLE_BAR_HEIGHT, 0, 0, 0));
|
||||
|
||||
// Address bar (top of content area)
|
||||
OACPanel navBar = new OACPanel(new BorderLayout(8, 0));
|
||||
navBar.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 10));
|
||||
|
||||
OACPanel leftControls = new OACPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
|
||||
backButton = new OACButton("←");
|
||||
forwardButton = new OACButton("→");
|
||||
reloadButton = new OACButton("⟳");
|
||||
leftControls.add(backButton);
|
||||
leftControls.add(forwardButton);
|
||||
leftControls.add(reloadButton);
|
||||
|
||||
addressField = new OACTextField();
|
||||
goButton = new OACButton("Go");
|
||||
|
||||
OACPanel rightControls = new OACPanel(new FlowLayout(FlowLayout.RIGHT, 6, 0));
|
||||
newTabButton = new OACButton("+");
|
||||
closeTabButton = new OACButton("✕");
|
||||
rightControls.add(newTabButton);
|
||||
rightControls.add(closeTabButton);
|
||||
|
||||
navBar.add(leftControls, BorderLayout.WEST);
|
||||
navBar.add(addressField, BorderLayout.CENTER);
|
||||
navBar.add(goButton, BorderLayout.EAST);
|
||||
navBar.add(rightControls, BorderLayout.EAST);
|
||||
|
||||
// Fix: BorderLayout only allows one EAST; wrap Go+RightControls in a single panel
|
||||
OACPanel east = new OACPanel(new FlowLayout(FlowLayout.RIGHT, 6, 0));
|
||||
|
||||
east.add(goButton);
|
||||
east.add(newTabButton);
|
||||
east.add(closeTabButton);
|
||||
navBar.add(east, BorderLayout.EAST);
|
||||
|
||||
content.add(navBar, BorderLayout.NORTH);
|
||||
|
||||
// Page host
|
||||
cardLayout = new CardLayout();
|
||||
pageHost = new OACPanel(cardLayout);
|
||||
content.add(pageHost, BorderLayout.CENTER);
|
||||
|
||||
// Wire title bar tab selection to content host
|
||||
getTitleBar().getTabs().addChangeListener(e -> onHeaderTabChanged());
|
||||
|
||||
// Wire address bar actions
|
||||
addressField.addActionListener(e -> navigateCurrent(addressField.getText()));
|
||||
goButton.addActionListener(e -> navigateCurrent(addressField.getText()));
|
||||
|
||||
// Wire navigation buttons
|
||||
backButton.addActionListener(e -> {
|
||||
BrowserTab tab = getCurrentTab();
|
||||
if (tab != null) tab.goBack();
|
||||
});
|
||||
forwardButton.addActionListener(e -> {
|
||||
BrowserTab tab = getCurrentTab();
|
||||
if (tab != null) tab.goForward();
|
||||
});
|
||||
reloadButton.addActionListener(e -> {
|
||||
BrowserTab tab = getCurrentTab();
|
||||
if (tab != null) tab.reload();
|
||||
});
|
||||
|
||||
newTabButton.addActionListener(e -> openNewTab("web://info.oac/"));
|
||||
closeTabButton.addActionListener(e -> closeCurrentTab());
|
||||
|
||||
// Create first tab
|
||||
DesignManager.apply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new tab and navigates to the given URL.
|
||||
*
|
||||
* @param url initial URL
|
||||
*/
|
||||
public void openNewTab(String url) {
|
||||
String key = nextTabKey();
|
||||
BrowserTab tab = new BrowserTab(url, newLocation -> SwingUtilities.invokeLater(() -> {
|
||||
BrowserTab current = getCurrentTab();
|
||||
if (current != null && Objects.equals(current.getKey(), key)) {
|
||||
addressField.setText(newLocation);
|
||||
}
|
||||
}));
|
||||
|
||||
tabsByKey.put(key, tab);
|
||||
|
||||
// Real page content in center host
|
||||
pageHost.add(tab.getView(), key);
|
||||
|
||||
// Header tab in title bar: DO NOT place the real page here (title bar is only ~42px high).
|
||||
getTitleBar().addTab(key, new OACPanel());
|
||||
|
||||
// Select it
|
||||
int idx = getTitleBar().getTabs().getTabCount() - 1;
|
||||
getTitleBar().getTabs().setSelectedIndex(idx);
|
||||
|
||||
// Navigate
|
||||
tab.loadUrl(url);
|
||||
|
||||
// Show content
|
||||
cardLayout.show(pageHost, key);
|
||||
pageHost.revalidate();
|
||||
pageHost.repaint();
|
||||
|
||||
// Update address field immediately
|
||||
addressField.setText(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates the current tab to the given input (URL or host).
|
||||
*
|
||||
* @param input user input
|
||||
*/
|
||||
public void navigateCurrent(String input) {
|
||||
BrowserTab tab = getCurrentTab();
|
||||
if (tab == null) return;
|
||||
|
||||
String url = normalizeUrl(input);
|
||||
addressField.setText(url);
|
||||
tab.loadUrl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the currently selected tab.
|
||||
*/
|
||||
public void closeCurrentTab() {
|
||||
int idx = getTitleBar().getTabs().getSelectedIndex();
|
||||
if (idx < 0) return;
|
||||
|
||||
String key = getTitleBar().getTabs().getTitleAt(idx);
|
||||
|
||||
BrowserTab removed = tabsByKey.remove(key);
|
||||
if (removed != null) {
|
||||
removed.dispose();
|
||||
pageHost.remove(removed.getView());
|
||||
}
|
||||
|
||||
getTitleBar().getTabs().removeTabAt(idx);
|
||||
|
||||
// If no tabs left, open a new one
|
||||
if (getTitleBar().getTabs().getTabCount() == 0) {
|
||||
openNewTab("web://info.oac/");
|
||||
return;
|
||||
}
|
||||
|
||||
// Show selected tab content
|
||||
onHeaderTabChanged();
|
||||
}
|
||||
|
||||
private void onHeaderTabChanged() {
|
||||
BrowserTab tab = getCurrentTab();
|
||||
if (tab == null) return;
|
||||
|
||||
cardLayout.show(pageHost, tab.getKey());
|
||||
pageHost.revalidate();
|
||||
pageHost.repaint();
|
||||
|
||||
// Sync address bar
|
||||
String loc = tab.getLocation();
|
||||
if (loc != null && !loc.isBlank()) {
|
||||
addressField.setText(loc);
|
||||
}
|
||||
}
|
||||
|
||||
public BrowserTab getCurrentTab() {
|
||||
int idx = getTitleBar().getTabs().getSelectedIndex();
|
||||
if (idx < 0) return null;
|
||||
|
||||
String key = getTitleBar().getTabs().getTitleAt(idx);
|
||||
return tabsByKey.get(key);
|
||||
}
|
||||
|
||||
private String nextTabKey() {
|
||||
tabCounter++;
|
||||
return "Tab " + tabCounter;
|
||||
}
|
||||
|
||||
private static String normalizeUrl(String input) {
|
||||
String s = input == null ? "" : input.trim();
|
||||
if (s.isEmpty()) return "web://info.oac/";
|
||||
if (s.startsWith("web://")) {
|
||||
// Ensure trailing slash for "host only" URLs
|
||||
String rest = s.substring("web://".length());
|
||||
if (!rest.contains("/")) return s + "/";
|
||||
return s;
|
||||
}
|
||||
return "web://" + s + (s.contains("/") ? "" : "/");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user