Skip to content

Commit

Permalink
Add Popup Menu for close Tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
sinyear committed Jul 21, 2023
1 parent eda6416 commit 622598a
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 72 deletions.
Expand Up @@ -10,6 +10,8 @@
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJButton;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedVisibleComponent;
import the.bytecode.club.uikit.tabpopup.closer.JTabbedPanePopupMenuTabsCloser;
import the.bytecode.club.uikit.tabpopup.closer.PopupMenuTabsCloseConfiguration;

import javax.swing.*;
import java.awt.*;
Expand Down Expand Up @@ -58,78 +60,10 @@ public Workspace() {

this.tabs = new DraggableTabbedPane();

JPopupMenu popUp = new JPopupMenu();
JMenuItem closeAllTabs = new JMenuItem("Close All But This");
JMenuItem closeTab = new JMenuItem("Close Tab");
closeTab.addActionListener(e ->
{
TabExitButton tabExitButton = (TabExitButton) ((JPopupMenu) ((JMenuItem) e.getSource()).getParent()).getInvoker();
final int index = tabExitButton.getTabIndex();

if (index != -1)
tabs.remove(index);
});

closeAllTabs.addActionListener(e ->
{
TabExitButton tabExitButton = (TabExitButton) ((JPopupMenu) ((JMenuItem) e.getSource()).getParent()).getInvoker();
final int index = tabExitButton.getTabIndex();

while (true) {
if (tabs.getTabCount() <= 1)
return;

if (index != 0)
tabs.remove(0);
else
tabs.remove(1);
}
});

tabs.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) {
if (BLOCK_TAB_MENU)
return;

if (e.getButton() == 3) {
Rectangle bounds = new Rectangle(1, 1, e.getX(), e.getY());

for (int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++) {
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i);
if (c != null && bounds.intersects(c.getBounds())) {
popUp.setVisible(true);
closeAllTabs.setText(TranslatedStrings.CLOSE_TAB + ": " + ((TabbedPane) c).tabName);
closeTab.setText(TranslatedStrings.CLOSE_TAB + ": " + ((TabbedPane) c).tabName);
} else {
popUp.setVisible(false);
}
}
}
}

@Override
public void mouseReleased(MouseEvent e) {
}
});

popUp.add(closeAllTabs);
popUp.add(closeTab);

if (!BLOCK_TAB_MENU)
tabs.setComponentPopupMenu(popUp);
// configure popup menu of close tabs
JTabbedPanePopupMenuTabsCloser popupMenuTabsCloser = new JTabbedPanePopupMenuTabsCloser(this.tabs);
PopupMenuTabsCloseConfiguration.Builder builder = new PopupMenuTabsCloseConfiguration.Builder();
popupMenuTabsCloser.configureCloseItems(builder.buildFull());

getContentPane().setLayout(new BorderLayout());
getContentPane().add(tabs, BorderLayout.CENTER);
Expand Down
@@ -0,0 +1,33 @@
package the.bytecode.club.uikit.tabpopup;

import java.awt.Component;

import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;

/**
* Show PopupMenu on Tabs
* @author su
*
*/
public abstract class AbstractJTabbedPanePopupMenuHandler extends JTabbedPanePopupEventHandler implements ITabPopupEventListener {

public AbstractJTabbedPanePopupMenuHandler(JTabbedPane tabbedPane) {
super(tabbedPane);
registerPopupEventListener(this);
}

@Override
public void onTabPopupEvent(JTabbedPane tabbedPane, int index, TabPopupEvent e) {
JPopupMenu popupMenu = toBuildTabPopupMenu(tabbedPane, e.getPopupOnTab());
popupTabMenuWithEvent(popupMenu, e);
}

public abstract JPopupMenu toBuildTabPopupMenu(JTabbedPane tabbedPane, Component popupOnTab);


public static void popupTabMenuWithEvent(JPopupMenu popupMenu, TabPopupEvent e) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}

}
@@ -0,0 +1,13 @@
package the.bytecode.club.uikit.tabpopup;

import javax.swing.JTabbedPane;

public interface ITabPopupEventListener {
/**
*
* @param tabbedPane
* @param index, index of tab
* @param e
*/
public void onTabPopupEvent(JTabbedPane tabbedPane, int index, TabPopupEvent e);
}
@@ -0,0 +1,11 @@
package the.bytecode.club.uikit.tabpopup;

import javax.swing.JTabbedPane;

public interface ITabZeroComponentEventListener {
/**
*
* @param tabbedPane
*/
public void onTabZeroComponent(JTabbedPane tabbedPane);
}
@@ -0,0 +1,58 @@
package the.bytecode.club.uikit.tabpopup;

