package app.navigps.gui.detailspanel; import app.navigps.gui.detailspanel.LoacationManager.LocationManager; import app.navigps.gui.repaintmanager.AlphaRepaintManager; import app.navigps.gui.borders.OvalBorder; import app.navigps.gui.borders.RoundBorder; import app.navigps.gui.detailspanel.LoacationManager.RightLocation; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; import java.util.Vector; import javax.swing.Icon; import javax.swing.RepaintManager; import javax.swing.SwingUtilities; import org.jdesktop.animation.timing.Animator; import org.jdesktop.animation.timing.Animator.Direction; import org.jdesktop.animation.timing.Animator.RepeatBehavior; import org.jdesktop.animation.timing.TimingTarget; import org.jdesktop.animation.timing.interpolation.PropertySetter; /** * Created on 2008-12-08, 21:25:25 * @author Gzregorz (vara) Warywoda */ public class RoundWindow extends RoundJPanel implements FocusListener{ public static final int CLOSE_WINDOW_ACTION = 0; public static final int OPEN_WINDOW_ACTION = 1; private static int currentAction = OPEN_WINDOW_ACTION; private boolean dynamicRevalidate = false; private Dimension defaultSize = new Dimension(330,400); private Color[] colorBorderGlow = {new Color(230,230,230,168),new Color(70,102,146,180), new Color(190,190,190, 250),new Color(255,255,255, 255)}; private boolean decoratedWindow = true; private Animator animator; private int animationDuration = 1300; private AbstractDecoratePanel decorate = new DecoratePanel(); private RoundWindowRootPane rootPane; private Insets innerGap = new Insets(7,7,7,7); private int decorateAndContentGap = 5; private LocationManager location; private WindowDisplayBehavior winBehavior = new WindowDisplayBehavior(); /* * Default options are: * Location: RightLocation * Border: OvalBorder with instets (3,3,3,3) */ public RoundWindow(){ super(20,20); setSize(defaultSize); OvalBorder mainBorder = (OvalBorder)getRoundBorder(); mainBorder.setInsets(new Insets(3,3,3,3)); setFocusable(true); addFocusListener(this); super.setLayout(new BorderLayout(0,getDecorateAndContentGap())); animator = new Animator(getAnimationDuration(), 1, RepeatBehavior.REVERSE,getWinBehavior()); //((DecoratePanel)decorate).addActionListenerToCloseButton(new CloseAction()); //contentPane.setBorder(new OvalBorder(3,5,3,5, mainBorder.getRecW(), // mainBorder.getRecH(), mainBorder.getBorderColor())); add(decorate,BorderLayout.NORTH); setRootPane(createRootPane()); getContentPane().setAlpha(0.0f); getDecoratePanel().setAlpha(0.0f); super.setEnabled(false); setLocationManager(new RightLocation(this)); winBehavior.addStartAction(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(e.getID() == OPEN_WINDOW_ACTION){ installRepaintManager(); } } }); } /** * Resize container */ public void pack(){ //getContentPane().revalidate(); ContentPaneForRoundWindow container = (ContentPaneForRoundWindow)getContentPane(); //System.out.println("coount "+container.getComponentCount()); Dimension contentPaneSize = container.getSize(); Insets contentInsets = container.getInsets(); Insets rootPaneInsets = getRoundWindowRootPane().getInsets(); Insets winInsets = getInsets(); int width = contentPaneSize.width + contentInsets.left+ contentInsets.right+ rootPaneInsets.left + rootPaneInsets.right + winInsets.left + winInsets.right; int height = contentPaneSize.height + contentInsets.top+ contentInsets.bottom+ rootPaneInsets.top + rootPaneInsets.bottom + winInsets.top + winInsets.bottom; //setSize(width, height); revalidate(); //System.err.println("Content size: "+contentPaneSize+ // " Insets rootPane: "+rootPaneInsets+ // " Insets Window "+winInsets+" window size "+getSize()); updatePosition(); } /** * * @return */ public boolean isEmpty(){ return !(getRoundWindowRootPane().getContentPane().getComponentCount()>0); } /** * * @return Rectangle represent window shape */ public RoundRectangle2D getWindowShape(){ Point2D corners = getOuterCorners(); return new RoundRectangle2D.Double( 0,0, getWidth(), getHeight(),corners.getX(),corners.getY()); } protected RoundWindowRootPane createRootPane(){ rootPane = new RoundWindowRootPane(); return rootPane; } public RoundWindowRootPane getRoundWindowRootPane() { return rootPane; } protected void setRootPane(RoundWindowRootPane rp){ add(rp, BorderLayout.CENTER); } public AlphaJPanel getContentPane(){ return rootPane.getContentPane(); } /** * */ public void clearWindow(){ setIcon(null); setTitle(""); getDecoratePanel().getContent().setIcon(null); getContentPane().removeAll(); } /** * * @param icon */ public void setIcon(Icon icon){ getDecoratePanel().getContent().setIcon(icon); } /** * * @param str */ public void setTitle(String str){ getDecoratePanel().setTitle(str); } /** * * @param aFlag */ @Override public void setEnabled(final boolean aFlag) { super.setEnabled(aFlag); if(animator.isRunning()){ animator.cancel(); } if(aFlag){ Float [] val = new Float[]{getAlpha(),getUpperThresholdAlpha()}; animator = PropertySetter.createAnimator(1500,this,"alphaToAllRootWindow",val); }else{ Float [] val = new Float[]{getAlpha(),0f}; animator = PropertySetter.createAnimator(1500,this,"alphaToAllRootWindow",val); } animator.addTarget(getWinBehavior()); animator.start(); /* SwingUtilities.invokeLater(new Runnable() { @Override public void run() { displayPanel(aFlag); } }); */ } /** * * @param val */ public void displayPanel(boolean val){ float frac = .0f; if(animator.isRunning()){ animator.cancel(); frac = getAlpha(); } if(val){ animator.setStartFraction(frac); animator.setStartDirection(Direction.FORWARD); currentAction = OPEN_WINDOW_ACTION; }else{ animator.setStartFraction(Math.max(getContentPane().getAlpha(),getAlpha())); animator.setStartDirection(Direction.BACKWARD); currentAction = CLOSE_WINDOW_ACTION; } animator.start(); } /** * */ public void updatePosition(){ Container parent = getParent(); if(parent == null) return; Rectangle rec = location.updateLocation(getParent()); updatePosition(rec); //int x = (getParent().getWidth()-getWidth()); //int y = (getParent().getHeight()-getHeight())>>1; //updateMyUI(x, y, getWidth(), getHeight()); //getVerboseStream().outputVerboseStream(getClass().getSimpleName()+" UpdateMyUI\n Parent size ["+width+","+height+"]" + // "\tLocation on parent component ["+getLocation().getX()+","+getLocation().y+"]"); } protected void updatePosition(int x,int y) { updatePosition(x,y, getWidth(), getHeight()); } protected void updatePosition(final Rectangle rec){ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { setBounds(rec); if(isDynamicRevalidate()) revalidate(); } }); } protected void updatePosition(int x,int y,int width,int height){ updatePosition(new Rectangle(x, y, width, height)); } private void installRepaintManager() { RepaintManager rpm = RepaintManager.currentManager(this); if(!(rpm instanceof AlphaRepaintManager)){ System.err.println("Install "+AlphaRepaintManager.class.getName()); AlphaRepaintManager manager = new AlphaRepaintManager(); RepaintManager.setCurrentManager(manager); } } /** * * @param g */ @Override public void paintComponent(Graphics g){ if(isVisible() && getAlpha()>0){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g.create(); GradientPaint gp = new GradientPaint(0.0f, (float) (getHeight()>>1),new Color(1,51,90,255), (float)(getWidth()>>1), 80.0f,new Color(43,105,152,255)); //GradientPaint gp = new GradientPaint(0.0f, (float) getHeight(),Utils.colorAlpha(0,0,0,getAlpha()), // 0.0f, 0.0f,Utils.colorAlpha(90,122,166,getAlpha())); RoundBorder mainBorder = getRoundBorder(); Insets outerIns = super.getInsets(); int x = outerIns.left; int y = outerIns.top; int w = getWidth()-outerIns.left-outerIns.right; int h = getHeight()-outerIns.top-outerIns.bottom; RoundRectangle2D outerBorderShape = OvalBorder.createOuterShape(x,y,w,h, mainBorder.getRecW(), mainBorder.getRecH(),outerIns); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(gp); g2.fillRoundRect(x+1, y+1, w-1, h-1,(int)mainBorder.getRecW(),(int)mainBorder.getRecH()); BorderEfects.paintBorderGlow(g2,4,outerBorderShape,colorBorderGlow); g2.dispose(); } } /** * * @return */ @Override public Insets getInsets() { Insets in = super.getInsets(); Insets inner = getInnerGap(); return new Insets(in.top+inner.top, in.left+inner.left, in.bottom+inner.bottom, in.right+inner.right); } /** * @return the decoratePanel */ public boolean isDecoratedWindow() { return decoratedWindow; } /** * @param decorated */ public void setDecorateWindow(boolean decorated) { if(decorated){ if(!this.isAncestorOf(this.decorate)){ add(this.decorate,BorderLayout.NORTH); } }else{ this.remove(this.decorate); } this.decoratedWindow = decorated; revalidate(); } /** * @return the dynamicRevalidate */ public boolean isDynamicRevalidate() { return dynamicRevalidate; } /** * * @param alphaBorder * @return */ public boolean setAlphaBorder(float alphaBorder){ RoundBorder border = getRoundBorder(); return border.setAlpha(alphaBorder); } /** * * @param alpha */ public void setAlphaToAllRootWindow(final float alpha){ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { setAlphaBorder(alpha); setAlpha(alpha); getRoundWindowRootPane().setAlpha(alpha); getContentPane().setAlpha(alpha); getDecoratePanel().setAlpha(alpha); repaint(0,0,getWidth(),getHeight()); } }); } /** * @param dynamicRevalidate the dynamicRevalidate to set */ public void setDynamicRevalidate(boolean dynamicRevalidate) { this.dynamicRevalidate = dynamicRevalidate; } /** * @return the decorate */ public AbstractDecoratePanel getDecoratePanel() { return decorate; } /** * @param decorate the decorate to set */ public void setDecoratePanel(AbstractDecoratePanel decorate) { this.decorate = decorate; } /** * @return the innerGap */ public Insets getInnerGap() { return innerGap; } /** * @param innerGap the innerGap to set */ public void setInnerGap(Insets innerGap) { this.innerGap = innerGap; } @Override public void focusGained(FocusEvent e) { System.out.println("Focus gained"); } @Override public void focusLost(FocusEvent e) { System.out.println("Focus lost"); } /** * @return the decorateAndContentGap */ public int getDecorateAndContentGap() { return decorateAndContentGap; } /** * @param decorateAndContentGap the decorateAndContentGap to set */ public void setDecorateAndContentGap(int decorateAndContentGap) { LayoutManager lm = getLayout(); if(lm instanceof BorderLayout){ ((BorderLayout)lm).setVgap(decorateAndContentGap); } this.decorateAndContentGap = decorateAndContentGap; lm.layoutContainer(this); if(isVisible()) getRoundWindowRootPane().revalidate(); } /** * * @param obj * @return */ @Override public boolean equals(Object obj) { boolean retVal = false; if(!(obj instanceof RoundWindow)) return retVal; RoundWindow tmp = (RoundWindow)obj; retVal = getDecoratePanel().getTitle().equals(tmp.getDecoratePanel().getTitle()); return retVal; } @Override public int hashCode() { int hash = 7; hash = 89 * hash + (this.rootPane != null ? this.rootPane.hashCode() : 0); hash = 89 * hash + (this.innerGap != null ? this.innerGap.hashCode() : 0); hash = 89 * hash + this.decorateAndContentGap; return hash; } /** * @return the animationDuration */ public int getAnimationDuration() { return animationDuration; } /** * @param animationDuration the animationDuration to set */ public void setAnimationDuration(int animationDuration) { this.animationDuration = animationDuration; animator.setDuration(getAnimationDuration()); } /** * @param location the location to set */ public void setLocationManager(LocationManager location) { if(this.location != null){ removeMouseListener(this.location); removeMouseMotionListener(this.location); } this.location = location; addMouseListener(location); addMouseMotionListener(location); } /** * @return the winBehavior */ public WindowDisplayBehavior getWinBehavior() { return winBehavior; } /** * @param winBehavior the winBehavior to set */ public void setWinBehavior(WindowDisplayBehavior winBehavior) { this.winBehavior = winBehavior; } public class WindowDisplayBehavior implements TimingTarget{ private Vector <ActionListener> startAction = new Vector<ActionListener>(); private Vector <ActionListener> endAction = new Vector<ActionListener>(); public void addStartAction(ActionListener al){ if(!startAction.contains(al)){ startAction.add(al); } } public void removeStartAction(ActionListener al){ startAction.remove(al); } public void addEndAction(ActionListener al){ if(!endAction.contains(al)){ endAction.add(al); } } public void removeEndAction(ActionListener al){ endAction.remove(al); } @Override public void timingEvent(float arg0) { //System.out.println(""+arg0); /* if(arg0>0 && arg0<Math.max(getContentPane().getUpperThresholdAlpha(), getUpperThresholdAlpha())){ Color outerColor = ((OvalBorder)getRoundBorder()).getBorderColor(); if(arg0<getRoundBorder().getUpperThresholdAlpha()){ ((OvalBorder)getRoundBorder()).setBorderColor(Utils.colorAlpha(outerColor, arg0)); } setAlphaToAllRootWindow(arg0); getContentPane().setAlpha(arg0); getDecoratePanel().setAlpha(arg0); repaint(0,0,getWidth(),getHeight()); }else{} //animator.stop(); */ } @Override public void begin() { if(isEnabled()) setVisible(isEnabled()); System.out.println("******** RW 'start' alpha: "+getAlpha()); final ActionEvent ae = new ActionEvent(this, currentAction, "start"); new Thread(new Runnable() { @Override public void run() { for (ActionListener al : startAction) { al.actionPerformed(ae); } } }).start(); } @Override public void end() { if(!isEnabled()){ setVisible(isEnabled()); } System.out.println("******** RW 'end' alpha: "+getAlpha()); final ActionEvent ae = new ActionEvent(this, currentAction, "end"); new Thread(new Runnable() { @Override public void run() { for (ActionListener al : endAction) { al.actionPerformed(ae); } } }).start(); } @Override public void repeat() { } } /* class CloseAction implements ActionListener,TimingTarget{ private Animator animator; public CloseAction(){ animator = new Animator(animationDuration, 1, RepeatBehavior.LOOP, this); } @Override public void actionPerformed(ActionEvent e) { animator.setStartFraction(getContentPane().getAlpha()); animator.setStartDirection(Direction.BACKWARD); animator.start(); } @Override public void timingEvent(float arg0) { if(getContentPane().setAlpha(arg0)){ setSize(getWidth()-1, getHeight()); updateMyUI(); //repaint(); }else{ end(); } } @Override public void begin() {} @Override public void end() {} @Override public void repeat() {} } */ }