Tabbed Windows
This gives the option to open all of the window dialogs as tabbed resources. The plugin writer and plugin console tab could be merged into a single pane at a later date. The error dialog might be over-kill and should remain an external window. This is mostly an experiment for better UIs, because of this everything is optional and can be turned off within the configuration class
This commit is contained in:
parent
582dccdb96
commit
15df6abfc9
9 changed files with 178 additions and 36 deletions
|
@ -33,6 +33,13 @@ public class Configuration
|
||||||
//if true it will show a settings dialog on click instead of more menu items
|
//if true it will show a settings dialog on click instead of more menu items
|
||||||
public static boolean useNewSettingsDialog = true; //TODO add to GUI
|
public static boolean useNewSettingsDialog = true; //TODO add to GUI
|
||||||
|
|
||||||
|
//if true it will put force error UIs and console UIs to be added as a tab
|
||||||
|
public static boolean pluginConsoleAsNewTab = true; //TODO add to GUI
|
||||||
|
//if true it will put force error UIs and console UIs to be added as a tab
|
||||||
|
public static boolean errorLogsAsNewTab = true; //TODO add to GUI
|
||||||
|
//if true the plugin writer will open inside of a tab
|
||||||
|
public static boolean pluginWriterAsNewTab = true; //TODO add to GUI
|
||||||
|
|
||||||
public static boolean forceResourceUpdateFromClassNode = false; //TODO add to GUI
|
public static boolean forceResourceUpdateFromClassNode = false; //TODO add to GUI
|
||||||
public static boolean showDarkLAFComponentIcons = false;
|
public static boolean showDarkLAFComponentIcons = false;
|
||||||
public static boolean currentlyDumping = false;
|
public static boolean currentlyDumping = false;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package the.bytecode.club.bytecodeviewer.api;
|
package the.bytecode.club.bytecodeviewer.api;
|
||||||
|
|
||||||
import java.awt.CardLayout;
|
import java.awt.*;
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
@ -12,6 +10,7 @@ import javax.swing.JTextArea;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsole;
|
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsole;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ComponentViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
|
||||||
|
@ -46,6 +45,7 @@ public class ExceptionUI extends JFrameConsole
|
||||||
public static final String KONLOCH = "https://github.com/Konloch/bytecode-viewer/issues or Konloch at https://the.bytecode.club or konloch@gmail.com";
|
public static final String KONLOCH = "https://github.com/Konloch/bytecode-viewer/issues or Konloch at https://the.bytecode.club or konloch@gmail.com";
|
||||||
public static final String SEND_STACKTRACE_TO = buildErrorLogHeader(KONLOCH);
|
public static final String SEND_STACKTRACE_TO = buildErrorLogHeader(KONLOCH);
|
||||||
public static final String SEND_STACKTRACE_TO_NL = SEND_STACKTRACE_TO + nl + nl;
|
public static final String SEND_STACKTRACE_TO_NL = SEND_STACKTRACE_TO + nl + nl;
|
||||||
|
public static int errorCounter = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param e The exception to be shown
|
* @param e The exception to be shown
|
||||||
|
@ -105,7 +105,7 @@ public class ExceptionUI extends JFrameConsole
|
||||||
*/
|
*/
|
||||||
private void setupFrame(String error, String author)
|
private void setupFrame(String error, String author)
|
||||||
{
|
{
|
||||||
this.setIconImages(IconResources.iconList);
|
setIconImages(IconResources.iconList);
|
||||||
setSize(new Dimension(600, 400));
|
setSize(new Dimension(600, 400));
|
||||||
setTitle("Bytecode Viewer " + VERSION + " - Error Log - Send this to " + author);
|
setTitle("Bytecode Viewer " + VERSION + " - Error Log - Send this to " + author);
|
||||||
getContentPane().setLayout(new CardLayout(0, 0));
|
getContentPane().setLayout(new CardLayout(0, 0));
|
||||||
|
@ -113,8 +113,17 @@ public class ExceptionUI extends JFrameConsole
|
||||||
getTextArea().setText(buildErrorLogHeader(author) + nl + nl + error);
|
getTextArea().setText(buildErrorLogHeader(author) + nl + nl + error);
|
||||||
getTextArea().setCaretPosition(0);
|
getTextArea().setCaretPosition(0);
|
||||||
|
|
||||||
this.setLocationRelativeTo(BytecodeViewer.viewer);
|
//embed error log as a new tab
|
||||||
this.setVisible(true);
|
if(Configuration.errorLogsAsNewTab)
|
||||||
|
{
|
||||||
|
ComponentViewer.addComponentAsTab("Error #" + errorCounter++, getComponent(0));
|
||||||
|
}
|
||||||
|
//pop open a new window frame
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setLocationRelativeTo(BytecodeViewer.viewer);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package the.bytecode.club.bytecodeviewer.api;
|
package the.bytecode.club.bytecodeviewer.api;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.SystemConsole;
|
import the.bytecode.club.bytecodeviewer.gui.components.SystemConsole;
|
||||||
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
@ -35,7 +36,7 @@ public class PluginConsole extends SystemConsole
|
||||||
|
|
||||||
public PluginConsole(String pluginName)
|
public PluginConsole(String pluginName)
|
||||||
{
|
{
|
||||||
super(TranslatedStrings.PLUGIN_CONSOLE_TITLE + " - " + pluginName);
|
super(Configuration.pluginConsoleAsNewTab ? (pluginName + " Output") : (TranslatedStrings.PLUGIN_CONSOLE_TITLE + " - " + pluginName));
|
||||||
|
|
||||||
PluginManager.addConsole(this);
|
PluginManager.addConsole(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,32 +187,7 @@ public class Workspace extends TranslatedVisibleComponent
|
||||||
//create a new tab if the resource isn't opened currently
|
//create a new tab if the resource isn't opened currently
|
||||||
if (!openedTabs.contains(workingName))
|
if (!openedTabs.contains(workingName))
|
||||||
{
|
{
|
||||||
//start processing the resource to be viewed
|
addResourceToTab(resourceView, workingName, container.name, name);
|
||||||
if(resourceView instanceof ClassViewer)
|
|
||||||
resourceView.refresh(null);
|
|
||||||
|
|
||||||
//add the resource view to the tabs
|
|
||||||
tabs.add(resourceView);
|
|
||||||
|
|
||||||
//get the resource view index
|
|
||||||
final int tabIndex = tabs.indexOfComponent(resourceView);
|
|
||||||
|
|
||||||
//create a new tabbed pane
|
|
||||||
TabbedPane tabbedPane = new TabbedPane(tabIndex, workingName, container.name, name, tabs, resourceView);
|
|
||||||
resourceView.tabbedPane = tabbedPane;
|
|
||||||
resourceView.resource.workingName = workingName;
|
|
||||||
|
|
||||||
//set the tabs index
|
|
||||||
tabs.setTabComponentAt(tabIndex, tabbedPane);
|
|
||||||
|
|
||||||
//open the tab that was just added
|
|
||||||
tabs.setSelectedIndex(tabIndex);
|
|
||||||
|
|
||||||
//set resource as opened in a tab
|
|
||||||
openedTabs.add(workingName);
|
|
||||||
|
|
||||||
//refresh the tab title
|
|
||||||
resourceView.refreshTitle();
|
|
||||||
}
|
}
|
||||||
else //if the resource is already opened select this tab as the active one
|
else //if the resource is already opened select this tab as the active one
|
||||||
{
|
{
|
||||||
|
@ -231,6 +206,36 @@ public class Workspace extends TranslatedVisibleComponent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addResourceToTab(ResourceViewer resourceView, String workingName, String containerName, String name)
|
||||||
|
{
|
||||||
|
//start processing the resource to be viewed
|
||||||
|
if(resourceView instanceof ClassViewer)
|
||||||
|
resourceView.refresh(null);
|
||||||
|
|
||||||
|
//add the resource view to the tabs
|
||||||
|
tabs.add(resourceView);
|
||||||
|
|
||||||
|
//get the resource view index
|
||||||
|
final int tabIndex = tabs.indexOfComponent(resourceView);
|
||||||
|
|
||||||
|
//create a new tabbed pane
|
||||||
|
TabbedPane tabbedPane = new TabbedPane(tabIndex, workingName, containerName, name, tabs, resourceView);
|
||||||
|
resourceView.tabbedPane = tabbedPane;
|
||||||
|
resourceView.resource.workingName = workingName;
|
||||||
|
|
||||||
|
//set the tabs index
|
||||||
|
tabs.setTabComponentAt(tabIndex, tabbedPane);
|
||||||
|
|
||||||
|
//open the tab that was just added
|
||||||
|
tabs.setSelectedIndex(tabIndex);
|
||||||
|
|
||||||
|
//set resource as opened in a tab
|
||||||
|
openedTabs.add(workingName);
|
||||||
|
|
||||||
|
//refresh the tab title
|
||||||
|
resourceView.refreshTitle();
|
||||||
|
}
|
||||||
|
|
||||||
public ResourceViewer getActiveResource() {
|
public ResourceViewer getActiveResource() {
|
||||||
return (ResourceViewer) tabs.getSelectedComponent();
|
return (ResourceViewer) tabs.getSelectedComponent();
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.resources.Resource;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||||
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents a component opened as a tab
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
* @since 7/23/2021
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ComponentViewer extends ResourceViewer
|
||||||
|
{
|
||||||
|
private Component component;
|
||||||
|
private static final String containerName = "internalComponent.";
|
||||||
|
|
||||||
|
public ComponentViewer(String title, Component component)
|
||||||
|
{
|
||||||
|
super(new Resource(title, containerName + title, null));
|
||||||
|
|
||||||
|
this.component = component;
|
||||||
|
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
setName(title);
|
||||||
|
add(component, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ComponentViewer addComponentAsTab(String title, Component c)
|
||||||
|
{
|
||||||
|
String workingName = containerName + title;
|
||||||
|
ComponentViewer componentViewer = new ComponentViewer(title, c);
|
||||||
|
BytecodeViewer.viewer.workPane.addResourceToTab(componentViewer,
|
||||||
|
workingName, containerName, title);
|
||||||
|
|
||||||
|
return componentViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refresh(JButton button) {
|
||||||
|
//TODO add a refresh event so the component can be updated
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ import the.bytecode.club.bytecodeviewer.util.SyntaxLanguage;
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents any open non-class file.
|
* Represents any open non-class file inside of a tab.
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,7 +26,7 @@ import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ResourceViewer
|
* Represents an opened tab
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
package the.bytecode.club.bytecodeviewer.plugin;
|
package the.bytecode.club.bytecodeviewer.plugin;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import javax.swing.filechooser.FileFilter;
|
import javax.swing.filechooser.FileFilter;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
import the.bytecode.club.bytecodeviewer.api.Plugin;
|
import the.bytecode.club.bytecodeviewer.api.Plugin;
|
||||||
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsoleTabbed;
|
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsoleTabbed;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ComponentViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.plugin.strategies.*;
|
import the.bytecode.club.bytecodeviewer.plugin.strategies.*;
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
||||||
|
@ -128,7 +132,11 @@ public final class PluginManager
|
||||||
if(activeTabbedConsole == null)
|
if(activeTabbedConsole == null)
|
||||||
{
|
{
|
||||||
activeTabbedConsole = new JFrameConsoleTabbed(console.getTitle());
|
activeTabbedConsole = new JFrameConsoleTabbed(console.getTitle());
|
||||||
activeTabbedConsole.setVisible(true);
|
|
||||||
|
if(Configuration.pluginConsoleAsNewTab)
|
||||||
|
ComponentViewer.addComponentAsTab(console.getTitle(), activeTabbedConsole.getComponent(0));
|
||||||
|
else
|
||||||
|
activeTabbedConsole.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.setConsoleID(id);
|
console.setConsoleID(id);
|
||||||
|
|
|
@ -5,6 +5,8 @@ import me.konloch.kontainer.io.DiskWriter;
|
||||||
import org.apache.commons.compress.utils.FileNameUtils;
|
import org.apache.commons.compress.utils.FileNameUtils;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ComponentViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.theme.LAFTheme;
|
||||||
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
import the.bytecode.club.bytecodeviewer.resources.IconResources;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
|
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||||
|
@ -24,10 +26,29 @@ import static the.bytecode.club.bytecodeviewer.Constants.fs;
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
|
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
|
||||||
import static the.bytecode.club.bytecodeviewer.Settings.addRecentPlugin;
|
import static the.bytecode.club.bytecodeviewer.Settings.addRecentPlugin;
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
||||||
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
* @since 7/1/2021
|
* @since 7/1/2021
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class PluginWriter extends JFrame
|
public class PluginWriter extends JFrame
|
||||||
{
|
{
|
||||||
private SearchableRSyntaxTextArea area;
|
private SearchableRSyntaxTextArea area;
|
||||||
|
@ -93,6 +114,33 @@ public class PluginWriter extends JFrame
|
||||||
this.setLocationRelativeTo(null);
|
this.setLocationRelativeTo(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisible(boolean b)
|
||||||
|
{
|
||||||
|
if(Configuration.pluginWriterAsNewTab)
|
||||||
|
{
|
||||||
|
Component component = getComponent(0);
|
||||||
|
|
||||||
|
JPanel p = new JPanel(new BorderLayout());
|
||||||
|
JPanel p2 = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
|
p.add(p2, BorderLayout.NORTH);
|
||||||
|
p.add(component, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
if(Configuration.lafTheme == LAFTheme.SYSTEM)
|
||||||
|
p2.add(getJMenuBar(), BorderLayout.CENTER);
|
||||||
|
else //TODO DarkLAF wont display the jMenuBar due to how it handles them, instead display the menu
|
||||||
|
//TODO make the menu interactable and display the menu manually
|
||||||
|
p2.add(getJMenuBar().getMenu(0), BorderLayout.CENTER);
|
||||||
|
|
||||||
|
ComponentViewer.addComponentAsTab(pluginName, p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
super.setVisible(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setPluginName(String name)
|
public void setPluginName(String name)
|
||||||
{
|
{
|
||||||
this.pluginName = name;
|
this.pluginName = name;
|
||||||
|
|
Loading…
Reference in a new issue