Skip to content

Commit 622598a

Browse files
committed
Add Popup Menu for close Tabs
1 parent eda6416 commit 622598a

File tree

9 files changed

+413
-72
lines changed

9 files changed

+413
-72
lines changed

src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/Workspace.java

Lines changed: 6 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
1111
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJButton;
1212
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedVisibleComponent;
13+
import the.bytecode.club.uikit.tabpopup.closer.JTabbedPanePopupMenuTabsCloser;
14+
import the.bytecode.club.uikit.tabpopup.closer.PopupMenuTabsCloseConfiguration;
1315

1416
import javax.swing.*;
1517
import java.awt.*;
@@ -58,78 +60,10 @@ public Workspace() {
5860

5961
this.tabs = new DraggableTabbedPane();
6062

61-
JPopupMenu popUp = new JPopupMenu();
62-
JMenuItem closeAllTabs = new JMenuItem("Close All But This");
63-
JMenuItem closeTab = new JMenuItem("Close Tab");
64-
closeTab.addActionListener(e ->
65-
{
66-
TabExitButton tabExitButton = (TabExitButton) ((JPopupMenu) ((JMenuItem) e.getSource()).getParent()).getInvoker();
67-
final int index = tabExitButton.getTabIndex();
68-
69-
if (index != -1)
70-
tabs.remove(index);
71-
});
72-
73-
closeAllTabs.addActionListener(e ->
74-
{
75-
TabExitButton tabExitButton = (TabExitButton) ((JPopupMenu) ((JMenuItem) e.getSource()).getParent()).getInvoker();
76-
final int index = tabExitButton.getTabIndex();
77-
78-
while (true) {
79-
if (tabs.getTabCount() <= 1)
80-
return;
81-
82-
if (index != 0)
83-
tabs.remove(0);
84-
else
85-
tabs.remove(1);
86-
}
87-
});
88-
89-
tabs.addMouseListener(new MouseListener() {
90-
@Override
91-
public void mouseClicked(MouseEvent e) {
92-
}
93-
94-
@Override
95-
public void mouseEntered(MouseEvent arg0) {
96-
}
97-
98-
@Override
99-
public void mouseExited(MouseEvent arg0) {
100-
}
101-
102-
@Override
103-
public void mousePressed(MouseEvent e) {
104-
if (BLOCK_TAB_MENU)
105-
return;
106-
107-
if (e.getButton() == 3) {
108-
Rectangle bounds = new Rectangle(1, 1, e.getX(), e.getY());
109-
110-
for (int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++) {
111-
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i);
112-
if (c != null && bounds.intersects(c.getBounds())) {
113-
popUp.setVisible(true);
114-
closeAllTabs.setText(TranslatedStrings.CLOSE_TAB + ": " + ((TabbedPane) c).tabName);
115-
closeTab.setText(TranslatedStrings.CLOSE_TAB + ": " + ((TabbedPane) c).tabName);
116-
} else {
117-
popUp.setVisible(false);
118-
}
119-
}
120-
}
121-
}
122-
123-
@Override
124-
public void mouseReleased(MouseEvent e) {
125-
}
126-
});
127-
128-
popUp.add(closeAllTabs);
129-
popUp.add(closeTab);
130-
131-
if (!BLOCK_TAB_MENU)
132-
tabs.setComponentPopupMenu(popUp);
63+
// configure popup menu of close tabs
64+
JTabbedPanePopupMenuTabsCloser popupMenuTabsCloser = new JTabbedPanePopupMenuTabsCloser(this.tabs);
65+
PopupMenuTabsCloseConfiguration.Builder builder = new PopupMenuTabsCloseConfiguration.Builder();
66+
popupMenuTabsCloser.configureCloseItems(builder.buildFull());
13367