import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JTabbedPane;

/**
* Register PopupEvent Handler on TabbedPane
* @author su
*
*/
public class JTabbedPanePopupEventHandler {
protected final JTabbedPane tabbedPane;
private ITabPopupEventListener tabPopupEventListener;

public JTabbedPanePopupEventHandler(JTabbedPane tabbedPane) {
super();
this.tabbedPane = tabbedPane;
this.registerMouseEventListener();
}

private void registerMouseEventListener() {
this.tabbedPane.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
tryTriggerTabPopupEvent(e);
}

@Override
public void mouseReleased(MouseEvent e) {
tryTriggerTabPopupEvent(e);
}
});
}

public void registerPopupEventListener(ITabPopupEventListener tabPopupEventListener) {
this.tabPopupEventListener = tabPopupEventListener;
}

protected void tryTriggerTabPopupEvent(MouseEvent e) {
if (e.isPopupTrigger()) {
int index = tabbedPane.indexAtLocation(e.getX(), e.getY());
if (index != -1) {
Component popupOnTab = tabbedPane.getComponentAt(index);
if (this.tabPopupEventListener != null) {
this.tabPopupEventListener.onTabPopupEvent(tabbedPane, index, new TabPopupEvent(e, popupOnTab));
}
}
}
}

public JTabbedPane getTabbedPane() {
return tabbedPane;
}

}
26 changes: 26 additions & 0 deletions src/main/java/the/bytecode/club/uikit/tabpopup/TabPopupEvent.java
@@ -0,0 +1,26 @@
package the.bytecode.club.uikit.tabpopup;

import java.awt.Component;
import java.awt.event.MouseEvent;

public class TabPopupEvent extends MouseEvent {
/**
*
*/
private static final long serialVersionUID = 2510164400674753411L;

private final Component popupOnTab;

public TabPopupEvent(MouseEvent e, Component popupOnTab) {
super(e.getComponent(), e.getID(), e.getWhen(), e.getModifiers(),
e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger(), e.getButton());

this.popupOnTab = popupOnTab;
}

public Component getPopupOnTab() {
return popupOnTab;
}


}
@@ -0,0 +1,87 @@
package the.bytecode.club.uikit.tabpopup.closer;

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JTabbedPane;

import the.bytecode.club.uikit.tabpopup.ITabZeroComponentEventListener;

/**
* Provide function of closing tabs
* @author su
*
*/
public class JTabbedPaneCloser {
private JTabbedPane tabbedPane;
private ITabZeroComponentEventListener tabZeroComponentEventListener;

public JTabbedPaneCloser(JTabbedPane tabbedPane) {
super();
this.tabbedPane = tabbedPane;
}

public JTabbedPaneCloser(JTabbedPane tabbedPane, ITabZeroComponentEventListener tabZeroComponentEventListener) {
this(tabbedPane);
this.tabZeroComponentEventListener = tabZeroComponentEventListener;
}

public void removeComponent(Component component) {
this.tabbedPane.remove(component);
tryTriggerTabZeroComponentEvent();
}

public void removeOtherComponents(Component component) {
removeOtherComponents(component, false);
}

protected void removeOtherComponents(Component component, boolean equalStop) {
int i = this.tabbedPane.getTabCount();
while (i-- > 0) {
Component c = this.tabbedPane.getComponentAt(i);
if (c != component) {
this.tabbedPane.remove(i);
} else if (equalStop) {
break ;
}
}

tryTriggerTabZeroComponentEvent();
}

public void removeLeftComponents(Component component) {
int count = this.tabbedPane.getTabCount();
int i = 0;
List<Component> removeTabs = new ArrayList<>();
do {
Component c = this.tabbedPane.getComponentAt(i);
if (c != component) {
removeTabs.add(c);
} else {
break ;
}
} while (i++ < count);

for (Component c : removeTabs) {
this.tabbedPane.remove(c);
}

tryTriggerTabZeroComponentEvent();
}

public void removeRightComponents(Component component) {
removeOtherComponents(component, true);
}

public void removeAllComponents() {
this.tabbedPane.removeAll();
tryTriggerTabZeroComponentEvent();
}

private void tryTriggerTabZeroComponentEvent() {
if (this.tabbedPane.getTabCount() == 0 && tabZeroComponentEventListener != null) {
tabZeroComponentEventListener.onTabZeroComponent(this.tabbedPane);
}
}
}

0 comments on commit 622598a

Please sign in to comment.