diff --git a/pom.xml b/pom.xml
index 322daad..9d76c01 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,7 +42,13 @@
rstaui
3.3.1
-
+
+
+ org.bidib.jbidib.com.vldocking
+ vldocking
+ 3.0.10
+
+
diff --git a/src/main/java/org/editor/AccessFrame.java b/src/main/java/org/editor/AccessFrame.java
index bddba0b..00177e4 100644
--- a/src/main/java/org/editor/AccessFrame.java
+++ b/src/main/java/org/editor/AccessFrame.java
@@ -1,5 +1,7 @@
package org.editor;
+import com.vlsolutions.swing.docking.DockKey;
+import com.vlsolutions.swing.docking.Dockable;
import org.editor.events.Actions;
import java.awt.BorderLayout;
import java.awt.Color;
diff --git a/src/main/java/org/editor/CanvasFrame.java b/src/main/java/org/editor/CanvasFrame.java
index b7d6929..9a9d077 100644
--- a/src/main/java/org/editor/CanvasFrame.java
+++ b/src/main/java/org/editor/CanvasFrame.java
@@ -1,8 +1,11 @@
package org.editor;
+import com.vlsolutions.swing.docking.DockKey;
+import com.vlsolutions.swing.docking.Dockable;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
@@ -54,6 +57,7 @@ public class CanvasFrame extends JPanel implements MouseListener, MouseMotionLis
private Point selectionEnd = null;
private static CanvasFrame _the = null;
+ private DockKey key = new DockKey("canvas");
private CanvasFrame() {
super(new BorderLayout());
@@ -319,5 +323,4 @@ private void drawCrosshair(Graphics2D g2) {
g2.fillOval(mouseX - radius, mouseY - radius, radius * 2, radius * 2);
}
}
-
}
diff --git a/src/main/java/org/editor/CodeEditor.java b/src/main/java/org/editor/CodeEditor.java
index 3f5d5d5..e554135 100644
--- a/src/main/java/org/editor/CodeEditor.java
+++ b/src/main/java/org/editor/CodeEditor.java
@@ -1,6 +1,11 @@
package org.editor;
+import com.vlsolutions.swing.docking.DockKey;
+import com.vlsolutions.swing.docking.Dockable;
import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
@@ -10,6 +15,8 @@
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.text.BadLocationException;
+import org.editor.fs.FileFilter;
+import org.editor.fs.FilePersistance;
import org.editor.icons.Icons;
import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.BasicCompletion;
@@ -20,6 +27,8 @@
import org.fife.ui.rsyntaxtextarea.CodeTemplateManager;
import org.fife.ui.rsyntaxtextarea.FileLocation;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaHighlighter;
+import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.TextEditorPane;
import org.fife.ui.rsyntaxtextarea.TokenMakerFactory;
import org.fife.ui.rsyntaxtextarea.templates.CodeTemplate;
@@ -30,13 +39,19 @@
*
* @author hexaredecimal
*/
-public class CodeEditor extends JPanel {
+public class CodeEditor extends JPanel implements Dockable {
public TextEditorPane textArea;
public Path file = null;
private boolean isTmp;
+ private DockKey key; // = new DockKey("textEditor");
+ public int tabIndex =0;
public CodeEditor() {
+ this(null);
+ }
+
+ public CodeEditor(Path path) {
super(new BorderLayout());
textArea = new TextEditorPane();
textArea.setCodeFoldingEnabled(true);
@@ -61,17 +76,55 @@ public CodeEditor() {
gutter.setBookmarkingEnabled(true);
gutter.setBookmarkIcon(Icons.getIcon("bookmark"));
+ var self = this;
+ textArea.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ EditorWindow.setSelectedEditor(self);
+ getCursorPositionText(self);
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+ });
+
+ this.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ EditorWindow.setSelectedEditor(self);
+ getCursorPositionText(self);
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+ });
+
try {
- var fp = File.createTempFile("piccasso-", "-tmp");
- file = fp.toPath();
- fp.deleteOnExit();
- isTmp = true;
+ String tip = "Source code editor";
+ var icon = Icons.getIcon("code-file");
+ if (path == null) {
+ var fp = File.createTempFile("piccasso-", "-tmp");
+
+ key = new DockKey(fp.getName(), fp.getName(), tip, icon);
+ file = fp.toPath();
+ isTmp = true;
+ fp.deleteOnExit();
+ } else {
+ key = new DockKey(path.toFile().getName(), path.toFile().getName(), tip, icon);
+ file = path;
+ }
+ key.setCloseEnabled(true);
+ key.setAutoHideEnabled(true);
+ this.putClientProperty("dockKey", key);
} catch (IOException ex) {
Logger.getLogger(CodeEditor.class.getName()).log(Level.SEVERE, null, ex);
}
textArea
.addCaretListener(e -> {
+ EditorWindow.setSelectedEditor(this);
getCursorPositionText(this);
});
@@ -85,6 +138,8 @@ public boolean saveFile() {
try {
textArea.save();
+ FilePersistance.persistFile(file);
+ EditorWindow.setSeletedTabTitle(file.toFile().getName());
EditorWindow.current_file.setText("Written to " + file);
return true;
} catch (IOException e) {
@@ -102,6 +157,9 @@ public void setIsTmp(boolean isTmp) {
public boolean saveFileAs() {
var fileChooser = new JFileChooser(".");
+ fileChooser.setFileFilter(FileFilter.mdFilter);
+ fileChooser.setFileFilter(FileFilter.picsFilter);
+
int status = fileChooser.showSaveDialog(EditorWindow.win);
if (status != JFileChooser.APPROVE_OPTION) {
EditorWindow.current_file.setText("Save cancelled");
@@ -113,8 +171,11 @@ public boolean saveFileAs() {
textArea.saveAs(loc);
textArea.load(loc);
file = path.toPath();
+ FilePersistance.persistFile(file);
getCursorPositionText(this);
+ EditorWindow.setSeletedTabTitle(path.getName());
EditorWindow.current_file.setText("Written to " + path);
+ isTmp = false;
return true;
} catch (IOException ex) {
JOptionPane.showMessageDialog(EditorWindow.win, ex);
@@ -192,4 +253,36 @@ public static void createTemplateManager() {
ctm.addTemplate(ct);
}
}
+
+ public boolean load(File fp) {
+ setIsTmp(false);
+ var loc = FileLocation.create(fp);
+ FilePersistance.persistFile(fp.toPath());
+ try {
+ textArea.load(loc);
+
+ if (fp.getName().endsWith(".pics")) {
+ textArea.setSyntaxEditingStyle("text/piccode");
+ } else if (fp.getName().endsWith(".md")) {
+ textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_MARKDOWN);
+ } else {
+ textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
+ }
+
+ return true;
+ } catch (IOException ex) {
+ JOptionPane.showMessageDialog(EditorWindow.win, ex);
+ return false;
+ }
+ }
+
+ @Override
+ public DockKey getDockKey() {
+ return key;
+ }
+
+ @Override
+ public Component getComponent() {
+ return this;
+ }
}
diff --git a/src/main/java/org/editor/DockablePanel.java b/src/main/java/org/editor/DockablePanel.java
new file mode 100644
index 0000000..e753f1d
--- /dev/null
+++ b/src/main/java/org/editor/DockablePanel.java
@@ -0,0 +1,42 @@
+package org.editor;
+
+import com.vlsolutions.swing.docking.DockKey;
+import com.vlsolutions.swing.docking.Dockable;
+import java.awt.Component;
+import java.awt.LayoutManager;
+import javax.swing.JPanel;
+import org.editor.icons.Icons;
+
+/**
+ *
+ * @author hexaredecimal
+ */
+public class DockablePanel extends JPanel implements Dockable {
+ private DockKey key;
+
+ public DockablePanel(LayoutManager layout) {
+ super(layout);
+ key = new DockKey("dock-" + System.nanoTime());
+ }
+
+ public DockablePanel(LayoutManager layout, String id) {
+ super(layout);
+ key = new DockKey(id);
+ }
+
+ public DockablePanel(LayoutManager layout, String id, String name, String tip, String icon) {
+ super(layout);
+ key = new DockKey(id, name, tip, Icons.getIcon(icon));
+ }
+
+ @Override
+ public DockKey getDockKey() {
+ return key;
+ }
+
+ @Override
+ public Component getComponent() {
+ return this;
+ }
+
+}
diff --git a/src/main/java/org/editor/EditorWindow.java b/src/main/java/org/editor/EditorWindow.java
index 0dd5816..1afc5c9 100644
--- a/src/main/java/org/editor/EditorWindow.java
+++ b/src/main/java/org/editor/EditorWindow.java
@@ -2,6 +2,16 @@
import org.editor.panels.DashboardPanel;
import com.formdev.flatlaf.FlatLightLaf;
+import com.vlsolutions.swing.docking.DockKey;
+import com.vlsolutions.swing.docking.DockView;
+import com.vlsolutions.swing.docking.Dockable;
+import com.vlsolutions.swing.docking.DockableState;
+import com.vlsolutions.swing.docking.DockingConstants;
+import com.vlsolutions.swing.docking.DockingDesktop;
+import com.vlsolutions.swing.docking.DockingPreferences;
+import com.vlsolutions.swing.docking.event.DockableStateWillChangeEvent;
+import com.vlsolutions.swing.docking.event.DockableStateWillChangeListener;
+import com.vlsolutions.swing.docking.ui.DockingUISettings;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@@ -11,15 +21,11 @@
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
-import javax.imageio.ImageIO;
import javax.swing.Action;
import javax.swing.BorderFactory;
+import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
@@ -38,22 +44,13 @@
import org.editor.events.Actions;
import org.editor.icons.Icons;
import org.editor.menu.Menus;
-import org.editor.util.It;
import org.fife.rsta.ui.CollapsibleSectionPanel;
//import org.fife.rsta.ui.DocumentMap;
-import org.fife.rsta.ui.GoToDialog;
-import org.fife.rsta.ui.SizeGripIcon;
import org.fife.rsta.ui.search.FindDialog;
import org.fife.rsta.ui.search.ReplaceDialog;
-import org.fife.rsta.ui.search.ReplaceToolBar;
import org.fife.rsta.ui.search.SearchEvent;
import org.fife.rsta.ui.search.SearchListener;
-import org.fife.rsta.ui.search.FindToolBar;
-import org.fife.ui.rsyntaxtextarea.ErrorStrip;
-import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
-import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
-import org.fife.ui.rtextarea.RTextScrollPane;
import org.fife.ui.rtextarea.SearchContext;
import org.fife.ui.rtextarea.SearchEngine;
import org.fife.ui.rtextarea.SearchResult;
@@ -72,10 +69,13 @@ public final class EditorWindow extends JFrame implements SearchListener {
public static JLabel line_perc = new JLabel();
public static JLabel charset = new JLabel();
public static JProgressBar seekBar = new JProgressBar();
+ private DockablePanel dashboard;
private CollapsibleSectionPanel csp;
public static FindDialog findDialog;
public static ReplaceDialog replaceDialog;
+ private DockingDesktop desk = new DockingDesktop();
+ private static CodeEditor selected = null;
public static EditorWindow the() {
if (win == null) {
@@ -88,27 +88,72 @@ public static EditorWindow the() {
public EditorWindow() {
super("Piccode - DashBoard");
-
+ var _ =new CodeEditor();
root = getRootPane();
Icons.loadIcons();
- tabs = new JTabbedPane();
tabEditors = new HashMap<>();
CodeEditor.createTemplateManager();
-
- addTab(null);
- Actions.loadActions();
initSearchDialogs();
+ DockingUISettings.getInstance().installUI();
+ customizeDock();
+
try {
UIManager.setLookAndFeel(new FlatLightLaf());
} catch (Exception ex) {
System.err.println("Failed to initialize LaF");
}
- var width = 900;
- var height = 600;
+ int width = 900;
+ int height = 600;
+
+ desk.addDockableStateWillChangeListener(event -> {
+ var current = event.getCurrentState();
+
+ if (current == null) {
+ return;
+ }
+
+ if (current.getDockable() instanceof CodeEditor ed) {
+ if (event.getFutureState().isClosed()) {
+ if (removeIfDirty(ed.tabIndex, ed) == false) {
+ event.cancel();
+ }
+ }
+ }
+ });
JPanel main_panel = new JPanel(new BorderLayout());
+ //main_panel.add(desk, BorderLayout.CENTER);
+
+ JToolBar tool_bar = makeToolBar(
+ Actions.newProjectAction,
+ Actions.newFileAction,
+ Actions.openFileAction,
+ null,
+ Actions.saveAction,
+ null,
+ Actions.undoAction,
+ Actions.redoAction,
+ Actions.compileAction,
+ Actions.renderAction,
+ null,
+ Actions.exitAction
+ );
+ main_panel.add(tool_bar, BorderLayout.PAGE_START);
+
+ current_file = new JLabel("[NONE]");
+ line_info = new JLabel();
+ line_perc = new JLabel();
+ charset = new JLabel();
+ seekBar = new JProgressBar();
+ seekBar.setValue(50);
+
+ JToolBar bottom_bar = makeLRToolBar(
+ new Component[]{current_file, null},
+ new Component[]{line_info, line_perc, seekBar, null, charset}
+ );
+ main_panel.add(bottom_bar, BorderLayout.PAGE_END);
Action[] app_actions = {
Actions.showFileTreeAction,
@@ -117,32 +162,25 @@ public EditorWindow() {
Actions.exportAction,
Actions.AIAction,
Actions.communityAction,
- Actions.pluginsAction,};
- var side_panel = makeCoolbar(height, app_actions);
-
- main_panel.add(side_panel, BorderLayout.WEST);
-
- JSplitPane editor_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
- editor_split.setDividerLocation(width - 300);
+ Actions.pluginsAction
+ };
- var pluginSpace = new JPanel();
- JSplitPane plugin_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
- plugin_split.setLeftComponent(editor_split);
- plugin_split.setDividerLocation(width - 100);
- plugin_split.setRightComponent(pluginSpace);
- main_panel.add(plugin_split, BorderLayout.CENTER);
+ var bar = makeCoolbar(height, app_actions);
- editor_split.setLeftComponent(tabs);
+ JMenuBar menu_bar = new JMenuBar();
+ this.setJMenuBar(menu_bar);
- JSplitPane canvas_split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
- canvas_split.setDividerLocation(height - 250);
- editor_split.setRightComponent(canvas_split);
+ Actions.loadActions();
+ Menus.addMenus(menu_bar);
+ this.setIconImage(Icons.getIcon("appicon").getImage());
+ // Canvas and Access Panels
var canvas_panel = CanvasFrame.the();
- JScrollPane scrollPane = new JScrollPane(canvas_panel);
-
- JPanel render_panel = new JPanel(new BorderLayout());
+ var access_panel = new DockablePanel(new BorderLayout(), "Run");
+ access_panel.add(new AccessFrame(width));
+ var render_panel = new DockablePanel(new BorderLayout(), "Render");
+ render_panel.add(canvas_panel, BorderLayout.CENTER);
Action[] render_actions = {
Actions.normalAction,
Actions.gridAction,
@@ -153,96 +191,36 @@ public EditorWindow() {
Actions.thickBrushAction,
Actions.paintBucketAction,
Actions.effectsAction,};
+
var short_cuts = makeCoolbar(canvas_panel.getHeight(), render_actions);
short_cuts.setBorder(BorderFactory.createEmptyBorder());
render_panel.add(short_cuts, BorderLayout.EAST);
- render_panel.add(scrollPane, BorderLayout.CENTER);
- canvas_split.setLeftComponent(render_panel);
+ render_panel.add(new JScrollPane(canvas_panel), BorderLayout.CENTER);
- var access_panel = new AccessFrame(width);
- canvas_split.setRightComponent(access_panel);
-
- JMenuBar menu_bar = new JMenuBar();
- this.setJMenuBar(menu_bar);
+ var cool_bar = new DockablePanel(new BorderLayout(), "Quick Access");
+ cool_bar.add(bar, BorderLayout.CENTER);
- Menus.addMenus(menu_bar);
-
- Action[] tool_actions = {
- Actions.newProjectAction,
- Actions.newFileAction,
- Actions.openFileAction,
- Actions.openProjectAction,
- null,
- Actions.saveAction,
- Actions.saveAsAction,
- Actions.saveAllAction,
- null,
- Actions.undoAction,
- Actions.redoAction,
- Actions.copyAction,
- Actions.cutAction,
- Actions.pasteAction,
- null,
- Actions.compileAction,
- Actions.renderAction,
- null,
- Actions.exportAction,
- Actions.exitAction,
- null,
- Actions.normalAction,
- Actions.gridAction,
- Actions.pointAction,
- Actions.rulerAction,
- Actions.snapAction,
- Actions.brushAction,
- Actions.thickBrushAction,
- Actions.paintBucketAction,
- Actions.effectsAction,
- null,
- Actions.docsAction,
- Actions.websiteAction,
- Actions.aboutAction
- };
+ DockingPreferences.setDottedDesktopStyle();
+ getContentPane().add(desk, BorderLayout.CENTER);
+ getContentPane().add(render_panel, BorderLayout.WEST);
+ getContentPane().add(access_panel, BorderLayout.SOUTH);
+ getContentPane().add(cool_bar, BorderLayout.EAST);
+ getContentPane().add(tool_bar, BorderLayout.PAGE_START);
+ getContentPane().add(bottom_bar, BorderLayout.PAGE_END);
- var tool_bar = makeToolBar(tool_actions);
- main_panel.add(tool_bar, BorderLayout.PAGE_START);
+ dashboard = new DockablePanel(new BorderLayout(), "Piccasso DashBoard", "DashBoard", "Home page", "file");
+ dashboard.add(new JScrollPane(new DashboardPanel()), BorderLayout.CENTER);
+ getContentPane().add(access_panel, BorderLayout.EAST);
+
+ desk.addDockable(dashboard);
+ desk.addDockable(cool_bar);
+ desk.setAutoHide(cool_bar, true);
- current_file = new JLabel();
- line_info = new JLabel();
- line_perc = new JLabel();
- charset = new JLabel();
- seekBar = new JProgressBar();
- seekBar.setValue(50);
+ desk.split(dashboard, render_panel, DockingConstants.SPLIT_RIGHT, 0.7);
+ desk.split(render_panel, access_panel, DockingConstants.SPLIT_BOTTOM);
- var file = getSelectedEditor().file;
+ win = this;
- if (file != null) {
- current_file.setText(file.toString());
- } else {
- current_file.setText("[NONE]");
- }
-
- var bottom_bar = makeLRToolBar(new Component[]{
- current_file,
- null
- }, new Component[]{
- line_info,
- line_perc,
- seekBar,
- null,
- charset,});
- main_panel.add(bottom_bar, BorderLayout.PAGE_END);
-
- tabs.addChangeListener(c -> {
- var ed = getSelectedEditor();
- if (ed == null) {
- return;
- }
- CodeEditor.getCursorPositionText(ed);
- });
-
- this.setIconImage(Icons.getIcon("appicon").getImage());
- this.add(main_panel);
this.setSize(width, height);
this.setLocationRelativeTo(null);
this.setVisible(true);
@@ -257,42 +235,58 @@ private void initSearchDialogs() {
}
public static void addTab(ActionEvent e) {
- var index = tabs.getTabCount();
- var editor = new CodeEditor();
- if (index >= 1) {
- tabs.remove(index - 1);
- index = tabs.getTabCount();
- }
+ int index = tabEditors.size();
+ CodeEditor editor = new CodeEditor();
+ editor.tabIndex = index;
+ Path file = editor.file;
+ editor.requestFocusInWindow();
+ current_file.setText(file != null ? file.toString() : "[NONE]");
tabEditors.put(index, editor);
- tabs.addTab("", editor);
- tabs.setTabComponentAt(tabs.getTabCount() - 1, makeTabHeader(tabs, editor.file == null ? "Tab " + index : editor.filePathTruncated()));
- if (index >= 0) {
- addPlusTab(tabs);
+
+ // Add first editor normally
+ if (index == 0) {
+ win.desk.addDockable(editor);
+ win.desk.createTab(win.dashboard, editor, 2);
+ } else {
+ // Add to same container as first editor
+ CodeEditor firstEditor = tabEditors.get(0);
+ win.desk.createTab(firstEditor, editor, 2);
}
- tabs.setSelectedIndex(index);
}
public static void addTab(Path path, Void e) {
- var index = tabs.getTabCount();
- var editor = new CodeEditor();
- editor.file = path;
- if (index >= 1) {
- tabs.remove(index - 1);
- index = tabs.getTabCount();
- }
+ var index = tabEditors.size();
+ var editor = new CodeEditor(path);
+ editor.tabIndex = index;
+ editor.load(path.toFile());
+ editor.requestFocusInWindow();
tabEditors.put(index, editor);
- tabs.addTab("", editor);
- tabs.setTabComponentAt(tabs.getTabCount() - 1, makeTabHeader(tabs, editor.file == null ? "Tab " + index : editor.filePathTruncated()));
- if (index >= 0) {
- addPlusTab(tabs);
+
+ // Add first editor normally
+ if (index == 0) {
+ win.desk.createTab(win.dashboard, editor, 2);
+ } else {
+ // Add to same container as first editor
+ CodeEditor firstEditor = tabEditors.get(0);
+ win.desk.createTab(firstEditor, editor, 1);
}
- tabs.setSelectedIndex(index);
+ }
+
+ public static void setSelectedEditor(CodeEditor ed) {
+ selected = ed;
}
public static CodeEditor getSelectedEditor() {
- int index = tabs.getSelectedIndex();
- var ed = tabEditors.get(index);
- return ed;
+ if (selected != null) {
+ return selected;
+ }
+
+ for (var editor : tabEditors.values()) {
+ if (editor.textArea.isFocusOwner()) {
+ return editor;
+ }
+ }
+ return tabEditors.values().toArray(CodeEditor[]::new)[0]; // fallback if nothing has focus
}
private static void addPlusTab(JTabbedPane tabs) {
@@ -340,62 +334,90 @@ private static Component makeTabHeader(JTabbedPane tabs, String title) {
}
public static void removeTab() {
- if (tabs.getTabCount() == 1) {
+ if (tabEditors.size() <= 1) {
return;
}
- int index = tabs.getSelectedIndex();
- var ed = tabEditors.get(index);
- removeIfDirty(index, ed);
+ CodeEditor selected = getSelectedEditor();
+ if (selected == null) {
+ return;
+ }
+
+ Integer index = getEditorIndex(selected);
+ if (index == null) {
+ return;
+ }
+
+ removeIfDirty(index, selected);
}
public static void removeAllTabs() {
- int count = tabs.getTabCount();
- for (int index = 0; index < count - 1; index++) {
- var ed = tabEditors.get(index);
- if (ed == null) {
- continue;
- }
- removeIfDirty(index, ed);
+ var editors = new HashMap<>(tabEditors); // Copy to avoid ConcurrentModificationException
+ for (var entry : editors.entrySet()) {
+ removeIfDirty(entry.getKey(), entry.getValue());
}
- addTab(null);
- removeTab();
}
public static int tabsCount() {
- return tabs.getTabCount();
+ return tabEditors.size();
}
-
- private static void removeIfDirty(Integer index, CodeEditor ed) {
+
+ private static boolean removeIfDirty(Integer index, CodeEditor ed) {
if (ed.textArea.isDirty()) {
int result = JOptionPane.showConfirmDialog(win, "File " + ed.filePathTruncated() + " is modified. Save?");
if (result == JOptionPane.OK_OPTION) {
- if (!ed.saveFile()) {
- return;
- }
+ return ed.saveFile();
}
}
+ win.desk.remove((Dockable) ed); // Actual removal from docking layout
tabEditors.remove(index);
- tabs.remove(index);
- int last = migrateIndexes();
- tabs.setSelectedIndex(last);
+ migrateIndexes();
+
+ return true;
}
- private static int migrateIndexes() {
- int index = 0;
- tabEditors.clear();
- for (int i = 0; i < tabs.getTabCount(); i++) {
- var comp = tabs.getComponentAt(i);
- if (comp instanceof CodeEditor ed) {
- tabEditors.put(i, ed);
- index = Math.max(index, i);
+ private static boolean isDocked(Dockable d) {
+ for (var state: win.desk.getDockables()) {
+ var dockable = state.getDockable();
+ if (dockable == d || dockable.equals(d)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Integer getEditorIndex(CodeEditor ed) {
+ for (var entry : tabEditors.entrySet()) {
+ if (entry.getValue() == ed) {
+ return entry.getKey();
}
}
- return index;
+ return null;
+ }
+
+ private static void migrateIndexes() {
+ HashMap newMap = new HashMap<>();
+ int idx = 0;
+ for (CodeEditor ed : tabEditors.values()) {
+ newMap.put(idx++, ed);
+ }
+ tabEditors = newMap;
+ }
+
+ public static void saveAll() {
+ for (var kv : tabEditors.entrySet()) {
+ var editor = kv.getValue();
+ editor.saveFile();
+ }
+ }
+
+ public static void setSeletedTabTitle(String title) {
+ int index = tabs.getSelectedIndex();
+ tabs.setTitleAt(index, title);
}
private JPanel makeCoolbar(int height, Action... actions) {
- JPanel cool_bar = new JPanel(new BorderLayout());
+ var cool_bar = new JPanel(new BorderLayout());
cool_bar.setPreferredSize(new Dimension(50, height));
JPanel top_buttons = new JPanel(new GridLayout(10, 1));
top_buttons.setOpaque(false); // transparent to inherit background
@@ -415,6 +437,7 @@ private JPanel makeCoolbar(int height, Action... actions) {
bottom_button.add(settingsBtn, BorderLayout.SOUTH);
cool_bar.add(top_buttons, BorderLayout.NORTH);
cool_bar.add(bottom_button, BorderLayout.SOUTH);
+
return cool_bar;
}
@@ -502,4 +525,13 @@ public String getSelectedText() {
return getSelectedEditor().textArea.getSelectedText();
}
+ private void customizeDock() {
+ UIManager.put("DockViewTitleBar.close", (Icon) Icons.getIcon("close"));
+ UIManager.put("DockTabbedPane.close", (Icon) Icons.getIcon("close"));
+ UIManager.put("DockViewTitleBar.isFloatButtonDisplayed", true);
+
+ var font = (Font)UIManager.get("DockViewTitleBar.titleFont");
+ UIManager.put("DockViewTitleBar.titleFont", new Font(font.getName(), font.getStyle(), 11));
+ }
+
}
diff --git a/src/main/java/org/editor/events/Actions.java b/src/main/java/org/editor/events/Actions.java
index 1cd8574..d521bea 100644
--- a/src/main/java/org/editor/events/Actions.java
+++ b/src/main/java/org/editor/events/Actions.java
@@ -179,7 +179,7 @@ public static void loadActions() {
.icon("save-all")
.tooltip("Save All")
.shortcut("control shift S")
- .handler(e -> It.todo())
+ .handler(MenuEvents::saveAllFiles)
.build();
exitAction
diff --git a/src/main/java/org/editor/events/ListAction.java b/src/main/java/org/editor/events/ListAction.java
new file mode 100644
index 0000000..9742d13
--- /dev/null
+++ b/src/main/java/org/editor/events/ListAction.java
@@ -0,0 +1,77 @@
+package org.editor.events;
+
+/**
+ *
+ * @author hexaredecimal
+ */
+import java.awt.event.*;
+import javax.swing.*;
+
+
+// Reference: https://stackoverflow.com/questions/4344682/double-click-event-on-jlist-element
+public class ListAction implements MouseListener {
+
+ private static final KeyStroke ENTER = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
+
+ private JList list;
+ private KeyStroke keyStroke;
+
+ /*
+ * Add an Action to the JList bound by the default KeyStroke
+ */
+ public ListAction(JList list, Action action) {
+ this(list, action, ENTER);
+ }
+
+ /*
+ * Add an Action to the JList bound by the specified KeyStroke
+ */
+ public ListAction(JList list, Action action, KeyStroke keyStroke) {
+ this.list = list;
+ this.keyStroke = keyStroke;
+
+ // Add the KeyStroke to the InputMap
+ InputMap im = list.getInputMap();
+ im.put(keyStroke, keyStroke);
+
+ // Add the Action to the ActionMap
+ setAction(action);
+
+ // Handle mouse double click
+ list.addMouseListener(this);
+ }
+
+ /*
+ * Add the Action to the ActionMap
+ */
+ public void setAction(Action action) {
+ list.getActionMap().put(keyStroke, action);
+ }
+
+ // Implement MouseListener interface
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ Action action = list.getActionMap().get(keyStroke);
+
+ if (action != null) {
+ ActionEvent event = new ActionEvent(
+ list,
+ ActionEvent.ACTION_PERFORMED,
+ "");
+ action.actionPerformed(event);
+ }
+ }
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ public void mouseExited(MouseEvent e) {
+ }
+
+ public void mousePressed(MouseEvent e) {
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ }
+}
diff --git a/src/main/java/org/editor/events/MenuEvents.java b/src/main/java/org/editor/events/MenuEvents.java
index 7370463..31774f5 100644
--- a/src/main/java/org/editor/events/MenuEvents.java
+++ b/src/main/java/org/editor/events/MenuEvents.java
@@ -1,6 +1,5 @@
package org.editor.events;
-
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.nio.file.Files;
@@ -14,6 +13,7 @@
import org.editor.CodeEditor;
import org.editor.EditorWindow;
import org.editor.dialogs.AboutDialog;
+import org.editor.fs.FileFilter;
import org.fife.rsta.ui.GoToDialog;
import org.fife.ui.rsyntaxtextarea.FileLocation;
@@ -64,15 +64,15 @@ static void findEvent(ActionEvent e) {
}
findDialog.setVisible(true);
}
-
+
public static void aboutDialog(ActionEvent e) {
- var _ = new AboutDialog(EditorWindow.win);
+ var _ = new AboutDialog(EditorWindow.win);
}
public static void closeTab(ActionEvent e) {
EditorWindow.removeTab();
}
-
+
public static void closeAllTabs(ActionEvent e) {
EditorWindow.removeAllTabs();
}
@@ -80,6 +80,9 @@ public static void closeAllTabs(ActionEvent e) {
static void openFile(ActionEvent e) {
// TODO: Use the System object to get the current pwd
var fileChooser = new JFileChooser(".");
+ fileChooser.setFileFilter(FileFilter.mdFilter);
+ fileChooser.setFileFilter(FileFilter.picsFilter);
+
int status = fileChooser.showOpenDialog(EditorWindow.win);
if (status != JFileChooser.APPROVE_OPTION) {
return;
@@ -87,31 +90,27 @@ static void openFile(ActionEvent e) {
var fp = fileChooser.getSelectedFile();
var path = fp.toPath();
- try {
- EditorWindow.addTab(path, null);
- var loc = FileLocation.create(fp);
- var ed = EditorWindow.getSelectedEditor();
- ed.setIsTmp(false);
- ed.textArea.load(loc);
- } catch (IOException ex) {
- JOptionPane.showMessageDialog(EditorWindow.win, ex);
- }
+ EditorWindow.addTab(path, null);
}
static void saveFile(ActionEvent e) {
- if (EditorWindow.tabsCount() == 1) {
- return;
- }
- var ed = EditorWindow.getSelectedEditor();
- ed.saveFile();
+ if (EditorWindow.tabsCount() == 1) {
+ return;
+ }
+ var ed = EditorWindow.getSelectedEditor();
+ ed.saveFile();
}
-
+
static void saveFileAs(ActionEvent e) {
- if (EditorWindow.tabsCount() == 1) {
- return;
- }
- var ed = EditorWindow.getSelectedEditor();
- ed.saveFileAs();
+ if (EditorWindow.tabsCount() == 1) {
+ return;
+ }
+ var ed = EditorWindow.getSelectedEditor();
+ ed.saveFileAs();
+ }
+
+ static void saveAllFiles(ActionEvent e) {
+ EditorWindow.saveAll();
}
static void closeFile(ActionEvent e) {
diff --git a/src/main/java/org/editor/fs/FileFilter.java b/src/main/java/org/editor/fs/FileFilter.java
new file mode 100644
index 0000000..cc946a7
--- /dev/null
+++ b/src/main/java/org/editor/fs/FileFilter.java
@@ -0,0 +1,13 @@
+package org.editor.fs;
+
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+/**
+ *
+ * @author hexaredecimal
+ */
+public class FileFilter {
+ public static final FileNameExtensionFilter picsFilter = new FileNameExtensionFilter("Piccasso Script Files", "pics");
+ public static final FileNameExtensionFilter mdFilter = new FileNameExtensionFilter("Markdown Files", "md");
+ public static final FileNameExtensionFilter allFilter = new FileNameExtensionFilter("All Files (*.*)", "*");
+}
diff --git a/src/main/java/org/editor/fs/FilePersistance.java b/src/main/java/org/editor/fs/FilePersistance.java
new file mode 100644
index 0000000..cdd1056
--- /dev/null
+++ b/src/main/java/org/editor/fs/FilePersistance.java
@@ -0,0 +1,88 @@
+package org.editor.fs;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author hexaredecimal
+ */
+public class FilePersistance {
+ private static final List EMPTY = new ArrayList<>();
+ private static final String RECENT_FILES = "./etc/rf/xxx.yy";
+ private static final String RECENT_PROJECTS = "./etc/rf/xxx.yy";
+
+ public static List getRecentFiles() {
+ return getFiles(RECENT_FILES);
+ }
+
+ public static List getRecentProjects() {
+ return getFiles(RECENT_PROJECTS);
+ }
+
+ public static boolean isFilePersisted(Path path) {
+ var name = path.toString();
+ return getRecentFiles().contains(name);
+ }
+
+ public static boolean isProjectPersisted(Path path) {
+ var name = path.toString();
+ return getRecentFiles().contains(name);
+ }
+
+ public static void persistProject(Path path) {
+ persistTo(path, RECENT_PROJECTS);
+ }
+
+ public static void persistFile(Path path) {
+ persistTo(path, RECENT_PROJECTS);
+ }
+
+
+ private static void persistTo(Path path, String dir) {
+ if (isFilePersisted(path)) {
+ return;
+ }
+ var files = getRecentFiles();
+ files.addFirst(path.toString());
+ var dest = new File(dir).toPath();
+ try {
+ Files.write(dest, files);
+ } catch (IOException ex) {
+ Logger.getLogger(FilePersistance.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ private static List getFiles(String file) {
+ var fp = new File(file);
+
+
+ if (!fp.exists()) {
+ try {
+ fp.createNewFile();
+ return EMPTY;
+ } catch (IOException ex) {
+ return EMPTY;
+ }
+ }
+
+ try {
+ var contents = Files.readString(fp.toPath());
+ var items = contents
+ .lines()
+ .limit(15) // TODO: Allow this to be customizable throw the settings
+ .toList();
+ var mutableList = new ArrayList();
+ items.forEach(item -> mutableList.add(item));
+ return mutableList;
+ } catch (IOException ex) {
+ return EMPTY;
+ }
+ }
+}
diff --git a/src/main/java/org/editor/menu/Menus.java b/src/main/java/org/editor/menu/Menus.java
index b7173cb..01371cc 100644
--- a/src/main/java/org/editor/menu/Menus.java
+++ b/src/main/java/org/editor/menu/Menus.java
@@ -1,6 +1,8 @@
package org.editor.menu;
import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.io.File;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ImageIcon;
@@ -9,8 +11,10 @@
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
+import org.editor.EditorWindow;
import org.editor.SearchInput;
import org.editor.events.Actions;
+import org.editor.fs.FilePersistance;
import org.editor.icons.Icons;
import org.fife.ui.rtextarea.RTextArea;
@@ -19,7 +23,7 @@
* @author hexaredecimal
*/
public class Menus {
-
+
public static void addMenus(JMenuBar menu_bar) {
addFileMenu(menu_bar);
addEditMenu(menu_bar);
@@ -37,9 +41,9 @@ public static void addMenus(JMenuBar menu_bar) {
searchField.setMaximumSize(new Dimension(150, searchSize.height)); // Limit max width
menu_bar.add(searchField);
menu_bar.add(Box.createRigidArea(new Dimension(5, 0)));
-
+
Action[] actions = {Actions.navBottom, Actions.navTop, Actions.navLeft, Actions.navRight};
- for (var action: actions) {
+ for (var action : actions) {
JButton btn = new JButton(action);
btn.setText("");
menu_bar.add(btn);
@@ -56,16 +60,28 @@ private static void addFileMenu(JMenuBar menu_bar) {
JMenu recents = new JMenu("Recent Projects");
recents.setIcon(Icons.getIcon("time-machine"));
fileMenu.add(recents);
-
+
fileMenu.add(new JMenuItem(Actions.closeProjectAction));
fileMenu.addSeparator();
fileMenu.add(new JMenuItem(Actions.openFileAction));
-
+
JMenu recentfiles = new JMenu("Recent Files");
recentfiles.setIcon(Icons.getIcon("restore-page"));
+
+ FilePersistance
+ .getRecentFiles()
+ .forEach(item -> {
+ var fp = new File(item);
+ var menuItem = createMenuItem(fp.getName(), "file", (e) -> {
+ var path = fp.toPath();
+ EditorWindow.addTab(path, null);
+ });
+ recentfiles.add(menuItem);
+ });
+
fileMenu.add(recentfiles);
-
+
fileMenu.add(new JMenuItem(Actions.closeFileAction));
fileMenu.addSeparator();
@@ -103,11 +119,11 @@ private static void addEditMenu(JMenuBar menu_bar) {
private static void addNavigateMenu(JMenuBar menu_bar) {
JMenu navMenu = new JMenu("Navigage");
-
+
JMenu tabs = new JMenu("Tabs");
tabs.setIcon(Icons.getIcon("layout"));
navMenu.add(tabs);
-
+
tabs.add(new JMenuItem(Actions.gotoTabAction));
tabs.add(new JMenuItem(Actions.addTabAction));
tabs.add(new JMenuItem(Actions.removeTabAction));
@@ -115,10 +131,10 @@ private static void addNavigateMenu(JMenuBar menu_bar) {
tabs.add(new JMenuItem(Actions.removeAllTabsAction));
tabs.addSeparator();
tabs.add(createMenuItem("[Tab: 0]", "restore-window"));
-
+
navMenu.addSeparator();
navMenu.add(new JMenuItem(Actions.gotoFileAction));
-
+
menu_bar.add(navMenu);
}
@@ -138,10 +154,10 @@ private static void addToolMenu(JMenuBar menu_bar) {
toolsMenu.addSeparator();
toolsMenu.add(new JMenuItem(Actions.optionsAction));
toolsMenu.addSeparator();
-
+
JMenu renderToolsMenu = new JMenu("Tools");
renderToolsMenu.setIcon(Icons.getIcon("tools"));
-
+
renderToolsMenu.add(new JMenuItem(Actions.normalAction));
renderToolsMenu.add(new JMenuItem(Actions.gridAction));
renderToolsMenu.add(new JMenuItem(Actions.pointAction));
@@ -151,11 +167,11 @@ private static void addToolMenu(JMenuBar menu_bar) {
renderToolsMenu.add(new JMenuItem(Actions.thickBrushAction));
renderToolsMenu.add(new JMenuItem(Actions.paintBucketAction));
renderToolsMenu.add(new JMenuItem(Actions.effectsAction));
-
+
toolsMenu.add(renderToolsMenu);
menu_bar.add(toolsMenu);
}
-
+
private static void addHelp(JMenuBar menu_bar) {
JMenu helpMenu = new JMenu("Help");
helpMenu.add(new JMenuItem(Actions.docsAction));
@@ -165,28 +181,23 @@ private static void addHelp(JMenuBar menu_bar) {
helpMenu.add(new JMenuItem(Actions.aboutAction));
menu_bar.add(helpMenu);
}
-
- private static JMenuItem createMenuItem(Action action) {
- JMenuItem item = new JMenuItem(action);
- item.setToolTipText(null); // Swing annoyingly adds tool tip text to the menu item
- return item;
- }
-
- private static JMenuItem createMenuItem(String text) {
- JMenuItem item = new JMenuItem(text);
+
+ private static JMenuItem createMenuItem(String text, String icon) {
+ JMenuItem item = new JMenuItem(text, Icons.getIcon(icon));
return item;
}
-
- private static JMenuItem createMenuItem(String text, String icon) {
+
+ private static JMenuItem createMenuItem(String text, String icon, ActionListener listener) {
JMenuItem item = new JMenuItem(text, Icons.getIcon(icon));
+ item.addActionListener(listener);
return item;
}
-
+
private static JMenuItem createMenuItem(String icon, Action action, String tooltip) {
JMenuItem item = new JMenuItem(action);
item.setIcon(Icons.getIcon(icon));
item.setToolTipText(tooltip); // Swing annoyingly adds tool tip text to the menu item
return item;
}
-
+
}
diff --git a/src/main/java/org/editor/panels/DashboardPanel.form b/src/main/java/org/editor/panels/DashboardPanel.form
index 254de04..19bfffe 100644
--- a/src/main/java/org/editor/panels/DashboardPanel.form
+++ b/src/main/java/org/editor/panels/DashboardPanel.form
@@ -18,11 +18,14 @@
-
+
-
+
+
+
+
@@ -36,11 +39,15 @@
-
-
-
+
+
+
+
+
+
+
-
+
@@ -60,7 +67,7 @@
-
+
@@ -72,15 +79,39 @@
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -172,5 +203,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/editor/panels/DashboardPanel.java b/src/main/java/org/editor/panels/DashboardPanel.java
index dab84b6..4936b7e 100644
--- a/src/main/java/org/editor/panels/DashboardPanel.java
+++ b/src/main/java/org/editor/panels/DashboardPanel.java
@@ -4,6 +4,21 @@
*/
package org.editor.panels;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.io.File;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import org.editor.EditorWindow;
+import org.editor.events.ListAction;
+import org.editor.fs.FilePersistance;
+import org.editor.icons.Icons;
+
/**
*
* @author hexaredecimal
@@ -15,6 +30,7 @@ public class DashboardPanel extends javax.swing.JPanel {
*/
public DashboardPanel() {
initComponents();
+ loadPersistedState();
}
/**
@@ -28,6 +44,8 @@ private void initComponents() {
jLabel1 = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
+ jScrollPane2 = new javax.swing.JScrollPane();
+ rFilesList = new javax.swing.JList<>(filesModel);
jPanel2 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
@@ -35,24 +53,34 @@ private void initComponents() {
jCheckBox1 = new javax.swing.JCheckBox();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
+ jPanel3 = new javax.swing.JPanel();
+ jScrollPane3 = new javax.swing.JScrollPane();
+ rProjList = new javax.swing.JList<>();
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/applogo/dashboard.png"))); // NOI18N
jLabel1.setToolTipText("");
jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jLabel1.setName(""); // NOI18N
- jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Recent Projects", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("sansserif", 1, 13), new java.awt.Color(255, 153, 51))); // NOI18N
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Recent Files", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("sansserif", 1, 13), new java.awt.Color(255, 153, 51))); // NOI18N
jPanel1.setAutoscrolls(true);
+ jScrollPane2.setViewportView(rFilesList);
+
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 339, Short.MAX_VALUE)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jScrollPane2)
+ .addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 0, Short.MAX_VALUE)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 121, Short.MAX_VALUE)
+ .addContainerGap())
);
jPanel2.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true));
@@ -111,17 +139,40 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addContainerGap())
);
+ jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Recent Projects", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("sansserif", 1, 13), new java.awt.Color(255, 153, 51))); // NOI18N
+ jPanel3.setAutoscrolls(true);
+
+ jScrollPane3.setViewportView(rProjList);
+
+ javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
+ jPanel3.setLayout(jPanel3Layout);
+ jPanel3Layout.setHorizontalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jScrollPane3)
+ .addContainerGap())
+ );
+ jPanel3Layout.setVerticalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(56, 56, 56)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addComponent(jLabel1))
.addContainerGap(56, Short.MAX_VALUE))
);
@@ -131,17 +182,66 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addContainerGap()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 401, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addContainerGap(15, Short.MAX_VALUE))
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(17, Short.MAX_VALUE))
);
}// //GEN-END:initComponents
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
- // TODO add your handling code here:
+ // TODO add your handling code here:
}//GEN-LAST:event_jButton1ActionPerformed
+ private void loadPersistedState() {
+ FilePersistance
+ .getRecentFiles()
+ .forEach(item -> {
+ var fp = new File(item);
+ var path = fp.toPath().toString();
+ filesModel.addElement(new ListItem(path, Icons.getIcon("file")));
+ });
+
+ Action displayAction = new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ var list = (JList) e.getSource();
+ var value = list.getSelectedValue().name;
+ EditorWindow.addTab(new File(value).toPath(), null);
+ }
+ };
+
+ rFilesList.setCellRenderer(new ListItemRenderer());
+ var _ = new ListAction(rFilesList, displayAction);
+ }
+
+ private static DefaultListModel filesModel = new DefaultListModel<>();
+ private static DefaultListModel projectModel = new DefaultListModel<>();
+
+ class ListItem {
+
+ String name;
+ Icon icon;
+
+ public ListItem(String name, Icon icon) {
+ this.name = name;
+ this.icon = icon;
+ }
+ }
+
+ class ListItemRenderer extends DefaultListCellRenderer {
+
+ @Override
+ public Component getListCellRendererComponent(JList> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ ListItem item = (ListItem) value;
+ JLabel label = (JLabel) super.getListCellRendererComponent(list, item.name, index, isSelected, cellHasFocus);
+ label.setIcon(item.icon);
+ return label;
+ }
+ }
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
@@ -153,5 +253,10 @@ private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
+ private javax.swing.JPanel jPanel3;
+ private javax.swing.JScrollPane jScrollPane2;
+ private javax.swing.JScrollPane jScrollPane3;
+ private javax.swing.JList rFilesList;
+ private javax.swing.JList rProjList;
// End of variables declaration//GEN-END:variables
}