package org.limewire.ui.swing.mainframe; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Rectangle; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.SwingUtilities; import org.limewire.core.api.Application; import org.limewire.core.api.updates.UpdateEvent; import org.limewire.core.settings.DownloadSettings; import org.limewire.friend.api.FriendConnectionEvent; import org.limewire.listener.EventListener; import org.limewire.listener.ListenerSupport; import org.limewire.listener.SwingEDTEvent; import org.limewire.ui.swing.components.FocusJOptionPane; import org.limewire.ui.swing.components.LimeSplitPane; import org.limewire.ui.swing.components.PanelResizer; import org.limewire.ui.swing.downloads.DownloadHeaderPanel; import org.limewire.ui.swing.downloads.DownloadVisibilityListener; import org.limewire.ui.swing.downloads.MainDownloadPanel; import org.limewire.ui.swing.event.DownloadVisibilityEvent; import org.limewire.ui.swing.friends.login.LoginPopupPanel; import org.limewire.ui.swing.nav.Navigator; import org.limewire.ui.swing.pro.ProNagController; import org.limewire.ui.swing.search.SearchHandler; import org.limewire.ui.swing.settings.SwingUiSettings; import org.limewire.ui.swing.statusbar.SharedFileCountPopupPanel; import org.limewire.ui.swing.statusbar.StatusPanel; import org.limewire.ui.swing.update.UpdatePanel; import org.limewire.ui.swing.util.GuiUtils; import org.limewire.ui.swing.util.I18n; import com.google.inject.Inject; import com.google.inject.Provider; public class LimeWireSwingUI extends JPanel { private final JPanel centerPanel; private final TopPanel topPanel; private final JLayeredPane layeredPane; private final ProNagController proNagController; private final LimeSplitPane splitPane; private final Provider<SignOnMessageLayer> signOnMessageProvider; private final MainDownloadPanel mainDownloadPanel; private final DownloadHeaderPanel downloadHeaderPanel; @Inject public LimeWireSwingUI( TopPanel topPanel, MainPanel mainPanel, StatusPanel statusPanel, Navigator navigator, SearchHandler searchHandler, ProNagController proNagController, SharedFileCountPopupPanel sharedFileCountPopup, LoginPopupPanel loginPopup, Provider<SignOnMessageLayer> signOnMessageProvider, MainDownloadPanel mainDownloadPanel, DownloadHeaderPanel downloadHeaderPanel, @GlobalLayeredPane JLayeredPane limeWireLayeredPane) { GuiUtils.assignResources(this); this.topPanel = topPanel; this.layeredPane = limeWireLayeredPane; this.proNagController = proNagController; this.signOnMessageProvider = signOnMessageProvider; this.centerPanel = new JPanel(new GridBagLayout()); this.mainDownloadPanel = mainDownloadPanel; this.downloadHeaderPanel = downloadHeaderPanel; splitPane = createSplitPane(mainPanel, mainDownloadPanel, downloadHeaderPanel.getComponent()); mainDownloadPanel.setVisible(false); setLayout(new BorderLayout()); GridBagConstraints gbc = new GridBagConstraints(); // The top panel gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.NORTH; gbc.weightx = 1; gbc.weighty = 0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridheight = 1; centerPanel.add(topPanel, gbc); // The main panel gbc.fill = GridBagConstraints.BOTH; gbc.anchor = GridBagConstraints.CENTER; gbc.weightx = 1; gbc.weighty = 1; gbc.gridwidth = GridBagConstraints.REMAINDER; centerPanel.add(splitPane, gbc); layeredPane.addComponentListener(new MainPanelResizer(centerPanel)); layeredPane.add(centerPanel, JLayeredPane.DEFAULT_LAYER); layeredPane.add(sharedFileCountPopup, JLayeredPane.PALETTE_LAYER); layeredPane.addComponentListener(new PanelResizer(sharedFileCountPopup)); layeredPane.add(loginPopup, JLayeredPane.POPUP_LAYER); layeredPane.addComponentListener(new PanelResizer(loginPopup)); add(layeredPane, BorderLayout.CENTER); add(statusPanel, BorderLayout.SOUTH); } @Inject public void registerListener(){ mainDownloadPanel.addDownloadVisibilityListener(new DownloadVisibilityHandler()); } private boolean isFirstPainting = true; @Override public void paint(Graphics g){ if(isFirstPainting && splitPane.getHeight() > 0){ isFirstPainting = false; if(DownloadSettings.ALWAYS_SHOW_DOWNLOADS_TRAY.getValue()){ handleDownloadVisibiltyChange(true); } } super.paint(g); } void hideMainPanel() { layeredPane.setVisible(false); centerPanel.setVisible(false); } void showMainPanel() { layeredPane.setVisible(true); centerPanel.setVisible(true); } void loadProNag() { proNagController.allowProNag(layeredPane); } public void goHome() { topPanel.goHome(); } public void focusOnSearch() { topPanel.requestFocusInWindow(); } private LimeSplitPane createSplitPane(final JComponent top, final MainDownloadPanel bottom, JComponent divider) { final LimeSplitPane splitPane = new LimeSplitPane(JSplitPane.VERTICAL_SPLIT, true, top, bottom, divider); splitPane.setDividerSize(0); bottom.setVisible(false); splitPane.setBorder(BorderFactory.createEmptyBorder()); //Allow bottom panel to be minimized bottom.setMinimumSize(new Dimension(0, 0)); //The bottom panel remains the same size when the splitpane is resized splitPane.setResizeWeight(1); //set top panel's minimum height to half of split pane height //(this fires when the app is initialized) splitPane.addComponentListener(new ComponentAdapter(){ @Override public void componentResized(ComponentEvent e) { top.setMinimumSize(new Dimension(0, splitPane.getHeight()/2)); } }); mainDownloadPanel.addComponentListener(new ComponentAdapter(){ @Override public void componentResized(ComponentEvent e) { int height = bottom.getHeight(); if(height > bottom.getDefaultPreferredHeight()){ SwingUiSettings.DOWNLOAD_TRAY_SIZE.setValue(height); } else { SwingUiSettings.DOWNLOAD_TRAY_SIZE.setValue(bottom.getDefaultPreferredHeight()); } } }); return splitPane; } private class DownloadVisibilityHandler implements DownloadVisibilityListener { @Override public void updateVisibility(DownloadVisibilityEvent event) { handleDownloadVisibiltyChange(event.getVisibility()); } } private void handleDownloadVisibiltyChange(boolean isVisible){ assert(SwingUtilities.isEventDispatchThread()); splitPane.getBottomComponent().setVisible(isVisible); if (isVisible) { splitPane.setDividerSize(downloadHeaderPanel.getComponent().getPreferredSize().height); int preferredDividerPosition = splitPane.getSize().height - splitPane.getInsets().bottom - splitPane.getDividerSize() - splitPane.getBottomComponent().getPreferredSize().height; if (preferredDividerPosition < (splitPane.getHeight()/2)){ preferredDividerPosition = splitPane.getHeight()/2; } splitPane.setDividerLocation(preferredDividerPosition); } else { splitPane.setDividerSize(0); } } private static class MainPanelResizer extends ComponentAdapter { private final JComponent target; public MainPanelResizer(JComponent target) { this.target = target; } @Override public void componentResized(ComponentEvent e) { Rectangle parentBounds = e.getComponent().getBounds(); target.setBounds(0, 0, (int)parentBounds.getWidth(), (int)parentBounds.getHeight()); } } /** * Listens for Update events and display a dialog if a update exists. * @param updateEvent */ @Inject void register(ListenerSupport<UpdateEvent> updateEvent, ListenerSupport<FriendConnectionEvent> connectionSupport, final Application application) { updateEvent.addListener(new EventListener<UpdateEvent>() { @Override @SwingEDTEvent public void handleEvent(UpdateEvent event) { UpdatePanel updatePanel = new UpdatePanel(event.getData(), application); JDialog dialog = FocusJOptionPane.createDialog(I18n.tr("New Version Available!"), null, updatePanel); dialog.setLocationRelativeTo(GuiUtils.getMainFrame()); dialog.getRootPane().setDefaultButton(updatePanel.getDefaultButton()); dialog.setSize(new Dimension(500, 300)); dialog.setModal(false); dialog.setVisible(true); } }); // Add listener to display sign-on message if enabled. if (SignOnMessageLayer.isSignOnMessageEnabled()) { connectionSupport.addListener(new EventListener<FriendConnectionEvent>() { @Override @SwingEDTEvent public void handleEvent(FriendConnectionEvent event) { if (event.getType() == FriendConnectionEvent.Type.CONNECTED) { signOnMessageProvider.get().showMessage(); } } }); } } }