diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main/ui/BrowserBar.java | 98 | ||||
-rw-r--r-- | src/main/ui/BrowserCanvas.java | 42 | ||||
-rw-r--r-- | src/main/ui/BrowserWindow.java | 139 | ||||
-rw-r--r-- | src/main/ui/Main.java | 2 |
4 files changed, 280 insertions, 1 deletions
diff --git a/src/main/ui/BrowserBar.java b/src/main/ui/BrowserBar.java new file mode 100644 index 0000000..09c78a5 --- /dev/null +++ b/src/main/ui/BrowserBar.java @@ -0,0 +1,98 @@ +package ui; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.*; + +public class BrowserBar extends JToolBar { + private BrowserWindow parent; + + private JPopupMenu tabMenu; + private JToggleButton tabButton; + private JTextField uriInput; +// private JButton saveTabsButton; + private JButton openUriButton; + + public BrowserBar(BrowserWindow parent) { + this.parent = parent; + + var test = new JMenuItem("Ipsum"); + tabMenu = new JPopupMenu("Tabs"); + tabMenu.add(new JMenuItem("Hello")); + tabMenu.add(new JMenuItem("World")); + tabMenu.add(new JMenuItem("Lorem")); + tabMenu.add(test); + tabMenu.remove(test); + + tabButton = new JToggleButton("Tabs"); + tabButton.addActionListener(toggleTabMenu()); + add(tabButton); + + uriInput = new JTextField(); + add(uriInput); + + openUriButton = new JButton("Go"); + openUriButton.addActionListener(openTab()); + add(openUriButton); + + } + + // EFFECTS: opens the content of the text field in the current tab + private ActionListener openTab() { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + String uri = uriInput.getText(); + parent.render(uri); + addTab(uri); + System.out.println(uri); + System.out.println("should run"); + } + }; + } + + // EFFECTS: adds a new tab pointing to URI in the background + public void addTab(String tab) { + JToggleButton tabButton = new JToggleButton(tab); + + tabButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + int action = JOptionPane.showOptionDialog(null, + "Open or close this tab?", "apus", + JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, + null, new String[]{"Open", "Close"}, "Open"); + if (action == 0) { + parent.render(tab); + } else { + tabMenu.remove(tabButton); + tabMenu.setVisible(false); + parent.removeTab(tab); + } + } + }); + + this.tabMenu.add(tabButton); + parent.addTab(tab); + } + + // MODIFIES: this + // EFFECTS: toggles the tab menu + private ActionListener toggleTabMenu() { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + if (tabButton.isSelected()) { + Point location = tabButton.getLocationOnScreen(); + location.translate(0, 30); // fuck this method lol + tabMenu.setLocation(location); + tabMenu.setVisible(true); + } else { + tabMenu.setVisible(false); + } + } + }; + } +} diff --git a/src/main/ui/BrowserCanvas.java b/src/main/ui/BrowserCanvas.java new file mode 100644 index 0000000..2a77442 --- /dev/null +++ b/src/main/ui/BrowserCanvas.java @@ -0,0 +1,42 @@ +package ui; + +import model.html.ElementNode; +import model.html.TextNode; +import model.util.Node; + +import javax.swing.*; +import java.awt.*; +import java.util.*; + +public class BrowserCanvas extends JPanel { + private ArrayList<Node> html; + + // MODIFIES: this + // EFFECTS: constructs a BrowserCanvas object + public BrowserCanvas(ArrayList<Node> html) { + super(); + this.html = html; + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Point location = new Point(10, 20); // we need a mutable reference + renderHtml(html, g, location); + } + + // EFFECTS: naively renders our html file by printing text nodes + private void renderHtml(ArrayList<Node> html, Graphics g, Point location) { + for (Node node : html) { + if (node instanceof TextNode) { + if (!node.getData().isBlank()) { + g.drawString(node.getData(), location.x, location.y); + location.translate(0, 20); + } + } else { + renderHtml(((ElementNode) node).getChildren(), g, location); + } + } + } + +} diff --git a/src/main/ui/BrowserWindow.java b/src/main/ui/BrowserWindow.java new file mode 100644 index 0000000..9a92186 --- /dev/null +++ b/src/main/ui/BrowserWindow.java @@ -0,0 +1,139 @@ +package ui; + +import model.html.HtmlParser; +import org.json.JSONArray; +import persistance.JsonUtils; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayDeque; +import java.util.ArrayList; + +// Broad JFrame usage taken from here: https://docs.oracle.com/javase/tutorial/uiswing/components/frame.html +public class BrowserWindow extends JFrame { + public static final int WIDTH = 1200; + public static final int HEIGHT = 800; + private static final String storagePath = "data/apus.cache"; + + private BrowserCanvas canvas; + private BrowserBar browserBar; + + private ArrayDeque<String> tabs; + private String pathString; + + // MODIFIES: this + // EFFECTS: creates a new BrowserWindow program for rendering pages + public BrowserWindow() { + super("apus"); + tabs = new ArrayDeque<>(); + canvas = new BrowserCanvas(new ArrayList<>()); +// render("data/example.html"); + browserBar = new BrowserBar(this); + getContentPane().add(browserBar, BorderLayout.SOUTH); +// pack(); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(WIDTH, HEIGHT); + render("/home/apropos/Projects/website/j-james/index.html"); +// browserBar.addTab("/home/apropos/Projects/website/j-james/index.html"); + setVisible(true); + setClosingBehavior(); + + initializeBrowser(); + } + + // MODIFIES: this + // EFFECTS: Renders an arbitrary page + public void render(String uri) { + pathString = uri; + remove(canvas); + System.out.println(pathString); + try { + Path path = Paths.get(pathString); + String file = new String(Files.readAllBytes(path)); + HtmlParser parser = new HtmlParser(); + canvas = new BrowserCanvas(parser.parseHtml(file)); + } catch (Exception e) { + System.out.println("Could not read file, rendering empty page: " + e.getMessage()); + + canvas = new BrowserCanvas(new ArrayList<>()); + } + add(canvas); + repaint(); + setVisible(true); + } + + // EFFECTS: Prompts the user to save their tabs before quitting + private void setClosingBehavior() { + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (tabs.size() > 0) { + saveCurrentTabs(); + } + super.windowClosing(e); + } + }); + } + + // EFFECTS: sets up the browser upon launching + private void initializeBrowser() { + if (new File(storagePath).length() > 2) { + restorePreviousTabs(); + } + } + + // MODIFIES: this + // EFFECTS: prompts the user to restore their previous tabs + private void restorePreviousTabs() { + int answer = JOptionPane.showOptionDialog( + this, "Would you like to restore your previous tabs?", "apus", + JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, + null, new String[]{"Yes", "No"}, "Yes"); + if (answer == 0) { + try { + JSONArray state = JsonUtils.readFromFile(storagePath); + for (int i = 0; i < state.length(); i++) { + this.browserBar.addTab((String) state.get(i)); + this.addTab((String) state.get(i)); + } + } catch (Exception e) { + System.out.println("Restoring state from disk failed with " + e.toString()); + } + } + } + + // EFFECTS: prompts the user to save their current tabs before closing + private void saveCurrentTabs() { + int answer = JOptionPane.showOptionDialog( + this, "Would you like to save your current tabs?", "apus", + JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, + null, new String[]{"Yes", "No"}, "Yes"); + if (answer == 0) { + JsonUtils.writeToFile(new JSONArray(tabs), storagePath); + } else { + JsonUtils.writeToFile(new JSONArray(), storagePath); + } + } + + public ArrayDeque<String> getTabs() { + return tabs; + } + + // MODIFIES: this + // EFFECTS: add a tab + public void addTab(String tab) { + this.tabs.add(tab); + } + + // MODIFIES: this + // EFFECTS: remove a tab + public void removeTab(String tab) { + this.tabs.remove(tab); + } +} diff --git a/src/main/ui/Main.java b/src/main/ui/Main.java index 841576f..267d65d 100644 --- a/src/main/ui/Main.java +++ b/src/main/ui/Main.java @@ -2,6 +2,6 @@ package ui; public class Main { public static void main(String[] args) { - new BrowserApp(); + new BrowserWindow(); } } |