/* * Copyright (C) 2014 Shashank Tulsyan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package neembuu.release1.ui; import neembuu.release1.ui.mc.MainComponentImpl; import neembuu.release1.ui.linkcontainer.LinksContainer; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicLong; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.Timer; import neembuu.release1.api.IndefiniteTask; import neembuu.release1.api.open.OpenerAccess; import neembuu.release1.api.settings.Settings; import neembuu.release1.api.ui.AddLinkUI; import neembuu.release1.api.ui.HeightProperty; import neembuu.release1.api.ui.IndefiniteTaskUI; import neembuu.release1.api.ui.MainComponent; import neembuu.release1.api.ui.access.MainUIA; import neembuu.release1.api.ui.actions.AddLinksAction; import neembuu.release1.ui.actions.AddLinkAction; import neembuu.release1.api.ui.LinkGroupUICreator; import neembuu.release1.api.ui.systray.SysTray; import neembuu.release1.mountmanager.MountManager; import neembuu.release1.ui.actions.CloseNeembuuActionImpl; import neembuu.release1.ui.frame.JFrameDecorator; import neembuu.release1.ui.mc.LazyFrame; import neembuu.util.Throwables; /** * * @author Shashank Tulsyan */ public final class NeembuuUI { private volatile JFrame jf;// = new JFrame(); private final MainPanel mp; private final LinksContainer lc; private final AddLinkAction ala; private final Settings settings; private final SysTray sysTray; private final boolean lazyUI; private MountManager mm; private OpenerAccess openerA; private final LinkedList<IndefiniteTask> indefiniteTasks = new LinkedList<IndefiniteTask>(); private final MainComponent mainComponent; private final IndefiniteTaskUI indefiniteTaskUI = new IndefiniteTaskUI() { @Override public IndefiniteTask showIndefiniteProgress(String message) { return NeembuuUI.this.showIndefiniteProgress(message); }}; private final MainUIA mainUIA = new MainUIA() { @Override public JButton neembuuVirtualFolderButton() { return mp.neembuuVirtualFolderButton; }}; public NeembuuUI(Settings settings,SysTray sysTray,boolean lazyUI) { this.settings = settings; this.sysTray = sysTray;this.lazyUI = lazyUI; mainComponent = new MainComponentImpl(new LazyFrame() { @Override public JFrame getJFrame() { if(jf==null)return new JFrame(); return jf; } @Override public boolean available() { return true; } }); this.mp = new MainPanel(addLinksAction,mainComponent,listener,indefiniteTaskUI); this.lc = new LinksContainer(mp,mp.linksPanel); lc.heightProperty().addListener(listener); ala = new AddLinkAction(getIndefiniteTaskUI(),getLinksContainer(), getMainComponent(),mp.getAddLinkUI(),settings); mp.neembuuVirtualFolderButton.setEnabled(false); } public AddLinkUI getAddLinkUI(){ return mp.getAddLinkUI(); } public LinkGroupUICreator getLinkGroupUICreator() { return ala; } public void initialize(MountManager mm){ this.jf = makeJFrame(); this.mm = mm; initJFrame(); ala.initialize(mm.getRealFileProvider(),mm.getMinimalistFileSystem()); JFrameDecorator fd = new JFrameDecorator(new MainComponentImpl(jf),sysTray,settings); fd.getFrameDecoration().getCustomJFrame().contentArea_add(mp); //fd.getContentPane().add(mp); if(!lazyUI) jf.setVisible(true); } public void initOpenerA(OpenerAccess openerA){ this.openerA = openerA; } public LinksContainer getLinksContainer() { return lc; } public MainUIA getMainUIA() { return mainUIA; } public MainComponent getMainComponent(){ return mainComponent; } public IndefiniteTaskUI getIndefiniteTaskUI() { return indefiniteTaskUI; } public IndefiniteTaskUI getIndefiniteTaskUI_withTrayNotification(){ return new IndefiniteTaskUI() { @Override public IndefiniteTask showIndefiniteProgress(String message) { IndefiniteTask it = indefiniteTaskUI.showIndefiniteProgress(message); sysTray.newMessage().setMessage(message).show(); return it; } }; } private IndefiniteTask showIndefiniteProgress(String message){ final IndefTask it = new IndefTask(message); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { indefiniteTasks.add(it); updateIndefTasks(); } }); return it; } private void updateIndefTasks(){ if(indefiniteTasks.isEmpty()){ mp.showIndefiniteProgress(false, null); return; } String message = ""; for (IndefiniteTask indefiniteTask : indefiniteTasks) { message+=indefiniteTask.displayMessage()+"\n"; } mp.showIndefiniteProgress(true, message); } void addLinks(boolean open) { mp.getAddLinkUI().addLinksPanelEnable(false);// no chance of race condition ala.open(open); Throwables.start(ala,"Add links thread"); } private void initJFrame(){ jf.setTitle("NEEMBUU"); jf.setFont(Fonts.FuturaLight); jf.setIconImage(new ImageIcon(NeembuuUI.class.getResource("/neembuu/release1/ui/images/7_ls_small_transparent_32x32.png") ).getImage()); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setMinimumSize(new Dimension(463+30,172+15)); jf.setMaximumSize(new Dimension(463+200,700)); //jf.getContentPane().add(mp); jf.addWindowListener(new WindowAdapter(){ @Override public void windowClosing(WindowEvent e) { new CloseNeembuuActionImpl(mm, openerA).actionPerformed(); }}); } private JFrame makeJFrame(){ return new JFrame(){ @Override public final void paint(Graphics g) { Dimension d = getSize(); Dimension m = getMaximumSize(); boolean resize = d.width > m.width || d.height > m.height; d.width = Math.min(m.width, d.width); d.height = Math.min(m.height, d.height); if (resize) { Point p = getLocation(); setVisible(false); setSize(d); setLocation(p); setVisible(true); } super.paint(g); } }; } private final class IndefTask implements IndefiniteTask{ private final String message; private final long submittedOn = System.currentTimeMillis(); private AtomicLong finishedOn = new AtomicLong(-1); public IndefTask(String message) { this.message = message; } @Override public String displayMessage() { return message; } @Override public long submittedOn() { return submittedOn; } @Override public long completedOn() { if(!hasCompleted()){ throw new IllegalStateException("Task not completed"); } return finishedOn.get(); } @Override public void done(boolean suppress,int delay) throws IllegalStateException { if(!finishedOn.compareAndSet(-1, System.currentTimeMillis())){ if(!suppress){ throw new IllegalStateException("Task already completed on "+finishedOn.get()); }//else return; } final Runnable t = new Runnable() { @Override public void run() { indefiniteTasks.remove(IndefTask.this); updateIndefTasks(); }}; if(delay<=0){ SwingUtilities.invokeLater(t); }else { Timer timer = new Timer(delay, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { t.run(); ((Timer)e.getSource()).stop(); } });timer.start(); } } @Override public boolean hasCompleted() { return finishedOn.get() > 0; } @Override public void done() throws IllegalStateException{ done(false,-1); } } private final HeightProperty.Listener listener = new HeightProperty.Listener() { @Override public void changed(HeightProperty h, int oldValue, int newValue) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { adjustHeightOfMainWindow(0); }}); } }; private final AddLinksAction addLinksAction = new AddLinksAction() { @Override public void addLinks(boolean open) { NeembuuUI.this.addLinks(open); }}; private void adjustHeightOfMainWindow(double f){ int ht = jf.getMinimumSize().height; //ht+=20;//for unaccounted things if(mp.addLinksPanel.isVisible()){ ht+=mp.addLinksPanel.getPreferredSize().height; } int linkContainerHeight = lc.heightProperty().getValue(); if(linkContainerHeight == 0){ // isEmpty jf.setSize(jf.getMinimumSize().width,ht); } else { ht += linkContainerHeight; ht = Math.min(ht,jf.getMaximumSize().height); if(ht < jf.getSize().height){ return; } int w = jf.getSize().width; jf.setSize(w,ht); } } }