From bfdab8ac4b36c3a5f90a234ce02fb8454f2f59ae Mon Sep 17 00:00:00 2001 From: Cody <6558800+Bl3nd@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:27:07 -0600 Subject: [PATCH 1/2] Middle-click to close tabs. - We could now also add the popup menu on the tab itself if we want to instead of just the button. --- .../gui/resourceviewer/TabComponent.java | 135 +++++++++++++++++- 1 file changed, 129 insertions(+), 6 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java index 42d58f7d..505567e9 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java @@ -19,6 +19,7 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer; import com.github.weisj.darklaf.components.CloseButton; +import com.github.weisj.darklaf.ui.tabbedpane.*; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.gui.components.listeners.MouseClickedListener; import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer; @@ -26,7 +27,8 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseEvent; +import java.awt.event.*; +import java.util.Objects; public class TabComponent extends JPanel { @@ -72,11 +74,8 @@ public class TabComponent extends JPanel rightClickMenu.add(closeTab); button.setComponentPopupMenu(rightClickMenu); - //TODO add left-click close: when we add a new listener the parent listener (jTabbedPane) conflicts and won't respect the opaque flag. - // button.addMouseListener(new MouseClickedListener(e -> - // if (e.getButton() == MouseEvent.BUTTON2) // middle-click - // closePane(); - // })); + addMouseListener(new TabMouseListener()); + addMouseMotionListener(new TabMouseListener()); button.addMouseListener(new MouseClickedListener(e -> { @@ -145,4 +144,128 @@ public class TabComponent extends JPanel pane.remove(index); } + /** + * Get the tab panel for mouse positions. + * + * @return the panel. + */ + private ScrollableTabPanel getTabPanel() + { + for (Component component : Objects.requireNonNull(viewport()).getComponents()) + if (component instanceof ScrollableTabPanel) + return (ScrollableTabPanel) component; + + return null; + } + + /** + * Get the viewport from darklaf. + * + * @return the viewport. + */ + private DarkScrollableTabViewport viewport() + { + for (Component component : pane.getComponents()) + if (component instanceof DarkScrollableTabViewport) + return (DarkScrollableTabViewport) component; + + return null; + } + + /** + * Get the tabbed pane handler from darklaf. + * + * @return the handler. + */ + private DarkScrollTabbedPaneHandler getHandler() + { + for (Component component : pane.getComponents()) + { + if (component instanceof DarkScrollableTabViewport) + { + DarkScrollableTabViewport viewport = (DarkScrollableTabViewport) component; + for (MouseListener mouseListener : viewport.getMouseListeners()) + if (mouseListener instanceof DarkScrollTabbedPaneHandler) + return (DarkScrollTabbedPaneHandler) mouseListener; + } + } + + return null; + } + + /** + * Create our own listener that redirects events back to darklaf. + */ + private class TabMouseListener extends MouseAdapter + { + @Override + public void mouseClicked(MouseEvent e) + { + e = convert(e); + Objects.requireNonNull(getHandler()).mouseClicked(e); + } + + @Override + public void mousePressed(MouseEvent e) + { + if (e.getButton() == MouseEvent.BUTTON2) + { + closePane(); + return; + } + + e = convert(e); + Objects.requireNonNull(getHandler()).mousePressed(e); + } + + @Override + public void mouseEntered(MouseEvent e) + { + e = convert(e); + Objects.requireNonNull(getHandler()).mouseEntered(e); + } + + @Override + public void mouseExited(MouseEvent e) + { + e = convert(e); + Objects.requireNonNull(getHandler()).mouseExited(e); + } + + @Override + public void mouseReleased(MouseEvent e) + { + e = convert(e); + Objects.requireNonNull(getHandler()).mouseReleased(e); + } + + @Override + public void mouseDragged(MouseEvent e) + { + e = convert(e); + Objects.requireNonNull(getHandler()).mouseDragged(e); + } + + @Override + public void mouseMoved(MouseEvent e) + { + e = convert(e); + Objects.requireNonNull(getHandler()).mouseMoved(e); + } + + + + private MouseEvent convert(MouseEvent e) + { + ScrollableTabPanel tabPanel = getTabPanel(); + if (tabPanel == null || tabPanel.getMousePosition() == null) + return null; + + int x = tabPanel.getMousePosition().x; + int y = tabPanel.getMousePosition().y; + return new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiersEx(), x, y, + e.getClickCount(), e.isPopupTrigger()); + } + } + } From 4597dbef7a57c6719fbe5a3d64ebe2dab0149be4 Mon Sep 17 00:00:00 2001 From: Cody <6558800+Bl3nd@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:33:32 -0600 Subject: [PATCH 2/2] Add null-check for converting event just to be safe. --- .../gui/resourceviewer/TabComponent.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java index 505567e9..d307d4c4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/TabComponent.java @@ -202,6 +202,9 @@ public class TabComponent extends JPanel public void mouseClicked(MouseEvent e) { e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mouseClicked(e); } @@ -215,6 +218,9 @@ public class TabComponent extends JPanel } e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mousePressed(e); } @@ -222,6 +228,9 @@ public class TabComponent extends JPanel public void mouseEntered(MouseEvent e) { e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mouseEntered(e); } @@ -229,6 +238,9 @@ public class TabComponent extends JPanel public void mouseExited(MouseEvent e) { e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mouseExited(e); } @@ -236,6 +248,9 @@ public class TabComponent extends JPanel public void mouseReleased(MouseEvent e) { e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mouseReleased(e); } @@ -243,6 +258,9 @@ public class TabComponent extends JPanel public void mouseDragged(MouseEvent e) { e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mouseDragged(e); } @@ -250,11 +268,12 @@ public class TabComponent extends JPanel public void mouseMoved(MouseEvent e) { e = convert(e); + if (e == null) + return; + Objects.requireNonNull(getHandler()).mouseMoved(e); } - - private MouseEvent convert(MouseEvent e) { ScrollableTabPanel tabPanel = getTabPanel();