Merge pull request #475 from sinyear/master

Add Popup Menu for close Tabs
This commit is contained in:
Konloch 2023-12-09 13:57:58 -08:00 committed by GitHub
commit d2d5fdb713
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

AI 샘플 코드 생성 중입니다

Loading...
9 changed files with 413 additions and 72 deletions

View File

@ -10,6 +10,8 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
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.*;
@ -58,78 +60,10 @@ public class Workspace extends TranslatedVisibleComponent {
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);

View File

@ -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());
}
}

View File

@ -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);
}

View File

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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,80 @@
package the.bytecode.club.uikit.tabpopup.closer;
import java.awt.Component;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import the.bytecode.club.uikit.tabpopup.AbstractJTabbedPanePopupMenuHandler;
/**
* PopupMenu & Items implementation of Close Tabs
* @author su
*
*/
public class JTabbedPanePopupMenuTabsCloser extends AbstractJTabbedPanePopupMenuHandler {
protected JTabbedPaneCloser tabbedPaneCloser;
private PopupMenuTabsCloseConfiguration closeConfiguration;
public JTabbedPanePopupMenuTabsCloser(JTabbedPane tabbedPane) {
super(tabbedPane);
this.tabbedPaneCloser = new JTabbedPaneCloser(tabbedPane);
}
public void configureCloseItems(PopupMenuTabsCloseConfiguration configuration) {
this.closeConfiguration = configuration;
}
public PopupMenuTabsCloseConfiguration getCloseConfiguration() {
return closeConfiguration;
}
@Override
public JPopupMenu toBuildTabPopupMenu(JTabbedPane tabbedPane, Component popupOnTab) {
JPopupMenu popUpMenu = new JPopupMenu();
if (closeConfiguration.isClose()) {
addItemCloseTab(popUpMenu, popupOnTab);
}
if (closeConfiguration.isCloseOthers()) {
addItemCloseOtherTabs(popUpMenu, popupOnTab);
}
if (closeConfiguration.isCloseAll()) {
addItemCloseAllTabs(popUpMenu);
}
if (closeConfiguration.isCloseLefts()) {
addItemCloseLeftTabs(popUpMenu, popupOnTab);
}
if (closeConfiguration.isCloseRights()) {
addItemCloseRightTabs(popUpMenu, popupOnTab);
}
return popUpMenu;
}
protected void addItemCloseTab(JPopupMenu popUpMenu, Component popupOnTab) {
addMenuItem(popUpMenu, "Close", e -> { tabbedPaneCloser.removeComponent(popupOnTab); });
}
protected void addItemCloseOtherTabs(JPopupMenu popUpMenu, Component popupOnTab) {
addMenuItem(popUpMenu, "Close Others", e -> { tabbedPaneCloser.removeOtherComponents(popupOnTab); });
}
protected void addItemCloseAllTabs(JPopupMenu popUpMenu) {
addMenuItem(popUpMenu, "Close All", e -> { tabbedPaneCloser.removeAllComponents(); });
}
protected void addItemCloseLeftTabs(JPopupMenu popUpMenu, Component popupOnTab) {
addMenuItem(popUpMenu, "Close Lefts", e -> { tabbedPaneCloser.removeLeftComponents(popupOnTab); });
}
protected void addItemCloseRightTabs(JPopupMenu popUpMenu, Component popupOnTab) {
addMenuItem(popUpMenu, "Close Rights", e -> { tabbedPaneCloser.removeRightComponents(popupOnTab); });
}
protected void addMenuItem(JPopupMenu popUpMenu, String item, ActionListener listener) {
JMenuItem menuItem = new JMenuItem(item);
popUpMenu.add(menuItem);
menuItem.addActionListener(listener);
}
}

View File

@ -0,0 +1,99 @@
package the.bytecode.club.uikit.tabpopup.closer;
/**
* PopupMenu items configuration of close tabs
* @author su
*
*/
public class PopupMenuTabsCloseConfiguration {
private boolean close;
private boolean closeOthers;
private boolean closeAll;
private boolean closeLefts;
private boolean closeRights;
public PopupMenuTabsCloseConfiguration(Builder builder) {
super();
this.close = builder.close;
this.closeOthers = builder.closeOthers;
this.closeAll = builder.closeAll;
this.closeLefts = builder.closeLefts;
this.closeRights = builder.closeRights;
}
public boolean isClose() {
return close;
}
public void Close(boolean close) {
this.close = close;
}
public boolean isCloseOthers() {
return closeOthers;
}
public void setCloseOthers(boolean closeOthers) {
this.closeOthers = closeOthers;
}
public boolean isCloseAll() {
return closeAll;
}
public void setCloseAll(boolean closeAll) {
this.closeAll = closeAll;
}
public boolean isCloseLefts() {
return closeLefts;
}
public void setCloseLefts(boolean closeLefts) {
this.closeLefts = closeLefts;
}
public boolean isCloseRights() {
return closeRights;
}
public void setCloseRights(boolean closeRights) {
this.closeRights = closeRights;
}
public static class Builder {
private boolean close;
private boolean closeOthers;
private boolean closeAll;
private boolean closeLefts;
private boolean closeRights;
public Builder close(boolean close) {
this.close = close;
return this;
}
public Builder closeOthers(boolean closeOthers) {
this.closeOthers = closeOthers;
return this;
}
public Builder closeAll(boolean closeAll) {
this.closeAll = closeAll;
return this;
}
public Builder closeLefts(boolean closeLefts) {
this.closeLefts = closeLefts;
return this;
}
public Builder closeRights(boolean closeRights) {
this.closeRights = closeRights;
return this;
}
public PopupMenuTabsCloseConfiguration build() {
return new PopupMenuTabsCloseConfiguration(this);
}
public PopupMenuTabsCloseConfiguration buildFull() {
return this.close(true).
closeOthers(true).
closeAll(true).
closeLefts(true).
closeRights(true).
build();
}
}
}