Merge pull request #242 from atnayan/Single-Instance

Excellent Contributions by atnayan
This commit is contained in:
Josh 2021-03-17 16:07:50 -04:00 committed by GitHub
commit 6558b5d440
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 204 additions and 84 deletions

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>us.deathmarine</groupId> <groupId>us.deathmarine</groupId>
<artifactId>luyten</artifactId> <artifactId>luyten</artifactId>
<version>0.5.4</version> <version>0.7.0</version>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.fifesoft</groupId> <groupId>com.fifesoft</groupId>

View File

@ -65,11 +65,14 @@ public class FindAllBox extends JDialog {
private Thread tmp_thread; private Thread tmp_thread;
private MainWindow mainWindow;
public FindAllBox(final MainWindow mainWindow) { public FindAllBox(final MainWindow mainWindow) {
this.setDefaultCloseOperation(HIDE_ON_CLOSE); this.setDefaultCloseOperation(HIDE_ON_CLOSE);
this.setHideOnEscapeButton(); this.setHideOnEscapeButton();
progressBar = new JProgressBar(0, 100); progressBar = new JProgressBar(0, 100);
this.mainWindow = mainWindow;
JLabel label = new JLabel("Find What:"); JLabel label = new JLabel("Find What:");
textField = new JTextField(); textField = new JTextField();
@ -99,7 +102,7 @@ public class FindAllBox extends JDialog {
String internalName = StringUtilities.removeRight(entryName, ".class"); String internalName = StringUtilities.removeRight(entryName, ".class");
TypeReference type = Model.metadataSystem.lookupType(internalName); TypeReference type = Model.metadataSystem.lookupType(internalName);
try { try {
mainWindow.getModel().extractClassToTextPane(type, array[array.length - 1], entryName, mainWindow.getSelectedModel().extractClassToTextPane(type, array[array.length - 1], entryName,
null); null);
} catch (Exception e) { } catch (Exception e) {
Luyten.showExceptionDialog("Exception!", e); Luyten.showExceptionDialog("Exception!", e);
@ -107,8 +110,8 @@ public class FindAllBox extends JDialog {
} else { } else {
try { try {
JarFile jfile = new JarFile(MainWindow.model.getOpenedFile()); JarFile jfile = new JarFile(mainWindow.getSelectedModel().getOpenedFile());
mainWindow.getModel().extractSimpleFileEntryToTextPane( mainWindow.getSelectedModel().extractSimpleFileEntryToTextPane(
jfile.getInputStream(jfile.getEntry(entryName)), array[array.length - 1], jfile.getInputStream(jfile.getEntry(entryName)), array[array.length - 1],
entryName); entryName);
jfile.close(); jfile.close();
@ -196,7 +199,7 @@ public class FindAllBox extends JDialog {
classesList.clear(); classesList.clear();
ConfigSaver configSaver = ConfigSaver.getLoadedInstance(); ConfigSaver configSaver = ConfigSaver.getLoadedInstance();
DecompilerSettings settings = configSaver.getDecompilerSettings(); DecompilerSettings settings = configSaver.getDecompilerSettings();
File inFile = MainWindow.model.getOpenedFile(); File inFile = mainWindow.getSelectedModel().getOpenedFile();
boolean filter = ConfigSaver.getLoadedInstance().getLuytenPreferences() boolean filter = ConfigSaver.getLoadedInstance().getLuytenPreferences()
.isFilterOutInnerClassEntries(); .isFilterOutInnerClassEntries();
try { try {

View File

@ -54,7 +54,7 @@ public class FindBox extends JDialog {
JLabel label = new JLabel("Find What:"); JLabel label = new JLabel("Find What:");
textField = new JTextField(); textField = new JTextField();
RSyntaxTextArea pane = mainWindow.getModel().getCurrentTextArea(); RSyntaxTextArea pane = mainWindow.getSelectedModel().getCurrentTextArea();
if (pane != null) { if (pane != null) {
textField.setText(pane.getSelectedText()); textField.setText(pane.getSelectedText());
} }
@ -132,7 +132,7 @@ public class FindBox extends JDialog {
if (textField.getText().length() == 0) if (textField.getText().length() == 0)
return; return;
RSyntaxTextArea pane = mainWindow.getModel().getCurrentTextArea(); RSyntaxTextArea pane = mainWindow.getSelectedModel().getCurrentTextArea();
if (pane == null) if (pane == null)
return; return;
@ -207,7 +207,7 @@ public class FindBox extends JDialog {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (textField.getText().length() == 0) if (textField.getText().length() == 0)
return; return;
RSyntaxTextArea pane = mainWindow.getModel().getCurrentTextArea(); RSyntaxTextArea pane = mainWindow.getSelectedModel().getCurrentTextArea();
if (pane == null) if (pane == null)
return; return;
SearchContext context = new SearchContext(); SearchContext context = new SearchContext();

View File

@ -7,13 +7,11 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.io.BufferedReader; import java.io.*;
import java.io.File; import java.net.ServerSocket;
import java.io.IOException; import java.net.Socket;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI; import java.net.URI;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
@ -40,8 +38,20 @@ public class Luyten {
private static final AtomicReference<MainWindow> mainWindowRef = new AtomicReference<>(); private static final AtomicReference<MainWindow> mainWindowRef = new AtomicReference<>();
private static final List<File> pendingFiles = new ArrayList<>(); private static final List<File> pendingFiles = new ArrayList<>();
private static ServerSocket lockSocket = null;
public static void main(String[] args) { public static void main(final String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
try {
if (lockSocket != null) {
lockSocket.close();
}
} catch (IOException e) {
}
}
}));
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
@ -55,12 +65,41 @@ public class Luyten {
// .zip or .jar) // .zip or .jar)
final File fileFromCommandLine = getFileFromCommandLine(args); final File fileFromCommandLine = getFileFromCommandLine(args);
try {
launchMainInstance(fileFromCommandLine);
} catch (Exception e) {
// Instance already exists. Open new file in running instance
try {
Socket socket = new Socket("localhost", 3456);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(args[0]);
dos.flush();
dos.close();
socket.close();
} catch (IOException ex) {
showExceptionDialog("Exception", e);
}
}
}
private static void launchMainInstance(final File fileFromCommandLine) throws IOException {
lockSocket = new ServerSocket(3456);
launchSession(fileFromCommandLine);
new Thread(new Runnable() {
@Override
public void run() {
launchServer();
}
}).start();
}
private static void launchSession(final File fileFromCommandLine) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!mainWindowRef.compareAndSet(null, new MainWindow(fileFromCommandLine))) { if (!mainWindowRef.compareAndSet(null, new MainWindow(fileFromCommandLine))) {
// Already set - so add the files to open // Already set - so add the files to open
openFileInInstance(fileFromCommandLine); addToPendingFiles(fileFromCommandLine);
} }
processPendingFiles(); processPendingFiles();
mainWindowRef.get().setVisible(true); mainWindowRef.get().setVisible(true);
@ -68,14 +107,29 @@ public class Luyten {
}); });
} }
private static void launchServer() {
try { // Server
while (true) {
Socket socket = lockSocket.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
addToPendingFiles(getFileFromCommandLine(dis.readUTF()));
processPendingFiles();
dis.close();
socket.close();
}
} catch (IOException e) { // Client
showExceptionDialog("Exception", e);
}
}
// Private function which processes all pending files - synchronized on the // Private function which processes all pending files - synchronized on the
// list of pending files // list of pending files
private static void processPendingFiles() { public static void processPendingFiles() {
final MainWindow mainWindow = mainWindowRef.get(); final MainWindow mainWindow = mainWindowRef.get();
if (mainWindow != null) { if (mainWindow != null) {
synchronized (pendingFiles) { synchronized (pendingFiles) {
for (File f : pendingFiles) { for (File f : pendingFiles) {
mainWindow.getModel().loadFile(f); mainWindow.loadNewFile(f);
} }
pendingFiles.clear(); pendingFiles.clear();
} }
@ -84,13 +138,12 @@ public class Luyten {
// Function which opens the given file in the instance, if it's running - // Function which opens the given file in the instance, if it's running -
// and if not, it processes the files // and if not, it processes the files
public static void openFileInInstance(File fileToOpen) { public static void addToPendingFiles(File fileToOpen) {
synchronized (pendingFiles) { synchronized (pendingFiles) {
if (fileToOpen != null) { if (fileToOpen != null) {
pendingFiles.add(fileToOpen); pendingFiles.add(fileToOpen);
} }
} }
processPendingFiles();
} }
// Function which exits the application if it's running // Function which exits the application if it's running
@ -101,7 +154,7 @@ public class Luyten {
} }
} }
public static File getFileFromCommandLine(String[] args) { public static File getFileFromCommandLine(String... args) {
File fileFromCommandLine = null; File fileFromCommandLine = null;
try { try {
if (args.length > 0) { if (args.length > 0) {

View File

@ -16,7 +16,8 @@ public class LuytenOsx extends Luyten {
Application app = new Application(); Application app = new Application();
app.addApplicationListener(new ApplicationAdapter() { app.addApplicationListener(new ApplicationAdapter() {
public void handleOpenFile(ApplicationEvent e) { public void handleOpenFile(ApplicationEvent e) {
Luyten.openFileInInstance(new File(e.getFilename())); Luyten.addToPendingFiles(new File(e.getFilename()));
Luyten.processPendingFiles();
} }
public void handleQuit(ApplicationEvent e) { public void handleQuit(ApplicationEvent e) {

View File

@ -167,7 +167,7 @@ public class MainMenuBar extends JMenuBar {
menuItem.addActionListener(new ActionListener() { menuItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
mainWindow.getModel().loadFile(file); mainWindow.loadNewFile(file);
} }
}); });
recentFiles.add(menuItem); recentFiles.add(menuItem);
@ -196,12 +196,12 @@ public class MainMenuBar extends JMenuBar {
menuItem.addActionListener(new ActionListener() { menuItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
JTabbedPane house = mainWindow.getModel().house; JTabbedPane house = mainWindow.getSelectedModel().house;
if (e.getModifiers() != 2 || house.getTabCount() == 0) if (e.getModifiers() != 2 || house.getTabCount() == 0)
mainWindow.onCloseFileMenu(); mainWindow.onCloseFileMenu();
else { else {
mainWindow.getModel().closeOpenTab(house.getSelectedIndex()); mainWindow.getSelectedModel().closeOpenTab(house.getSelectedIndex());
} }
} }
}); });

View File

@ -15,20 +15,12 @@ import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.Iterator; import java.util.*;
import java.util.Vector; import java.util.concurrent.Callable;
import javax.swing.AbstractAction; import javax.swing.*;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.border.BevelBorder; import javax.swing.border.BevelBorder;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
@ -39,8 +31,8 @@ public class MainWindow extends JFrame {
private static final long serialVersionUID = 5265556630724988013L; private static final long serialVersionUID = 5265556630724988013L;
private static final String TITLE = "Luyten"; private static final String TITLE = "Luyten";
private static final String DEFAULT_TAB = "#DEFAULT";
public static Model model;
private JProgressBar bar; private JProgressBar bar;
private JLabel label; private JLabel label;
FindBox findBox; FindBox findBox;
@ -50,13 +42,16 @@ public class MainWindow extends JFrame {
private LuytenPreferences luytenPrefs; private LuytenPreferences luytenPrefs;
private FileDialog fileDialog; private FileDialog fileDialog;
private FileSaver fileSaver; private FileSaver fileSaver;
private JTabbedPane jarsTabbedPane;
private Map<String, Model> jarModels;
public MainMenuBar mainMenuBar; public MainMenuBar mainMenuBar;
public MainWindow(File fileFromCommandLine) { public MainWindow(File fileFromCommandLine) {
configSaver = ConfigSaver.getLoadedInstance(); configSaver = ConfigSaver.getLoadedInstance();
windowPosition = configSaver.getMainWindowPosition(); windowPosition = configSaver.getMainWindowPosition();
luytenPrefs = configSaver.getLuytenPreferences(); luytenPrefs = configSaver.getLuytenPreferences();
jarModels = new HashMap<String, Model>();
mainMenuBar = new MainMenuBar(this); mainMenuBar = new MainMenuBar(this);
this.setJMenuBar(mainMenuBar); this.setJMenuBar(mainMenuBar);
@ -84,8 +79,18 @@ public class MainWindow extends JFrame {
panel2.setPreferredSize(new Dimension(this.getWidth() / 3, 20)); panel2.setPreferredSize(new Dimension(this.getWidth() / 3, 20));
panel2.add(bar); panel2.add(bar);
model = new Model(this); jarsTabbedPane = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
this.getContentPane().add(model); jarsTabbedPane.setUI(new BasicTabbedPaneUI() {
@Override
protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
if (jarsTabbedPane.indexOfTab(DEFAULT_TAB) == -1)
return super.calculateTabAreaHeight(tab_placement, run_count, max_tab_height);
else
return 0;
}
});
jarsTabbedPane.addTab(DEFAULT_TAB, new Model(this));
this.getContentPane().add(jarsTabbedPane);
JSplitPane spt = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel1, panel2) { JSplitPane spt = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel1, panel2) {
private static final long serialVersionUID = 2189946972124687305L; private static final long serialVersionUID = 2189946972124687305L;
@ -108,8 +113,9 @@ public class MainWindow extends JFrame {
spt.setBorder(new BevelBorder(BevelBorder.LOWERED)); spt.setBorder(new BevelBorder(BevelBorder.LOWERED));
spt.setPreferredSize(new Dimension(this.getWidth(), 24)); spt.setPreferredSize(new Dimension(this.getWidth(), 24));
this.add(spt, BorderLayout.SOUTH); this.add(spt, BorderLayout.SOUTH);
Model jarModel = null;
if (fileFromCommandLine != null) { if (fileFromCommandLine != null) {
model.loadFile(fileFromCommandLine); jarModel = loadNewFile(fileFromCommandLine);
} }
try { try {
@ -123,34 +129,80 @@ public class MainWindow extends JFrame {
fileDialog = new FileDialog(this); fileDialog = new FileDialog(this);
fileSaver = new FileSaver(bar, label); fileSaver = new FileSaver(bar, label);
this.setExitOnEscWhenEnabled(model); if (jarModel != null) {
this.setExitOnEscWhenEnabled(jarModel);
}
if (fileFromCommandLine == null || fileFromCommandLine.getName().toLowerCase().endsWith(".jar") if (jarModel != null && (fileFromCommandLine.getName().toLowerCase().endsWith(".jar")
|| fileFromCommandLine.getName().toLowerCase().endsWith(".zip")) { || fileFromCommandLine.getName().toLowerCase().endsWith(".zip"))) {
model.startWarmUpThread(); jarModel.startWarmUpThread();
} }
if(RecentFiles.load() > 0) mainMenuBar.updateRecentFiles(); if(RecentFiles.load() > 0) mainMenuBar.updateRecentFiles();
} }
private void createDefaultTab() {
jarsTabbedPane.addTab(DEFAULT_TAB, new Model(this));
}
private void removeDefaultTab() {
jarsTabbedPane.remove(jarsTabbedPane.indexOfTab(DEFAULT_TAB));
}
public void onOpenFileMenu() { public void onOpenFileMenu() {
File selectedFile = fileDialog.doOpenDialog(); File selectedFile = fileDialog.doOpenDialog();
if (selectedFile != null) { if (selectedFile != null) {
System.out.println("[Open]: Opening " + selectedFile.getAbsolutePath()); System.out.println("[Open]: Opening " + selectedFile.getAbsolutePath());
this.loadNewFile(selectedFile);
this.getModel().loadFile(selectedFile);
} }
} }
public Model loadNewFile(final File file) {
// In case we open the same file again
// we remove the old entry to force a refresh
if (jarModels.containsKey(file.getAbsolutePath())) {
jarModels.remove(file.getAbsolutePath());
int index = jarsTabbedPane.indexOfTab(file.getName());
jarsTabbedPane.remove(index);
}
Model jarModel = new Model(this);
jarModel.loadFile(file);
jarModels.put(file.getAbsolutePath(), jarModel);
jarsTabbedPane.addTab(file.getName(), jarModel);
jarsTabbedPane.setSelectedComponent(jarModel);
final String tabName = file.getName();
int index = jarsTabbedPane.indexOfTab(tabName);
Model.Tab tabUI = new Model.Tab(tabName, new Callable<Void>() {
@Override
public Void call() {
int index = jarsTabbedPane.indexOfTab(tabName);
jarModels.remove(file.getAbsolutePath());
jarsTabbedPane.remove(index);
if (jarsTabbedPane.getTabCount() == 0) {
createDefaultTab();
}
return null;
}
});
jarsTabbedPane.setTabComponentAt(index, tabUI);
if (jarsTabbedPane.indexOfTab(DEFAULT_TAB) != -1 && jarsTabbedPane.getTabCount() > 1) {
removeDefaultTab();
}
return jarModel;
}
public void onCloseFileMenu() { public void onCloseFileMenu() {
this.getModel().closeFile(); this.getSelectedModel().closeFile();
jarModels.remove(getSelectedModel());
} }
public void onSaveAsMenu() { public void onSaveAsMenu() {
RSyntaxTextArea pane = this.getModel().getCurrentTextArea(); RSyntaxTextArea pane = this.getSelectedModel().getCurrentTextArea();
if (pane == null) if (pane == null)
return; return;
String tabTitle = this.getModel().getCurrentTabTitle(); String tabTitle = this.getSelectedModel().getCurrentTabTitle();
if (tabTitle == null) if (tabTitle == null)
return; return;
@ -162,7 +214,7 @@ public class MainWindow extends JFrame {
} }
public void onSaveAllMenu() { public void onSaveAllMenu() {
File openedFile = this.getModel().getOpenedFile(); File openedFile = this.getSelectedModel().getOpenedFile();
if (openedFile == null) if (openedFile == null)
return; return;
@ -187,7 +239,7 @@ public class MainWindow extends JFrame {
public void onSelectAllMenu() { public void onSelectAllMenu() {
try { try {
RSyntaxTextArea pane = this.getModel().getCurrentTextArea(); RSyntaxTextArea pane = this.getSelectedModel().getCurrentTextArea();
if (pane != null) { if (pane != null) {
pane.requestFocusInWindow(); pane.requestFocusInWindow();
pane.setSelectionStart(0); pane.setSelectionStart(0);
@ -200,7 +252,7 @@ public class MainWindow extends JFrame {
public void onFindMenu() { public void onFindMenu() {
try { try {
RSyntaxTextArea pane = this.getModel().getCurrentTextArea(); RSyntaxTextArea pane = this.getSelectedModel().getCurrentTextArea();
if (pane != null) { if (pane != null) {
if (findBox == null) if (findBox == null)
findBox = new FindBox(this); findBox = new FindBox(this);
@ -229,7 +281,7 @@ public class MainWindow extends JFrame {
bar.setVisible(true); bar.setVisible(true);
bar.setIndeterminate(true); bar.setIndeterminate(true);
String legalStr = getLegalStr(); String legalStr = getLegalStr();
MainWindow.this.getModel().showLegal(legalStr); getSelectedModel().showLegal(legalStr);
} finally { } finally {
bar.setIndeterminate(false); bar.setIndeterminate(false);
bar.setVisible(false); bar.setVisible(false);
@ -251,7 +303,7 @@ public class MainWindow extends JFrame {
} }
myCL = myCL.getParent(); myCL = myCL.getParent();
} }
MainWindow.this.getModel().show("Debug", sb.toString()); this.getSelectedModel().show("Debug", sb.toString());
} finally { } finally {
bar.setIndeterminate(false); bar.setIndeterminate(false);
bar.setVisible(false); bar.setVisible(false);
@ -295,21 +347,27 @@ public class MainWindow extends JFrame {
} }
public void onThemesChanged() { public void onThemesChanged() {
this.getModel().changeTheme(luytenPrefs.getThemeXml()); for (Model jarModel : jarModels.values()) {
luytenPrefs.setFont_size(this.getModel().getTheme().baseFont.getSize()); jarModel.changeTheme(luytenPrefs.getThemeXml());
luytenPrefs.setFont_size(jarModel.getTheme().baseFont.getSize());
}
} }
public void onSettingsChanged() { public void onSettingsChanged() {
this.getModel().updateOpenClasses(); for (Model jarModel : jarModels.values()) {
jarModel.updateOpenClasses();
}
} }
public void onTreeSettingsChanged() { public void onTreeSettingsChanged() {
this.getModel().updateTree(); for (Model jarModel : jarModels.values()) {
jarModel.updateTree();
}
} }
public void onFileDropped(File file) { public void onFileDropped(File file) {
if (file != null) { if (file != null) {
this.getModel().loadFile(file); this.loadNewFile(file);
} }
} }
@ -326,7 +384,7 @@ public class MainWindow extends JFrame {
} }
public void onNavigationRequest(String uniqueStr) { public void onNavigationRequest(String uniqueStr) {
this.getModel().navigateTo(uniqueStr); this.getSelectedModel().navigateTo(uniqueStr);
} }
private void adjustWindowPositionBySavedState() { private void adjustWindowPositionBySavedState() {
@ -426,8 +484,8 @@ public class MainWindow extends JFrame {
mainComponent.getActionMap().put("ESCAPE", escapeAction); mainComponent.getActionMap().put("ESCAPE", escapeAction);
} }
public Model getModel() { public Model getSelectedModel() {
return model; return (Model) jarsTabbedPane.getSelectedComponent();
} }
public JProgressBar getBar() { public JProgressBar getBar() {

View File

@ -5,12 +5,7 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.event.ActionEvent; import java.awt.event.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -28,6 +23,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
@ -213,8 +209,14 @@ public class Model extends JSplitPane {
house.addTab(title, rTextScrollPane); house.addTab(title, rTextScrollPane);
index = house.indexOfComponent(rTextScrollPane); index = house.indexOfComponent(rTextScrollPane);
house.setSelectedIndex(index); house.setSelectedIndex(index);
Tab ct = new Tab(title); Tab ct = new Tab(title, new Callable<Void>() {
ct.getButton().addMouseListener(new CloseTab(title)); @Override
public Void call() throws Exception {
int index = house.indexOfTab(title);
closeOpenTab(index);
return null;
}
});
house.setTabComponentAt(index, ct); house.setTabComponentAt(index, ct);
} else { } else {
house.setSelectedIndex(index); house.setSelectedIndex(index);
@ -586,25 +588,28 @@ public class Model extends JSplitPane {
} }
} }
private class Tab extends JPanel { public static class Tab extends JPanel {
private static final long serialVersionUID = -514663009333644974L; private JLabel tabTitle;
private JLabel closeButton = new JLabel(new ImageIcon( private JLabel closeButton = new JLabel(new ImageIcon(
Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/icon_close.png")))); Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/resources/icon_close.png"))));
private JLabel tabTitle = new JLabel();
private String title = "";
public Tab(String t) { public Tab(String title, final Callable<Void> onCloseTabAction) {
super(new GridBagLayout()); super(new GridBagLayout());
this.setOpaque(false); this.setOpaque(false);
this.title = t;
this.tabTitle = new JLabel(title); this.tabTitle = new JLabel(title);
this.createTab(); this.createTab();
} closeButton.addMouseListener(new MouseAdapter() {
@Override
public JLabel getButton() { public void mouseClicked(MouseEvent e) {
return this.closeButton; try {
if (onCloseTabAction != null) {
onCloseTabAction.call();
}
} catch (Exception ex) {
Luyten.showExceptionDialog("Exception!", ex);
}
}
});
} }
public void createTab() { public void createTab() {