sbool installInternalFrameSwitcher_v2_debug; svoid installInternalFrameSwitcher_v2(final JDesktopPane desktop) { swing { new DesktopListener desktopListener; desktop.addContainerListener(desktopListener); new SwitchDispatcher<JInternalFrame>(new DesktopSwitcher(desktop), desktopListener).start(); } } sclass JInternalFrameCellRenderer extends DefaultListCellRenderer { static int marginW = 20, marginH = 3; public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); setText(((JInternalFrame) value).getTitle()); setMargin(marginW, marginH, this); ret c; } } sclass DesktopListener extends ContainerAdapter implements SwitchableComponentsListener<JInternalFrame> { private final List<JInternalFrame> frames = new ArrayList<>(); private final boolean titleOptional; private final InternalFrameAdapter frameActivatedListener = new InternalFrameAdapter() { @Override public void internalFrameActivated(InternalFrameEvent e) { JInternalFrame frame = e.getInternalFrame(); frames.remove(frame); frames.add(0, frame); } }; public DesktopListener() { this(false); } public DesktopListener(boolean titleOptional) { this.titleOptional = titleOptional; } @Override public void componentAdded(final ContainerEvent e) { if (e.getChild() instanceof JInternalFrame) { final JInternalFrame frame = (JInternalFrame) e.getChild(); if (isTitleOptional() || frame.getTitle() != null && !frame.getTitle().trim().isEmpty()) { frames.add(frame); frame.addInternalFrameListener(frameActivatedListener); } } } @Override public void componentRemoved(final ContainerEvent e) { if (e.getChild() instanceof JInternalFrame) { JInternalFrame frame = (JInternalFrame) e.getChild(); frames.remove(frame); frame.removeInternalFrameListener(frameActivatedListener); } } private boolean isTitleOptional() { return titleOptional; } public List<JInternalFrame> getSwitchableComponentList() { return frames; } } sclass DesktopSwitcher implements Switcher<JInternalFrame> { private final JDesktopPane jDesktopPane; private SwitchDialog<JInternalFrame> switchDialog; public DesktopSwitcher(JDesktopPane jDesktopPane) { this.jDesktopPane = jDesktopPane; switchDialog = new SwitchDialog<>(SwingUtilities.getWindowAncestor(jDesktopPane), new ArrayList<JInternalFrame>()); initMouseListener(); } public void previous(List<JInternalFrame> switchableComponentList) { showMenu(switchableComponentList); switchDialog.selectPrevious(); } public void next(List<JInternalFrame> switchableComponentList) { showMenu(switchableComponentList); switchDialog.selectNext(); } public void dismiss() { hideMenu(); } @Override public JDesktopPane getDesktop() { return jDesktopPane; } @Override public boolean hasFocus() { return switchDialog.hasFocus() || switchDialog.getList().hasFocus(); } public SwitchDialog<JInternalFrame> getSwitchDialog() { return switchDialog; } private void showMenu(List<JInternalFrame> switchableComponentList) { switchDialog.setSwitchableComponents(switchableComponentList); if (!switchableComponentList.isEmpty()) { switchDialog.pack(); switchDialog.setLocationRelativeTo(jDesktopPane); switchDialog.setVisible(true); } } private void hideMenu() { if (switchDialog != null && switchDialog.isVisible()) { pcall { JInternalFrame selected = switchDialog.getSelected(); if (selected != null) { switchDialog.unselect(); selected.setSelected(true); selected.toFront(); } } switchDialog.dispose(); } } private void initMouseListener() { switchDialog.getList().addMouseListener(new MouseAdapter() { @Override public void mouseReleased(final MouseEvent e) { hideMenu(); } }); } } sclass SwitchDispatcher<T> implements KeyEventDispatcher { private static final KeyStroke nextStroke = KeyStroke.getKeyStroke("ctrl TAB"); private static final KeyStroke previousStroke = KeyStroke.getKeyStroke("ctrl shift TAB"); private final Switcher<T> switcher; private final SwitchableComponentsListener<T> desktopListener; public SwitchDispatcher(Switcher<T> switcher, SwitchableComponentsListener<T> switchableComponentsListener) { this.switcher = switcher; this.desktopListener = switchableComponentsListener; } public void start() { KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); } public void stop() { KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); } public boolean dispatchKeyEvent(KeyEvent e) { boolean shouldSwitch = isDesktopPaneFocused(e.getComponent(), switcher.getDesktop()) || switcher.hasFocus(); if (!shouldSwitch) { return false; } KeyStroke keyStrokeForEvent = KeyStroke.getKeyStrokeForEvent(e); boolean next = nextStroke.equals(keyStrokeForEvent); boolean previous = previousStroke.equals(keyStrokeForEvent); boolean dismiss = e.getKeyCode() == KeyEvent.VK_CONTROL && !e.isControlDown(); if (installInternalFrameSwitcher_v2_debug) print("Have keystroke: " + keyStrokeForEvent + ", " + next + "/" + previous + "/" + dismiss); if (next) { switcher.next(desktopListener.getSwitchableComponentList()); } else if (previous) { switcher.previous(desktopListener.getSwitchableComponentList()); } else if (dismiss) { switcher.dismiss(); } return next || previous || dismiss; } private boolean isDesktopPaneFocused(Component component, JDesktopPane desktop) { return getDesktopPaneParent(component) == desktop; } private JDesktopPane getDesktopPaneParent(Component component) { Component parent = component; while (parent != null && !(parent instanceof JDesktopPane)) { parent = parent.getParent(); } return (JDesktopPane) parent; } } sinterface SwitchableComponentsListener<T> { /** * Get a list of the components that the user can switch through. * Ideally, this would be sorted by the last focused order. * * @return - list of switchable components of type T */ List<T> getSwitchableComponentList(); } /** * This class will do the actual switching based on the lists of components it receives. * * @param <T> - The type of the components that can be switched. {@link javax.swing.JInternalFrame} initially but * will be extended for tabs and other components. */ sinterface Switcher<T> { /** * Trigger this to select the previous component in the list * * @param switchableComponentList - list of all the switchable components */ void previous(List<T> switchableComponentList); /** * Trigger this to select the next component in the list * * @param switchableComponentList - list of all the switchable components */ void next(List<T> switchableComponentList); /** * This method will hide the dialog that shows all the switchable components if it exists. */ void dismiss(); /** * Returns the desktop pane on which the switcher is working */ JDesktopPane getDesktop(); /** * Checks whether the switcher component currently has focus * @return - true if the switch dialog is open and has focus; false otherwise */ boolean hasFocus(); } sclass SwitchDialog<T> extends JDialog { private final JList<T> list; public SwitchDialog(Window owner, List<T> titles) { super(owner); setUndecorated(true); list = new JList<>(new Vector<>(titles)); addFocusListener(focusLostListener); initList(); setContentPane(jCenteredSection(" Frames ", list)); pack(); } private void initList() { list.setCellRenderer(new JInternalFrameCellRenderer); list.setSelectedIndex(0); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.addFocusListener(focusLostListener); list.setSelectionModel(new DefaultListSelectionModel() { public void removeSelectionInterval(int index0, int index1) {} public void addSelectionInterval(int index0, int index1) { super.setSelectionInterval(index0, index1); } }); } public void selectNext() { int indexToSelect = list.getSelectedIndex() != list.getModel().getSize() - 1 ? list.getSelectedIndex() + 1 : 0; list.setSelectedIndex(indexToSelect); } public void selectPrevious() { int indexToSelect = list.getSelectedIndex() != 0 ? list.getSelectedIndex() - 1 : list.getModel().getSize() - 1; list.setSelectedIndex(indexToSelect > -1 ? indexToSelect : 0); } public T getSelected() { return list.getSelectedValue(); } public void unselect() { list.setSelectedIndex(-1); } public void setSwitchableComponents(List<T> switchableComponents) { T oldSelection = list.getSelectedValue(); list.setListData(new Vector<>(switchableComponents)); list.setSelectedValue(oldSelection, false); } public JList<T> getList() { return list; } private final FocusAdapter focusLostListener = new FocusAdapter { public void focusLost(FocusEvent e) { dispose(); } }; }
Began life as a copy of #1016825
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1016948 |
Snippet name: | installInternalFrameSwitcher_v2 |
Eternal ID of this version: | #1016948/14 |
Text MD5: | f0c4e3ee36cf88d4eaff3456c7eb859f |
Author: | stefan |
Category: | javax / gui |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-09-26 17:21:32 |
Source code size: | 10033 bytes / 311 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 337 / 395 |
Version history: | 13 change(s) |
Referenced in: | [show references] |