/** * * Copyright * 2009-2015 Jayway Products AB * 2016-2017 Föreningen Sambruk * * Licensed under AGPL, Version 3.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.gnu.org/licenses/agpl.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package se.streamsource.streamflow.client.util.popup; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import org.qi4j.api.util.Iterables; import se.streamsource.streamflow.client.util.StreamflowToggleButton; public class StandardPopupHandler implements PopupHandler { private StreamflowToggleButton button; private JPanel optionsPanel; private JDialog popup; private final JPanel parentPanel; private Position position; private boolean refreshOnClose; private RefreshHandler refreshHandler; public StandardPopupHandler(JPanel parent, Action action, RefreshHandler refreshHandler) { this( parent, action, Position.left, true, refreshHandler ); } public StandardPopupHandler(final JPanel parent, Action action, Position position, boolean refreshOnClose, RefreshHandler refreshHandler) { this.parentPanel = parent; this.position = position; this.refreshOnClose = refreshOnClose; this.refreshHandler = refreshHandler; button = new StreamflowToggleButton( action ); button.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent itemEvent) { int state = itemEvent.getStateChange(); if (state == ItemEvent.SELECTED) { cleanToggleButtonSelection(); optionsPanel = new JPanel(); JToggleButton button = (JToggleButton) itemEvent.getSource(); showPopup( button ); } else if (state == ItemEvent.DESELECTED) { kill(); } } } ); } public StreamflowToggleButton getButton() { return button; } public void setPanelContent(JPanel filterPanel) { optionsPanel.add( filterPanel ); } private void showPopup(final Component button) { SwingUtilities.invokeLater( new Runnable() { public void run() { // Make it impossible to have several popups open at the same time if (popup != null) { popup.dispose(); popup = null; } final JFrame frame = (JFrame) SwingUtilities.getAncestorOfClass( JFrame.class, parentPanel ); popup = new JDialog( frame ); popup.getRootPane().registerKeyboardAction( new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Enter"); kill(); cleanToggleButtonSelection(); } }, KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), JComponent.WHEN_IN_FOCUSED_WINDOW ); popup.setUndecorated( true ); popup.setModal( false ); popup.setLayout( new BorderLayout() ); popup.add( optionsPanel, BorderLayout.CENTER ); Point location = button.getLocationOnScreen(); int diff = 0; if (position == Position.right) { diff = (int) optionsPanel.getPreferredSize().getWidth() - button.getWidth(); } popup.setBounds( (int) location.getX() -diff, (int) location.getY() + button.getHeight(), optionsPanel.getWidth(), optionsPanel.getHeight() ); popup.pack(); popup.setVisible( true ); frame.addComponentListener( new ComponentAdapter() { @Override public void componentMoved(ComponentEvent e) { if (popup != null) { System.out.println("Moved"); kill(); ((JToggleButton) button).setSelected( false ); frame.removeComponentListener( this ); } } } ); } } ); } public void kill() { if (popup != null) { popup.setVisible( false ); popup.dispose(); popup = null; } if (refreshOnClose) { refreshHandler.refresh(); } } private void cleanToggleButtonSelection() { for (Component component : Iterables.flatten( Iterables.iterable( parentPanel.getComponents() ), Iterables.iterable( parentPanel.getComponents() ) )) { if (!(component instanceof JToggleButton)) continue; if (((JToggleButton) component).isSelected() && component != button) { ((JToggleButton) component).setSelected( false ); } } } }