summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
blob: 11b02f58157243aa0c8c0230493b73dc837aeaa7 (plain) (tree)
1
2
3
4
5
6
7
8
9
                               
 
                             


                                     

                                     
                               

                                    
                    

                           

                                              
                                     
 
                       

                             
                          


                             
                          
                              
                                  
 
                               

                                                     
                                                   
                              
                                   
                                 
                                                    
                                                       


                                                             
                                              
                                                     
                                                     
                                                          
                                                   
                                                   
                                             
                                                   
                                                 
                                                 
                                                 
                                                
                                                       
                                                  
                                                      
                                                     
                                                       

                                                    
                                                         
                                                             
                                                  
                                                  
                                         
                                               
                                             
                                            

                                                       
                                              

                                        




                                                                                
                                               

                                                  
 

                                                 

                                                          
                                                                                                                  
 

                                                                                
           
                                                   
           
                       
           
                                                                            



                                                                                                          

                                                         
                                                                                
                         

                                                      
                                   

                                                    
                                          
                                             
                                      









                                                                           

         
                                                      
                                                            

         
                
                                                                     

                                             
                                                                                 

                         











                                                                        

         
           
                                                                               


                                                                        
           

                                   
                                 
                                                                                

                                             
                                                                  

                                                                  
                                                                

                         
 
                                                         
                                                                                                                                              
                                                                                                                  
 


                                                                    



                                                                   

                                                                                                                              

                                         


                         
                                      


                                                                                                                      



                                                                                                   

                                                                          
                                                                
                                         





                                                                                                                     
                                                                        
                                                 
                                         
                                 
                                                          

                         
 
                                                                                               
                                                                                           
 
                                              
                                                                             
 
                                                        
                                                   
                                                    
                                                      
                                               
 


                                                            
                                                                           
                                                                   
                                                                                      
                 
                                                                    
                                                                                           

                                                    
                                                                                      
 
                                                           
                                                                                    
                                                       
                                            
 
                                                       
                                                     









                                                                                                                       
                                                                                                                                   












                                                                                                          
                 
         
 
                                                
 



                                                  
 



                                                                                                     


                                                                                
                                                                                     
                 

                                               
                             
                                                                                                                                       



                                                                       


                                                             


           



                                                                                






                                                           
                            






                                                                                             

                         
                         
                                                                                                                
                                                                                          

                                    
                                           


           








                                                                                                                     
                                          


                                         
                                                           





                                               

                                                               












                                                                                              

         

                                                                                                       














                                                                                              



                                                                                                





                                                                

         
                                          
                                       
                                                  
                                                
 



                                                                      

                                                                               





                                                                             



                                                                 
                                                                            
                                                





                                                                      
                                                                          
                                                  
 
                                        
                                                            

                                              
                                                                                 
                                                                                     
                                                                                  
                                                                                    
                                                                                     
                                                     
                                                        
                                                            
                                                
                                               
                                                      

                                                        
                                                     

                                      





















                                                                             





                                                                    


                                                                    
                                                                                         

                         







                                                                      
                                                                 
                                 
                                                                    
                                                     

                         
 
                                  
                                                                       
                                 
                                                                    
                                                                  


                         






                                                                          
                                                                              
                                 
                                                                    
                                                                         

                         
 


                                                                    
                                                                         


                         






                                                                        


                                                            

                                                    
                                                         
                                                                






                                                                                
                                                                                                   

                                                                                         
                                                                                                  
                                 
                                           





















                                                                                                                                                                                     
                                                                                                                                                     

                                                                                                                                           
                                                         
                                                 









                                                                                                                                            

                                         
                                                                            







                                                                            
         
 




                                                                                


                                                                                          












                                                                                
 
 
package org.openslx.dozmod.gui;

import java.awt.BorderLayout;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;

