From af1edda1cc1231031b4af34cb87a2fb7a6e71fea Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Fri, 1 Feb 2008 04:23:00 +0000 Subject: [PATCH] [ 1884105 ] Show preview of all open window - Ctrl+W to show a preview of all open windows. --- client/src/org/compiere/apps/AMenu.java | 12 +- client/src/org/compiere/apps/APanel.java | 16 +- client/src/org/compiere/apps/WindowMenu.java | 253 ++++++++++++++++++- 3 files changed, 273 insertions(+), 8 deletions(-) diff --git a/client/src/org/compiere/apps/AMenu.java b/client/src/org/compiere/apps/AMenu.java index 388652a446..dd38e53b20 100644 --- a/client/src/org/compiere/apps/AMenu.java +++ b/client/src/org/compiere/apps/AMenu.java @@ -232,6 +232,7 @@ public final class AMenu extends CFrame private VTreePanel treePanel = null; private WFActivity wfActivity = null; private WFPanel wfPanel = null; + private WindowMenu m_WindowMenu; /** * Static Init. @@ -424,8 +425,13 @@ public final class AMenu extends CFrame } //Window Menu - JMenu mWindow = new WindowMenu(windowManager, this); - menuBar.add(mWindow); + m_WindowMenu = new WindowMenu(windowManager, this); + menuBar.add(m_WindowMenu); + KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK); + this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "ShowAllWindow"); + AppsAction action = new AppsAction("ShowAllWindow", ks, false); + this.getRootPane().getActionMap().put("ShowAllWindow", action); + action.setDelegate(this); // Help JMenu mHelp = AEnv.getMenu("Help"); @@ -533,6 +539,8 @@ public final class AMenu extends CFrame gotoNotes(); else if (e.getSource() == bRequests) gotoRequests(); + else if (e.getActionCommand().equals("ShowAllWindow")) + m_WindowMenu.expose(); else if (!AEnv.actionPerformed(e.getActionCommand(), m_WindowNo, this)) log.log(Level.SEVERE, "unknown action=" + e.getActionCommand()); //updateInfo(); diff --git a/client/src/org/compiere/apps/APanel.java b/client/src/org/compiere/apps/APanel.java index e76806fd92..4a3ce07b36 100644 --- a/client/src/org/compiere/apps/APanel.java +++ b/client/src/org/compiere/apps/APanel.java @@ -19,6 +19,7 @@ package org.compiere.apps; import java.awt.*; import java.awt.event.*; +import java.beans.PropertyChangeListener; import java.util.*; import java.util.logging.*; @@ -218,9 +219,12 @@ public final class APanel extends CPanel // Local (added to toolbar) private AppsAction aReport, aEnd, aHome, aHelp, aProduct, aLogout, aAccount, aCalculator, aCalendar, aEditor, aPreference, aScript, - aOnline, aMailSupport, aAbout, aPrintScr, aScrShot, aExit, aBPartner, aDeleteSelection; + aOnline, aMailSupport, aAbout, aPrintScr, aScrShot, aExit, aBPartner, + aDeleteSelection, aShowAllWindow; private SwitchAction aSwitchLinesDownAction, aSwitchLinesUpAction; + + private WindowMenu m_WindowMenu; /************************************************************************** * Create Menu and Toolbar and registers keyboard actions. * - started from constructor @@ -349,8 +353,9 @@ public final class APanel extends CPanel //Window AMenu aMenu = (AMenu)Env.getWindow(0); - JMenu mWindow = new WindowMenu(aMenu.getWindowManager(), m_window); - menuBar.add(mWindow); + m_WindowMenu = new WindowMenu(aMenu.getWindowManager(), m_window); + menuBar.add(m_WindowMenu); + aShowAllWindow = addAction("ShowAllWindow", null, KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK), false); // Help JMenu mHelp = AEnv.getMenu("Help"); @@ -1376,7 +1381,8 @@ public final class APanel extends CPanel } // Problem: doubleClick detection - can't disable button as clicking button may change button status - setBusy (true, true); + if (!cmd.equals(aShowAllWindow.getName())) + setBusy (true, true); // Command Buttons if (e.getSource() instanceof VButton) { @@ -1506,6 +1512,8 @@ public final class APanel extends CPanel // General Commands (Environment) else if (cmd.equals(aLogout.getName())) cmd_logout(); + else if (cmd.equals(aShowAllWindow.getName())) + m_WindowMenu.expose(); else if (!AEnv.actionPerformed (e.getActionCommand(), m_curWindowNo, this)) log.log(Level.SEVERE, "No action for: " + cmd); } diff --git a/client/src/org/compiere/apps/WindowMenu.java b/client/src/org/compiere/apps/WindowMenu.java index e784446211..0904e0ff7b 100644 --- a/client/src/org/compiere/apps/WindowMenu.java +++ b/client/src/org/compiere/apps/WindowMenu.java @@ -13,19 +13,66 @@ *****************************************************************************/ package org.compiere.apps; +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.awt.event.WindowStateListener; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; +import javax.swing.JDialog; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JRootPane; +import javax.swing.KeyStroke; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; +import org.compiere.swing.CDialog; import org.compiere.swing.CFrame; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.jdesktop.swingx.JXButton; +import org.jdesktop.swingx.JXDialog; +import org.jdesktop.swingx.JXHyperlink; +import org.jdesktop.swingx.JXImagePanel; +import org.jdesktop.swingx.JXImageView; +import org.jdesktop.swingx.JXPanel; +import org.jdesktop.swingx.JXTitledPanel; +import org.jdesktop.swingx.painter.Painter; +import org.jdesktop.swingx.plaf.PainterUIResource; /** * Menu component that handles the functionality expected of a standard @@ -42,6 +89,8 @@ public class WindowMenu extends JMenu { private JFrame frame; private JMenuItem closeAll=new JMenuItem("Close All Windows"); private JMenuItem closeOthers = new JMenuItem("Close Other Windows"); + private JMenuItem expose = new JMenuItem("Show All"); + private JXTitledPanel firstBox; private void setEnvText(JMenu menu, String msg) { String text = Msg.getMsg(Env.getCtx(), msg); @@ -88,6 +137,18 @@ public class WindowMenu extends JMenu { WindowMenu.this.windowManager.closeOthers((CFrame)WindowMenu.this.frame); } }); + expose.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + SwingUtilities.invokeLater(new Runnable() { + + public void run() { + expose(); + } + }); + } + }); + setEnvText(expose, "ShowAllWindow"); + expose.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK)); setEnvText(closeOthers, "CloseOtherWindows"); addMenuListener(new MenuListener() { public void menuCanceled (MenuEvent e) {} @@ -102,17 +163,117 @@ public class WindowMenu extends JMenu { }); } - /* Sets up the children menus depending on the current desktop state */ + private JXPanel createSelectionPanel() { + + GridLayout l = new GridLayout(3, 3); + l.setHgap(5); + l.setVgap(5); + + JXPanel p = new JXPanel(); + p.setLayout(l); + + return p; + } + + public void expose() { + + final JDialog dialog = new JDialog(frame); + dialog.setSize(Toolkit.getDefaultToolkit().getScreenSize()); + dialog.setUndecorated(true); + dialog.setModal(true); + + //add escape to close + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent actionEvent) { + dialog.setVisible(false); + } + }; + JRootPane jr = dialog.getRootPane(); + KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); + jr.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); + + //new Thread(new Loader(dialog)).start(); + SwingUtilities.invokeLater(new Loader(dialog)); + + dialog.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + dialog.setVisible(true); + } + + private JXTitledPanel createImageBox(JPanel p, final JDialog dialog, + int width, int height, final CFrame window) { + BufferedImage bi = new BufferedImage (window.getWidth(), window.getHeight(), + BufferedImage.TYPE_INT_RGB); // TYPE_INT_ARGB is tinted red + window.paintAll(bi.createGraphics()); + + Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH); + + final JXTitledPanel box = new JXTitledPanel(); + final Painter painter = box.getTitlePainter(); + box.setTitlePainter(null); + box.setFocusable(true); + box.setTitle(window.getTitle()); + final JXImageView imageView = new JXImageView(); + imageView.setImage(image); + imageView.setEditable(false); + box.setContentContainer(imageView); + box.setPreferredSize(new Dimension(width,height)); + box.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + box.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + dialog.dispose(); + AEnv.showWindow(window); + } + + @Override + public void mouseEntered(MouseEvent e) { + box.requestFocus(); + } + }); + imageView.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + dialog.dispose(); + AEnv.showWindow(window); + } + + @Override + public void mouseEntered(MouseEvent e) { + box.requestFocus(); + } + }); + imageView.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + box.addFocusListener(new FocusAdapter(){ + + @Override + public void focusGained(FocusEvent e) { + box.setTitlePainter(painter); + } + + @Override + public void focusLost(FocusEvent e) { + box.setTitlePainter(null); + } + + }); + return box; + } + + /* Sets up the children menus depending on the current desktop state */ private void buildChildMenus() { this.removeAll(); int i; ChildMenuItem menu; CFrame[] array = windowManager.getWindows(); + add(expose); + if ( !(frame instanceof AMenu) ) add(closeOthers); add(closeAll); + if (array.length > 0) { + expose.setEnabled(true); closeAll.setEnabled(true); if ( array.length > 1 ) closeOthers.setEnabled(true); @@ -122,6 +283,7 @@ public class WindowMenu extends JMenu { } else { closeAll.setEnabled(false); closeOthers.setEnabled(false); + expose.setEnabled(false); } if ( !(frame instanceof AMenu) ) { @@ -168,4 +330,91 @@ public class WindowMenu extends JMenu { return window; } } -} \ No newline at end of file + + class Loader implements Runnable { + private JDialog dialog; + + Loader(JDialog d) { + dialog = d; + } + + public void run() { + CFrame[] w = windowManager.getWindows(); + Container dialogContent = dialog.getContentPane(); + dialogContent.setLayout(new BorderLayout()); + + final CardLayout card = new CardLayout(); + final JXPanel cardContainer = new JXPanel(card); + + dialogContent.add(cardContainer, BorderLayout.CENTER); + + JXPanel p = createSelectionPanel(); + cardContainer.add(p, "page1"); + + Dimension s = Toolkit.getDefaultToolkit().getScreenSize(); + int width = ( s.width - 30 ) / 3; + int height = ( s.height - 30 ) / 3; + int count = 0; + JFrame frame = Env.getWindow(0); + if (frame != null && frame instanceof AMenu) { + JXTitledPanel box = createImageBox(p, dialog, width, height, + (CFrame)frame); + p.add(box); + count ++; + firstBox = box; + } + int page = 1; + for(int i = 0; i < w.length; i++) { + count ++; + CFrame window = w[i]; + JXTitledPanel box = createImageBox(p, dialog, width, height, + window); + p.add(box); + if (i == 0 && firstBox == null) firstBox = box; + if ( count == 9) { + count = 0; + page++; + p = createSelectionPanel(); + cardContainer.add(p, "page" + page); + } + } + for ( int i = count; i < 9; i++ ) { + p.add(Box.createGlue()); + } + dialog.addWindowFocusListener(new WindowFocusListener() { + + public void windowGainedFocus(WindowEvent e) { + if (firstBox != null) + firstBox.requestFocus(); + } + + public void windowLostFocus(WindowEvent e) { + } + + }); + card.first(cardContainer); + if (page > 1) { + JXPanel ctrl = new JXPanel(); + JXButton previous = new JXButton("<"); + JXButton next = new JXButton(">"); + previous.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + card.previous(cardContainer); + } + + }); + next.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + card.next(cardContainer); + } + }); + ctrl.add(previous); + ctrl.add(next); + dialogContent.add(ctrl, BorderLayout.NORTH); + } + dialog.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + } +} +