View Javadoc
1   package org.argeo.swt.desktop;
2   
3   import java.util.Observable;
4   import java.util.function.BiFunction;
5   
6   import org.eclipse.swt.SWT;
7   import org.eclipse.swt.browser.Browser;
8   import org.eclipse.swt.browser.LocationAdapter;
9   import org.eclipse.swt.browser.LocationEvent;
10  import org.eclipse.swt.events.SelectionAdapter;
11  import org.eclipse.swt.events.SelectionEvent;
12  import org.eclipse.swt.graphics.Point;
13  import org.eclipse.swt.layout.FillLayout;
14  import org.eclipse.swt.layout.GridData;
15  import org.eclipse.swt.layout.GridLayout;
16  import org.eclipse.swt.widgets.Composite;
17  import org.eclipse.swt.widgets.Control;
18  import org.eclipse.swt.widgets.Display;
19  import org.eclipse.swt.widgets.Shell;
20  import org.eclipse.swt.widgets.Text;
21  
22  /** A minimalistic web browser based on {@link Browser}. */
23  public class MiniBrowser implements BiFunction<Composite, MiniBrowser.Context, Control> {
24  	@Override
25  	public Control apply(Composite parent, MiniBrowser.Context context) {
26  		parent.setLayout(new GridLayout());
27  		Control toolBar = createToolBar(parent, context);
28  		toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
29  		Control body = createBody(parent, context);
30  		body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
31  		return body;
32  	}
33  
34  	public Control createToolBar(Composite parent, MiniBrowser.Context context) {
35  		Composite toolBar = new Composite(parent, SWT.NONE);
36  		toolBar.setLayout(new FillLayout());
37  		Text addressT = new Text(toolBar, SWT.SINGLE | SWT.BORDER);
38  		addressT.addSelectionListener(new SelectionAdapter() {
39  
40  			@Override
41  			public void widgetDefaultSelected(SelectionEvent e) {
42  				String url = addressT.getText().trim();
43  				context.setUrl(url);
44  			}
45  		});
46  		context.addObserver((o, v) -> addressT.setText(((Context) o).getUrl().toString()));
47  		return toolBar;
48  	}
49  
50  	public Control createBody(Composite parent, MiniBrowser.Context context) {
51  		Browser browser = new Browser(parent, SWT.NONE);
52  		browser.addLocationListener(new LocationAdapter() {
53  			@Override
54  			public void changing(LocationEvent event) {
55  //				if (event.top && !context.getUrl().equals(event.location))
56  //					context.setUrl(event.location);
57  			}
58  
59  			@Override
60  			public void changed(LocationEvent event) {
61  				if (event.top && !context.getUrl().equals(event.location))
62  					context.setUrl(event.location);
63  			}
64  
65  		});
66  		browser.addTitleListener(e -> context.setTitle(e.title));
67  		context.addObserver((o, v) -> {
68  			String url = ((Context) o).getUrl();
69  			if (url != null && !url.equals(browser.getUrl()))
70  				browser.setUrl(url.toString());
71  		});
72  		return browser;
73  	}
74  
75  	/** The observable context of this web browser. */
76  	public static class Context extends Observable {
77  		private String url;
78  		private String title = "";
79  
80  		public void setUrl(String url) {
81  			this.url = url;
82  			System.out.println(url);
83  			setChanged();
84  			notifyObservers(url);
85  		}
86  
87  		public String getUrl() {
88  			return url;
89  		}
90  
91  		public String getTitle() {
92  			return title;
93  		}
94  
95  		public void setTitle(String title) {
96  			this.title = title;
97  			setChanged();
98  			notifyObservers(title);
99  		}
100 
101 	}
102 
103 	public static void main(String[] args) {
104 		Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent();
105 		Shell shell = new Shell(display, SWT.SHELL_TRIM);
106 
107 		MiniBrowser miniBrowser = new MiniBrowser();
108 		MiniBrowser.Context context = new MiniBrowser.Context();
109 		miniBrowser.apply(shell, context);
110 		context.addObserver((o, v) -> shell.setText(((Context) o).getTitle()));
111 		String url = args.length > 0 ? args[0] : "http://www.argeo.org";
112 		context.setUrl(url);
113 
114 		shell.open();
115 		shell.setSize(new Point(800, 480));
116 		while (!shell.isDisposed()) {
117 			if (!display.readAndDispatch())
118 				display.sleep();
119 		}
120 	}
121 
122 }