import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.SatelliteStatus;
import org.openslx.bwlp.thrift.iface.TransferState;
import org.openslx.dozmod.App;
import org.openslx.dozmod.Branding;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.filetransfer.DownloadTask;
import org.openslx.dozmod.filetransfer.PassiveTransfer;
import org.openslx.dozmod.filetransfer.TransferEvent;
import org.openslx.dozmod.filetransfer.TransferEventListener;
import org.openslx.dozmod.filetransfer.UploadTask;
import org.openslx.dozmod.gui.Gui.GuiCallable;
import org.openslx.dozmod.gui.activity.ActivityPanel;
import org.openslx.dozmod.gui.activity.DownloadPanel;
import org.openslx.dozmod.gui.activity.PassiveUploadPanel;
import org.openslx.dozmod.gui.activity.UpdatePanel;
import org.openslx.dozmod.gui.activity.UploadPanel;
import org.openslx.dozmod.gui.control.QLabel;
import org.openslx.dozmod.gui.helper.CompositePage;
import org.openslx.dozmod.gui.helper.DebugWindow;
import org.openslx.dozmod.gui.helper.GridManager;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.UiFeedback;
import org.openslx.dozmod.gui.window.CheckUpdateWindow;
import org.openslx.dozmod.gui.window.ConfigWindow;
import org.openslx.dozmod.gui.window.DisclaimerWindow;
import org.openslx.dozmod.gui.window.ImageListWindow;
import org.openslx.dozmod.gui.window.LectureListWindow;
import org.openslx.dozmod.gui.window.LoginWindow;
import org.openslx.dozmod.gui.window.MainMenuWindow;
import org.openslx.dozmod.gui.window.PrivacyNoticeWindow;
import org.openslx.dozmod.gui.window.VirtualizerNoticeWindow;
import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.GuiErrorCallback;
import org.openslx.dozmod.thrift.Session;
import org.openslx.dozmod.thrift.ThriftActions;
import org.openslx.dozmod.util.ClientVersion;
import org.openslx.dozmod.util.FormatHelper;
import org.openslx.dozmod.util.DesktopEnvironment;
import org.openslx.dozmod.util.DesktopEnvironment.Link;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;

public abstract class MainWindow {

	private final static Logger LOGGER = Logger.getLogger(MainWindow.class);

	private static final JFrame mainWindow;
	private static final JPanel mainContainer;
	private static final JPanel activityPanel;

	private static CompositePage currentPage;

	private static boolean isQuitQuestionOpen = false;

	private static final Map<Class<? extends CompositePage>, CompositePage> pages = new ConcurrentHashMap<>();

	private static final List<ActivityPanel> activities = new ArrayList<>();

	/**
	 * Set the visible page of the main window.
	 * 
	 * @param clazz
	 */
	public static <T extends CompositePage> T showPage(Class<T> clazz) {
		T page = getPage(clazz);
		if (page == null) {
			throw new RuntimeException("Tried to show unknown page " + clazz.getSimpleName());
		}
		if (currentPage != null) {
			if (!currentPage.requestHide()) {
				return null; // Canceled by currently shown page
			}
			currentPage.setVisible(false);
		}
		currentPage = page;

		// sets the starting preferred size.
		currentPage.requestShow();
		currentPage.setVisible(true);
		mainWindow.validate();
		return page;
	}

	@SuppressWarnings("unchecked")
	public static <T extends CompositePage> T getPage(Class<T> clazz) {
		CompositePage page = pages.get(clazz);
		if (page == null) {
			return null;
		}
		return (T) page;
	}

	public static void centerShell(Window shell) {
		Gui.centerShellOverShell(mainWindow, shell);
	}

	static {
		mainWindow = Gui.syncExec(new GuiCallable<JFrame>() {
			@Override
			public JFrame run() {
				return new JFrame(Branding.getApplicationName());
			}
		});
		mainContainer = Gui.syncExec(new GuiCallable<JPanel>() {
			@Override
			public JPanel run() {
				return new JPanel();
			}
		});
		activityPanel = Gui.syncExec(new GuiCallable<JPanel>() {
			@Override
			public JPanel run() {
				return new JPanel();
			}
		});
	}

