Enabled tabs to be rearranged. Did not add functionality for a tab to be dropped out. We could possibly add it at a later time, also add a setting to toggle it on/off? Recommend to gather feedback to see if that is something wanted.
This commit is contained in:
parent
218de052e0
commit
ae6911658c
5 changed files with 45 additions and 172 deletions
|
@ -129,8 +129,6 @@ import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
|
||||||
|
|
||||||
public class BytecodeViewer
|
public class BytecodeViewer
|
||||||
{
|
{
|
||||||
//TODO fix this for tab dragging & better tab controls
|
|
||||||
public static boolean EXPERIMENTAL_TAB_CODE = true;
|
|
||||||
|
|
||||||
//the launch args called on BCV
|
//the launch args called on BCV
|
||||||
public static String[] launchArgs;
|
public static String[] launchArgs;
|
||||||
|
|
|
@ -2,14 +2,23 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
|
||||||
|
|
||||||
import com.android.tools.r8.internal.Cl;
|
import com.android.tools.r8.internal.Cl;
|
||||||
import com.github.weisj.darklaf.components.CloseButton;
|
import com.github.weisj.darklaf.components.CloseButton;
|
||||||
|
import com.github.weisj.darklaf.listener.MouseClickListener;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.components.listeners.MouseClickedListener;
|
||||||
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
|
||||||
public class CloseButtonComponent extends JPanel {
|
public class CloseButtonComponent extends JPanel {
|
||||||
|
|
||||||
private final JTabbedPane pane;
|
private final JTabbedPane pane;
|
||||||
|
|
||||||
|
String title = "";
|
||||||
|
|
||||||
public CloseButtonComponent(final JTabbedPane pane) {
|
public CloseButtonComponent(final JTabbedPane pane) {
|
||||||
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||||
if (pane == null) {
|
if (pane == null) {
|
||||||
|
@ -33,6 +42,40 @@ public class CloseButtonComponent extends JPanel {
|
||||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||||
JButton button = new CloseButton();
|
JButton button = new CloseButton();
|
||||||
add(button);
|
add(button);
|
||||||
|
|
||||||
|
JPopupMenu rightClickMenu = new JPopupMenu();
|
||||||
|
JMenuItem closeAllTabs = new JMenuItem(String.valueOf(TranslatedStrings.CLOSE_ALL_BUT_THIS));
|
||||||
|
JMenuItem closeTab = new JMenuItem(String.valueOf(TranslatedStrings.CLOSE_TAB));
|
||||||
|
|
||||||
|
rightClickMenu.add(closeAllTabs);
|
||||||
|
rightClickMenu.add(closeTab);
|
||||||
|
button.setComponentPopupMenu(rightClickMenu);
|
||||||
|
|
||||||
|
button.addMouseListener(new MouseClickedListener(e ->
|
||||||
|
{
|
||||||
|
if (pane.indexOfTabComponent(CloseButtonComponent.this) != -1)
|
||||||
|
pane.remove(pane.indexOfTabComponent(CloseButtonComponent.this));
|
||||||
|
}));
|
||||||
|
|
||||||
|
closeTab.addActionListener(e ->
|
||||||
|
{
|
||||||
|
if (pane.indexOfTabComponent(CloseButtonComponent.this) != -1)
|
||||||
|
pane.remove(pane.indexOfTabComponent(CloseButtonComponent.this));
|
||||||
|
});
|
||||||
|
closeAllTabs.addActionListener(e ->
|
||||||
|
{
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (pane.getTabCount() <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pane.indexOfTabComponent(CloseButtonComponent.this) != 0)
|
||||||
|
pane.remove(0);
|
||||||
|
else
|
||||||
|
pane.remove(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
|
package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
|
||||||
|
|
||||||
import com.github.weisj.darklaf.components.CloseButton;
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -8,10 +7,6 @@ import java.awt.*;
|
||||||
import java.awt.datatransfer.DataFlavor;
|
import java.awt.datatransfer.DataFlavor;
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
import java.awt.dnd.*;
|
import java.awt.dnd.*;
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseListener;
|
|
||||||
import java.awt.event.MouseMotionAdapter;
|
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
|
|
@ -76,166 +76,8 @@ public class TabbedPane extends JPanel {
|
||||||
this.add(label);
|
this.add(label);
|
||||||
// add more space between the label and the button
|
// add more space between the label and the button
|
||||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||||
// tab button
|
|
||||||
JButton exitButton = new CloseButton();
|
|
||||||
// add more space to the top of the component
|
// add more space to the top of the component
|
||||||
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
||||||
|
|
||||||
//define the right click pop-up menu
|
|
||||||
JPopupMenu rightClickMenu = new JPopupMenu();
|
|
||||||
this.putClientProperty("index", this.getTabIndex());
|
|
||||||
JMenuItem closeAllTabs = new JMenuItem(TranslatedStrings.CLOSE_ALL_BUT_THIS + ": " + name);
|
|
||||||
JMenuItem closeTab = new JMenuItem(TranslatedStrings.CLOSE_TAB + ": " + name);
|
|
||||||
|
|
||||||
rightClickMenu.add(closeAllTabs);
|
|
||||||
rightClickMenu.add(closeTab);
|
|
||||||
//setComponentPopupMenu(rightClickMenu);
|
|
||||||
|
|
||||||
exitButton.setComponentPopupMenu(rightClickMenu);
|
|
||||||
exitButton.addMouseListener(new MouseClickedListener(e ->
|
|
||||||
{
|
|
||||||
if (this.getTabIndex() != -1)
|
|
||||||
existingTabs.remove(this.getTabIndex());
|
|
||||||
}));
|
|
||||||
|
|
||||||
closeTab.addActionListener(e ->
|
|
||||||
{
|
|
||||||
if (this.getTabIndex() != -1)
|
|
||||||
existingTabs.remove(this.getTabIndex());
|
|
||||||
});
|
|
||||||
closeAllTabs.addActionListener(e ->
|
|
||||||
{
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (existingTabs.getTabCount() <= 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this.getTabIndex() != 0)
|
|
||||||
existingTabs.remove(0);
|
|
||||||
else
|
|
||||||
existingTabs.remove(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//tab dragging
|
|
||||||
if (BytecodeViewer.EXPERIMENTAL_TAB_CODE) {
|
|
||||||
/*label.addMouseListener(new MouseListener() {
|
|
||||||
@Override public void mouseClicked(MouseEvent e) {}
|
|
||||||
@Override public void mouseEntered(MouseEvent arg0) {
|
|
||||||
}
|
|
||||||
@Override public void mouseExited(MouseEvent arg0) {
|
|
||||||
}
|
|
||||||
@Override public void mousePressed(MouseEvent e) {
|
|
||||||
onMousePressed(e);
|
|
||||||
}
|
|
||||||
@Override public void mouseReleased(MouseEvent e) {
|
|
||||||
stopDragging(e.getX(), e.getY());
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
this.addMouseListener(new MouseListener() {
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent arg0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent arg0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
onMousePressed(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//middle click close
|
|
||||||
if (BytecodeViewer.EXPERIMENTAL_TAB_CODE) {
|
|
||||||
this.addMouseListener(new MouseAdapter() {
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
if (e.getButton() != MouseEvent.BUTTON2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
final int i = existingTabs.indexOfTabComponent(TabbedPane.this);
|
|
||||||
if (i != -1)
|
|
||||||
existingTabs.remove(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopDragging(int mouseX, int mouseY) {
|
|
||||||
if (System.currentTimeMillis() - startedDragging >= 210) {
|
|
||||||
if (mouseX < 0) {
|
|
||||||
mouseX = 0;
|
|
||||||
}
|
|
||||||
Rectangle bounds = new Rectangle(1, 1, mouseX, mouseY);
|
|
||||||
System.out.println("debug-5: " + mouseX + ", " + mouseY);
|
|
||||||
|
|
||||||
int totalTabs = BytecodeViewer.viewer.workPane.tabs.getTabCount();
|
|
||||||
int curIndex = getTabIndex();
|
|
||||||
int toIndex = -1;
|
|
||||||
|
|
||||||
//Set up the indexes of our tabs.
|
|
||||||
for (int i = 0; i < totalTabs; i++) {
|
|
||||||
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i);
|
|
||||||
System.err.println("Our bounds: " + bounds + " component: " + c.getBounds() + " intersects: " + bounds.intersects(c.getBounds()));
|
|
||||||
if (bounds.intersects(c.getBounds()) && c != this) {
|
|
||||||
toIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.err.println(totalTabs + " " + curIndex + " " + toIndex);
|
|
||||||
|
|
||||||
if (toIndex == totalTabs) {
|
|
||||||
System.err.println("here");
|
|
||||||
} else if (curIndex > toIndex) {
|
|
||||||
if (toIndex == -1) {
|
|
||||||
toIndex = 0;
|
|
||||||
}
|
|
||||||
// [tab0=index0][tab1=index1]
|
|
||||||
// ---> == remove(tab0)
|
|
||||||
// [tab1=index0]
|
|
||||||
// add(tab0)
|
|
||||||
// [tab1=index0][tab0=index1]
|
|
||||||
|
|
||||||
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(toIndex + 1);
|
|
||||||
System.err.println("here1");
|
|
||||||
// BytecodeViewer.viewer.workPane.tabs.remove(curIndex - 1); // 0
|
|
||||||
// BytecodeViewer.viewer.workPane.tabs.add(BytecodeViewer.viewer.workPane.op);
|
|
||||||
// BytecodeViewer.viewer.workPane.tabs.setTabComponentAt(curIndex, BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(curIndex - 1));
|
|
||||||
} else {
|
|
||||||
BytecodeViewer.viewer.workPane.tabs.remove(curIndex); // 0
|
|
||||||
BytecodeViewer.viewer.workPane.tabs.add(resource);
|
|
||||||
BytecodeViewer.viewer.workPane.tabs.setTabComponentAt(toIndex, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toIndex == -1) {
|
|
||||||
for (int i = 0; i < totalTabs; i++) {
|
|
||||||
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i);
|
|
||||||
//do some check to see if it's past the X or Y
|
|
||||||
if (c != null) {
|
|
||||||
System.out.println("debug-6: " + c.getBounds());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() ->
|
|
||||||
{
|
|
||||||
label.setBackground(BLANK_COLOR);
|
|
||||||
label.updateUI();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onMousePressed(MouseEvent e)
|
public void onMousePressed(MouseEvent e)
|
||||||
|
@ -260,15 +102,11 @@ public class TabbedPane extends JPanel {
|
||||||
BytecodeViewer.viewer.workPane.tabs.setSelectedIndex(i);
|
BytecodeViewer.viewer.workPane.tabs.setSelectedIndex(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
stopDragging(e.getX(), e.getY());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = -4774885688297538774L;
|
private static final long serialVersionUID = -4774885688297538774L;
|
||||||
|
|
||||||
public int getTabIndex() {
|
/*public int getTabIndex() {
|
||||||
return tabs.indexOfTabComponent(this);
|
return tabs.indexOfTabComponent(this);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,6 @@ public class Workspace extends TranslatedVisibleComponent
|
||||||
resourceView.resource.workingName = workingName;
|
resourceView.resource.workingName = workingName;
|
||||||
|
|
||||||
//set the tabs index
|
//set the tabs index
|
||||||
// tabs.setTabComponentAt(tabIndex, tabbedPane);
|
|
||||||
tabs.setTabComponentAt(tabIndex, new CloseButtonComponent(tabs));
|
tabs.setTabComponentAt(tabIndex, new CloseButtonComponent(tabs));
|
||||||
|
|
||||||
//open the tab that was just added
|
//open the tab that was just added
|
||||||
|
|
Loading…
Reference in a new issue