13468
getContentPane().setLayout(new BorderLayout());
13569
getContentPane().add(tabs, BorderLayout.CENTER);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package the.bytecode.club.uikit.tabpopup;
2+
3+
import java.awt.Component;
4+
5+
import javax.swing.JPopupMenu;
6+
import javax.swing.JTabbedPane;
7+
8+
/**
9+
* Show PopupMenu on Tabs
10+
* @author su
11+
*
12+
*/
13+
public abstract class AbstractJTabbedPanePopupMenuHandler extends JTabbedPanePopupEventHandler implements ITabPopupEventListener {
14+
15+
public AbstractJTabbedPanePopupMenuHandler(JTabbedPane tabbedPane) {
16+
super(tabbedPane);
17+
registerPopupEventListener(this);
18+
}
19+
20+
@Override
21+
public void onTabPopupEvent(JTabbedPane tabbedPane, int index, TabPopupEvent e) {
22+
JPopupMenu popupMenu = toBuildTabPopupMenu(tabbedPane, e.getPopupOnTab());
23+
popupTabMenuWithEvent(popupMenu, e);
24+
}
25+
26+
public abstract JPopupMenu toBuildTabPopupMenu(JTabbedPane tabbedPane, Component popupOnTab);
27+
28+
29+
public static void popupTabMenuWithEvent(JPopupMenu popupMenu, TabPopupEvent e) {
30+
popupMenu.show(e.getComponent(), e.getX(), e.getY());
31+
}
32+
33+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package the.bytecode.club.uikit.tabpopup;
2+
3+
import javax.swing.JTabbedPane;
4+
5+
public interface ITabPopupEventListener {
6+
/**
7+
*
8+
* @param tabbedPane
9+
* @param index, index of tab
10+
* @param e
11+
*/
12+
public void onTabPopupEvent(JTabbedPane tabbedPane, int index, TabPopupEvent e);
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package the.bytecode.club.uikit.tabpopup;
2+
3+
import javax.swing.JTabbedPane;
4+
5+
public interface ITabZeroComponentEventListener {
6+
/**
7+
*
8+
* @param tabbedPane
9+
*/
10+
public void onTabZeroComponent(JTabbedPane tabbedPane);
11+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package the.bytecode.club.uikit.tabpopup;
2+
3+
import java.awt.Component;
4+
import java.awt.event.MouseAdapter;
5+
import java.awt.event.MouseEvent;
6+
7+
import javax.swing.JTabbedPane;
8+
9+
/**
10+
* Register PopupEvent Handler on TabbedPane
11+
* @author su
12+
*
13+
*/
14+
public class JTabbedPanePopupEventHandler {
15+
protected final JTabbedPane tabbedPane;
16+
private ITabPopupEventListener tabPopupEventListener;
17+
18+
public JTabbedPanePopupEventHandler(JTabbedPane tabbedPane) {
19+
super();
20+
this.tabbedPane = tabbedPane;
21+
this.registerMouseEventListener();
22+
}
23+
24+
private void registerMouseEventListener() {
25+
this.tabbedPane.addMouseListener(new MouseAdapter() {
26+
@Override
27+
public void mousePressed(MouseEvent e) {
28+
tryTriggerTabPopupEvent(e);
29+
}
30+
31+
@Override
32+
public void mouseReleased(MouseEvent e) {
33+
tryTriggerTabPopupEvent(e);
34+
}
35+
});
36+
}
37+
38+
public void registerPopupEventListener(ITabPopupEventListener tabPopupEventListener) {
39+
this.tabPopupEventListener = tabPopupEventListener;
40+
}
41+
42+
protected void tryTriggerTabPopupEvent(MouseEvent e) {
43+
if (e.isPopupTrigger()) {
44+
int index = tabbedPane.indexAtLocation(e.getX(), e.getY());
45+
if (index != -1) {
46+
Component popupOnTab = tabbedPane.getComponentAt(index);
47+
if (this.tabPopupEventListener != null) {
48+
this.tabPopupEventListener.onTabPopupEvent(tabbedPane, index, new TabPopupEvent(e, popupOnTab));
49+
}
50+
}
51+
}
52+
}
53+
54+
public JTabbedPane getTabbedPane() {
55+
return tabbedPane;
56+
}
57+
58+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package the.bytecode.club.uikit.tabpopup;
2+
3+
import java.awt.Component;
4+
import java.awt.event.MouseEvent;
5+
6+
public class TabPopupEvent extends MouseEvent {
7+
/**
8+
*
9+
*/
10+
private static final long serialVersionUID = 2510164400674753411L;
11+
12+
private final Component popupOnTab;
13+
14+
public TabPopupEvent(MouseEvent e, Component popupOnTab) {
15+
super(e.getComponent(), e.getID(), e.getWhen(), e.getModifiers(),
16+
e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger(), e.getButton());
17+
18+
this.popupOnTab = popupOnTab;
19+
}
20+
21+
public Component getPopupOnTab() {
22+
return popupOnTab;
23+
}
24+
25+
26+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package the.bytecode.club.uikit.tabpopup.closer;
2+
3+
import java.awt.Component;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
import javax.swing.JTabbedPane;
8+
9+
import the.bytecode.club.uikit.tabpopup.ITabZeroComponentEventListener;
10+
11+
/**
12+
* Provide function of closing tabs
13+
* @author su
14+
*
15+
*/
16+
public class JTabbedPaneCloser {
17+
private JTabbedPane tabbedPane;
18+
private ITabZeroComponentEventListener tabZeroComponentEventListener;
19+
20+
public JTabbedPaneCloser(JTabbedPane tabbedPane) {
21+
super();
22+
this.tabbedPane = tabbedPane;
23+
}
24+
25+
public JTabbedPaneCloser(JTabbedPane tabbedPane, ITabZeroComponentEventListener tabZeroComponentEventListener) {
26+
this(tabbedPane);
27+
this.tabZeroComponentEventListener = tabZeroComponentEventListener;
28+
}
29+
30+
public void removeComponent(Component component) {
31+
this.tabbedPane.remove(component);
32+
tryTriggerTabZeroComponentEvent();
33+
}
34+
35+
public void removeOtherComponents(Component component) {
36+
removeOtherComponents(component, false);
37+
}
38+
39+
protected void removeOtherComponents(Component component, boolean equalStop) {
40+
int i = this.tabbedPane.getTabCount();
41+
while (i-- > 0) {
42+
Component c = this.tabbedPane.getComponentAt(i);
43+
if (c != component) {
44+
this.tabbedPane.remove(i);
45+
} else if (equalStop) {
46+
break ;
47+
}
48+
}
49+
50+
tryTriggerTabZeroComponentEvent();
51+
}
52+
53+
public void removeLeftComponents(Component component) {
54+
int count = this.tabbedPane.getTabCount();
55+
int i = 0;
56+
List<Component> removeTabs = new ArrayList<>();
57+
do {
58+
Component c = this.tabbedPane.getComponentAt(i);
59+
if (c != component) {
60+
removeTabs.add(c);
61+
} else {
62+
break ;
63+
}
64+
} while (i++ < count);
65+
66+
for (Component c : removeTabs) {
67+
this.tabbedPane.remove(c);
68+
}
69+
70+
tryTriggerTabZeroComponentEvent();
71+
}
72+
73+
public void removeRightComponents(Component component) {
74+
removeOtherComponents(component, true);
75+
}
76+
77+
public void removeAllComponents() {
78+
this.tabbedPane.removeAll();
79+
tryTriggerTabZeroComponentEvent();
80+
}
81+
82+
private void tryTriggerTabZeroComponentEvent() {
83+
if (this.tabbedPane.getTabCount() == 0 && tabZeroComponentEventListener != null) {
84+
tabZeroComponentEventListener.onTabZeroComponent(this.tabbedPane);
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)