	/**
	 * Initializes the GUI by creating the main window, adding the menu and
	 * creating the login mask as the first content window.
	 * Further sets up the global thrift error callback to catch any
	 * connection errors during the communication with the servers.
	 */

	public static void open() {
		// init SWT stuff
		mainWindow.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		// Catch the close button (X)
		mainWindow.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				MainWindow.askApplicationQuit();
			}
		});

		// Set up thrift error message displaying
		ThriftManager.setMasterErrorCallback(new GuiErrorCallback(mainWindow, "dem " + Branding.getServiceName() + "-Zentralserver"));
		ThriftManager.setSatelliteErrorCallback(new GuiErrorCallback(mainWindow, "dem Satellitenserver"));

		// Same for config errors
		Config.setErrorCallback(new Config.ErrorCallback() {
			@Override
			public void writeError(final Throwable t) {
				Gui.asyncExec(new Runnable() {
					@Override
					public void run() {
						Gui.showMessageBox(mainWindow, "Konnte Programmeinstellungen nicht speichern",
								MessageType.WARNING, LOGGER, t);
					}
				});
			}
		});

		// Global key listener
		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
			@Override
			public boolean dispatchKeyEvent(KeyEvent event) {
				int type = event.getID();
				int code = event.getKeyChar();
				if (code == 17) { // Ctrl-Q = Quit
					if (type == KeyEvent.KEY_RELEASED && !isQuitQuestionOpen) {
						isQuitQuestionOpen = true;
						askApplicationQuit();
						event.consume();
					}
				} else if (code == 27 || code == 23) { // ESC or Ctrl-W closes current window
					if (type == KeyEvent.KEY_PRESSED) {
						Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager()
								.getActiveWindow();
						if (window instanceof UiFeedback) {
							((UiFeedback) window).escapePressed();
							event.consume();
						}
					}
				}
				return event.isConsumed();
			}
		});

		// Set layout for the mainshell, items added to the shell should get a gridData
		mainContainer.setLayout(new BoxLayout(mainContainer, BoxLayout.PAGE_AXIS));

		// Scale the ui with the font.
		mainWindow.setMinimumSize(Gui.getScaledDimension(1050, 670));

		// register all pages of the main window
		registerPage(new MainMenuWindow());
		registerPage(new ImageListWindow());
		registerPage(new LectureListWindow());
		registerPage(new PleaseWait());

		// Debug?
		if (System.getProperty("log") != null) {
			DebugWindow win = new DebugWindow();
			win.setMinimumSize(Gui.getScaledDimension(0, 250));
			win.setPreferredSize(win.getMinimumSize());
			mainWindow.getContentPane().add(win, BorderLayout.PAGE_START);
		}
		// Activity panel at the bottom (file transfer, ...)
		activityPanel.setLayout(new BoxLayout(activityPanel, BoxLayout.PAGE_AXIS));
		activityPanel.setVisible(false);
		activityPanel.add(new JSeparator());
		mainWindow.getContentPane().add(activityPanel, BorderLayout.PAGE_END);

		// center the window on the primary monitor
		mainWindow.getContentPane().add(mainContainer, BorderLayout.CENTER);
		mainWindow.setLocationRelativeTo(null);
		mainWindow.setVisible(true);

		if (Config.getSavedSession() == null) {
			LoginWindow.open(mainWindow);
			initWindow();
		} else {
			if (!App.isInitDone()) {
				showPage(PleaseWait.class);
			}
			QuickTimer.scheduleOnce(new Task() {
				@Override
				public void fire() {
					App.waitForInit();
					// now try to init the session with the saved configuration (by giving it null)
					if (ThriftActions.initSession(null, false, SwingUtilities.getWindowAncestor(mainWindow))) {
						initWindow();
					} else {
						// session resume failed, so do the normal login procedure
						Gui.asyncExec(new Runnable() {
							@Override
							public void run() {
								LoginWindow.open(mainWindow);
								initWindow();
							}
						});
					}
				}
			});
		}
	}

	private static boolean initOnce = false;

	private static void initWindow() {
		if (initOnce || !App.isInitDone())
			return;
		initOnce = true;

		// Sanity check: This should only happen once the user is logged in, if we don't have
		// a session, just bail out completely
		if (Session.getSatelliteToken() == null)
			System.exit(42);
		// at this point we are sure to be logged in with a proper token
		// thus we directly check for new version
		if (!ClientVersion.isNewest()) {
			addPanel(new UpdatePanel(ClientVersion.getRemoteRevision()));
		}
		// Show main menu by default
		showPage(MainMenuWindow.class);
		createMenu();
		mainWindow.setTitle(Branding.getApplicationName() + " - " + Session.getFirstName() + " " + Session.getLastName() + " ["
				+ Session.getSatelliteAddress() + "]");
		if (DisclaimerWindow.shouldBeShown()) {
			DisclaimerWindow.open(mainWindow);
		}
		if (PrivacyNoticeWindow.shouldBeShown()) {
			PrivacyNoticeWindow.open(mainWindow);
		}
	}

	/**
	 * Request application quit. Will show a message box asking the user for
	 * confirmation.
	 */
	protected static void askApplicationQuit() {
		boolean open = false;
		for (ActivityPanel activity : activities) {
			if (activity.wantConfirmQuit()) {
				open = true;
				break;
			}
		}
		if (!open) {
			Window[] windows = Window.getWindows();
			for (Window window : windows) {
				if (window.isVisible() && window instanceof UiFeedback
						&& ((UiFeedback) window).wantConfirmQuit()) {
					open = true;
					break;
				}
			}
		}
		if (!open
				|| Gui.showMessageBox(mainWindow, "Möchten Sie das Programm wirklich beenden?",
						MessageType.QUESTION_YESNO, null, null)) {
			Gui.exit(0);
		}
		isQuitQuestionOpen = false;
	}

	/**
	 * Register a page that can be displayed in the main window.
	 * 
	 * @param window
	 */
	private static synchronized void registerPage(CompositePage window) {
		Class<? extends CompositePage> clazz = window.getClass();
		if (pages.containsKey(clazz))
			throw new IllegalArgumentException("Page " + clazz.getSimpleName() + " already registered!");
		pages.put(clazz, window);
		mainContainer.add(window);
		window.setVisible(false);
	}

	private static void addPanel(ActivityPanel panel) {
		activities.add(panel);
		activityPanel.add(panel);
		activityPanel.setVisible(true);
		mainWindow.validate();
	}

	public static void addUpload(UploadWizardState state) {
		addPanel(new UploadPanel(state));
		final UploadTask task = state.upload.getUploadTask();
		task.addListener(new TransferEventListener() {
			@Override
			public void update(TransferEvent event) {
				if (event.state == TransferState.FINISHED) {
					ImageListWindow page = getPage(ImageListWindow.class);
					if (page != null) {
						page.refresh(true);
					}
					task.removeListener(this);
				}
			}
		});
	}

	public static void addPassiveTransfer(String transferToken, String name, boolean queryMaster) {
		final PassiveTransfer transfer = new PassiveTransfer(transferToken, queryMaster);
		addPanel(new PassiveUploadPanel(transfer, name));
		transfer.addListener(new TransferEventListener() {
			@Override
			public void update(TransferEvent event) {
				if (event.state == TransferState.FINISHED) {
					ImageListWindow page = getPage(ImageListWindow.class);
					if (page != null) {
						page.refresh(true);
					}
					transfer.removeListener(this);
				}
			}
		});
	}

	public static void addDownload(String imageName, String diskFile, DownloadTask dlTask) {
		addPanel(new DownloadPanel(imageName, diskFile, dlTask));
	}

	public static void removeActivity(ActivityPanel panel) {
		activities.remove(panel);
		activityPanel.remove(panel);
		if (activities.isEmpty())
			activityPanel.setVisible(false);
		mainWindow.validate();
	}

	private static void createMenu() {
		// the File menu button
		JMenuBar menuBar = new JMenuBar();
		mainWindow.setJMenuBar(menuBar);

		JMenu cascadeSessionMenu = new JMenu("Sitzung");
		menuBar.add(cascadeSessionMenu);
		JMenuItem configItem = new JMenuItem("Einstellungen");
		cascadeSessionMenu.add(configItem);
		JMenuItem logDirItem = new JMenuItem("Logverzeichnis öffnen");
		cascadeSessionMenu.add(logDirItem);
		cascadeSessionMenu.addSeparator();
		JMenuItem logoutItem = new JMenuItem("Abmelden und beenden");
		cascadeSessionMenu.add(logoutItem);
		JMenuItem exitItem = new JMenuItem("Beenden");
		cascadeSessionMenu.add(exitItem);

		JMenu cascadeViewMenu = new JMenu("Ansicht");
		menuBar.add(cascadeViewMenu);
		JMenuItem homeItem = new JMenuItem("Startseite");
		cascadeViewMenu.add(homeItem);
		JMenuItem imagesItem = new JMenuItem("Virtuelle Maschinen");
		cascadeViewMenu.add(imagesItem);

		// Prevent switching to imageList when user is student
		if (!Session.canListImages()) {
			imagesItem.setEnabled(false);
		}

		JMenuItem lecturesItem = new JMenuItem("Veranstaltungen");
		cascadeViewMenu.add(lecturesItem);

		// the About menu button
		JMenu cascadeAboutMenu = new JMenu("Über");
		menuBar.add(cascadeAboutMenu);

		JMenuItem disclaimerItem = new JMenuItem("Nutzungsvereinbarung");
		JMenuItem privacyNoticeItem = new JMenuItem("Datenschutzerklärung");
		JMenuItem virtualizerNoticeItem = new JMenuItem("Virtualisierer");
		JMenuItem wikiItem = new JMenuItem(Branding.getServiceFAQWebsite());
		JMenuItem updateCheckItem = new JMenuItem("Software-Aktualisierung");
		cascadeAboutMenu.add(disclaimerItem);
		cascadeAboutMenu.add(privacyNoticeItem);
		cascadeAboutMenu.add(virtualizerNoticeItem);
		cascadeAboutMenu.addSeparator();
		cascadeAboutMenu.add(wikiItem);
		cascadeAboutMenu.add(updateCheckItem);

		menuBar.add(Box.createHorizontalGlue());
		final QLabel memStats = new QLabel();
		menuBar.add(memStats);

		// "View" actions
		homeItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.showPage(MainMenuWindow.class);
			}
		});
		imagesItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.showPage(ImageListWindow.class);
			}
		});

		lecturesItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				MainWindow.showPage(LectureListWindow.class);
			}
		});

		// "Session" actions
		configItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ConfigWindow.open(mainWindow);
			}
		});
		logDirItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				DesktopEnvironment.openLocal(new File(Config.getPath()));
			}
		});
		logoutItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Config.saveCurrentSession("", "", "");
				askApplicationQuit();
			}
		});

		exitItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				askApplicationQuit();
			}
		});

		// "About" actions
		disclaimerItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				DisclaimerWindow.open(mainWindow);
			}
		});

		privacyNoticeItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				PrivacyNoticeWindow.open(mainWindow);
			}
		});

		virtualizerNoticeItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				VirtualizerNoticeWindow.open(mainWindow);
			}
		});

		wikiItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				DesktopEnvironment.openWebpage(Link.FAQ);
			}
		});

		updateCheckItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				CheckUpdateWindow.open(mainWindow);
			}
		});

		// Debug label

		QuickTimer.scheduleAtFixedDelay(new Task() {
			private int failures = 0;
			private int ignoreCount = 0;
			private String remoteString = "";
			private boolean timeDiffChecked = false;

			@Override
			public void fire() {
				Runtime rt = Runtime.getRuntime();
				long maxMemory = rt.maxMemory();
				long totalMemory = rt.totalMemory();
				long usedMemory = totalMemory - rt.freeMemory();
				String txt = "[JVM: " + FormatHelper.bytes(usedMemory, false) + "/"
						+ FormatHelper.bytes(totalMemory, false);
				if (maxMemory != Long.MAX_VALUE) {
					txt += ", Limit: " + FormatHelper.bytes(maxMemory, false);
				}
				txt += "]";
				if (ignoreCount > 0) {
					ignoreCount -= 1;
				} else if (Session.getUserId() != null) {
					try {
						SatelliteStatus status = ThriftManager.getSatClient().getStatus();
						failures = 0;
						remoteString = " [Store: " + FormatHelper.bytes(status.availableStorageBytes, false) + "]";
						if (!timeDiffChecked) {
							final long now = System.currentTimeMillis() / 1000;
							final long diffSecs = Math.abs(now - status.serverTime);
							LOGGER.debug("Clock diff client<->server: " + diffSecs + "s");
							timeDiffChecked = true;
							if (diffSecs > TimeUnit.MINUTES.toMillis(10)) {
								Gui.asyncMessageBox(
										"ACHTUNG: Die Uhrzeit Ihres Computers weicht von der Uhrzeit auf dem Satellitenserver ab.\n"
												+ "Bitte stellen Sie sicher, dass die Uhr Ihres Computers richtig gestellt ist.\n"
												+ "Falls Ihre Sytemzeit korrekt gesetzt ist, ist möglicherweise die Uhrzeit auf\n"
												+ "dem Satellitenserver nicht korrekt eingestellt.\n"
												+ "In diesem Fall kann es - je nach Abweichung - zu unerwarteten Problemen mit den\n"
												+ "Start- und Endzeiten von Veranstaltungen kommen. Kontaktieren Sie in diesem\n"
												+ "Fall den zuständigen Administrator, damit die Uhrzeit auf dem Satellitenserver\n"
												+ "korrigiert werden kann.\n\n" + "Ihr Computer: "
												+ FormatHelper.longDate(now) + "\nSatellitenserver: "
												+ FormatHelper.longDate(status.serverTime),
										MessageType.WARNING, LOGGER, null);
							}
						}
						// If user is not active and no upload is running, only update the value once a minute
						// TODO: Count active uploads
						long inactiveMins = (System.currentTimeMillis() - Gui.getLastUserActivityMillis()) / 60000l;
						if (inactiveMins > 10 && UploadTask.getNumberOfUploads() == 0) {
							ignoreCount = 30;
						}
					} catch (TException e) {
						failures += 1;
						ignoreCount = Math.min(10, failures / 3);
						remoteString = " [Store: ???]";
					}
				}
				final String labelText = txt + remoteString;
				Gui.asyncExec(new Runnable() {
					@Override
					public void run() {
						memStats.setText(labelText);
					}
				});
			}
		}, 10, 2001);
	}

	@SuppressWarnings("serial")
	private static class PleaseWait extends CompositePage {
		public PleaseWait() {
			GridManager grid = new GridManager(this, 3);
			grid.add(Box.createHorizontalGlue()).expand(true, true);
			grid.add(new JLabel("Bitte warten, suche Proxy-Konfiguration..."))
					.expand(false, true)
					.fill(true, true);
			grid.add(Box.createHorizontalGlue()).expand(true, true);
			grid.finish(false);
		}

		@Override
		public boolean requestHide() {
			return true;
		}

		@Override
		public void requestShow() {
		}
	}

}