int-test mqtt <-> prediction
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2018 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed;
|
||||
|
||||
import org.cef.CefApp;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.handler.CefLifeSpanHandlerAdapter;
|
||||
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class BrowserFrame extends JFrame {
|
||||
private volatile boolean isClosed_ = false;
|
||||
private CefBrowser browser_ = null;
|
||||
private static int browserCount_ = 0;
|
||||
private Runnable afterParentChangedAction_ = null;
|
||||
|
||||
public BrowserFrame() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public BrowserFrame(String title) {
|
||||
super(title);
|
||||
|
||||
// Browser window closing works as follows:
|
||||
// 1. Clicking the window X button calls WindowAdapter.windowClosing.
|
||||
// 2. WindowAdapter.windowClosing calls CefBrowser.close(false).
|
||||
// 3. CEF calls CefLifeSpanHandler.doClose() which calls CefBrowser.doClose()
|
||||
// which returns true (canceling the close).
|
||||
// 4. CefBrowser.doClose() triggers another call to WindowAdapter.windowClosing.
|
||||
// 5. WindowAdapter.windowClosing calls CefBrowser.close(true).
|
||||
// 6. For windowed browsers CEF destroys the native window handle. For OSR
|
||||
// browsers CEF calls CefLifeSpanHandler.doClose() which calls
|
||||
// CefBrowser.doClose() again which returns false (allowing the close).
|
||||
// 7. CEF calls CefLifeSpanHandler.onBeforeClose and the browser is destroyed.
|
||||
//
|
||||
// On macOS pressing Cmd+Q results in a call to CefApp.handleBeforeTerminate
|
||||
// which calls CefBrowser.close(true) for each existing browser. CEF then calls
|
||||
// CefLifeSpanHandler.onBeforeClose and the browser is destroyed.
|
||||
//
|
||||
// Application shutdown works as follows:
|
||||
// 1. CefLifeSpanHandler.onBeforeClose calls CefApp.getInstance().dispose()
|
||||
// when the last browser window is destroyed.
|
||||
// 2. CefAppHandler.stateHasChanged terminates the application by calling
|
||||
// System.exit(0) when the state changes to CefAppState.TERMINATED.
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (browser_ == null) {
|
||||
// If there's no browser we can dispose immediately.
|
||||
isClosed_ = true;
|
||||
System.out.println("BrowserFrame.windowClosing Frame.dispose");
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isClosed = isClosed_;
|
||||
|
||||
if (isClosed) {
|
||||
// Cause browser.doClose() to return false so that OSR browsers
|
||||
// can close.
|
||||
browser_.setCloseAllowed();
|
||||
}
|
||||
|
||||
// Results in another call to this method.
|
||||
System.out.println("BrowserFrame.windowClosing CefBrowser.close(" + isClosed + ")");
|
||||
browser_.close(isClosed);
|
||||
if (!isClosed_) {
|
||||
isClosed_ = true;
|
||||
}
|
||||
if (isClosed) {
|
||||
// Dispose after the 2nd call to this method.
|
||||
System.out.println("BrowserFrame.windowClosing Frame.dispose");
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setBrowser(CefBrowser browser) {
|
||||
if (browser_ == null) browser_ = browser;
|
||||
|
||||
browser_.getClient().removeLifeSpanHandler();
|
||||
browser_.getClient().addLifeSpanHandler(new CefLifeSpanHandlerAdapter() {
|
||||
@Override
|
||||
public void onAfterCreated(CefBrowser browser) {
|
||||
System.out.println("BrowserFrame.onAfterCreated id=" + browser.getIdentifier());
|
||||
browserCount_++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterParentChanged(CefBrowser browser) {
|
||||
System.out.println(
|
||||
"BrowserFrame.onAfterParentChanged id=" + browser.getIdentifier());
|
||||
if (afterParentChangedAction_ != null) {
|
||||
SwingUtilities.invokeLater(afterParentChangedAction_);
|
||||
afterParentChangedAction_ = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doClose(CefBrowser browser) {
|
||||
boolean result = browser.doClose();
|
||||
System.out.println("BrowserFrame.doClose id=" + browser.getIdentifier()
|
||||
+ " CefBrowser.doClose=" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeClose(CefBrowser browser) {
|
||||
System.out.println("BrowserFrame.onBeforeClose id=" + browser.getIdentifier());
|
||||
if (--browserCount_ == 0) {
|
||||
System.out.println("BrowserFrame.onBeforeClose CefApp.dispose");
|
||||
CefApp.getInstance().dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void removeBrowser(Runnable r) {
|
||||
System.out.println("BrowserFrame.removeBrowser");
|
||||
afterParentChangedAction_ = r;
|
||||
remove(browser_.getUIComponent());
|
||||
// The removeNotify() notification should be sent as a result of calling remove().
|
||||
// However, it isn't in all cases so we do it manually here.
|
||||
browser_.getUIComponent().removeNotify();
|
||||
browser_ = null;
|
||||
}
|
||||
|
||||
public CefBrowser getBrowser() {
|
||||
return browser_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed;
|
||||
|
||||
import org.cef.CefApp;
|
||||
import org.cef.CefApp.CefVersion;
|
||||
import org.cef.CefBrowserSettings;
|
||||
import org.cef.CefClient;
|
||||
import org.cef.CefSettings;
|
||||
import org.cef.CefSettings.ColorType;
|
||||
import org.cef.OS;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.browser.CefMessageRouter;
|
||||
import org.cef.browser.CefRequestContext;
|
||||
import org.cef.handler.CefDisplayHandlerAdapter;
|
||||
import org.cef.handler.CefFocusHandlerAdapter;
|
||||
import org.cef.handler.CefLoadHandlerAdapter;
|
||||
import org.cef.handler.CefRequestContextHandlerAdapter;
|
||||
import org.cef.network.CefCookieManager;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.io.File;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import tests.detailed.dialog.DownloadDialog;
|
||||
import tests.detailed.handler.AppHandler;
|
||||
import tests.detailed.handler.ContextMenuHandler;
|
||||
import tests.detailed.handler.DragHandler;
|
||||
import tests.detailed.handler.JSDialogHandler;
|
||||
import tests.detailed.handler.KeyboardHandler;
|
||||
import tests.detailed.handler.MessageRouterHandler;
|
||||
import tests.detailed.handler.MessageRouterHandlerEx;
|
||||
import tests.detailed.handler.RequestHandler;
|
||||
import tests.detailed.ui.ControlPanel;
|
||||
import tests.detailed.ui.MenuBar;
|
||||
import tests.detailed.ui.StatusPanel;
|
||||
import tests.detailed.util.DataUri;
|
||||
|
||||
public class MainFrame extends BrowserFrame {
|
||||
private static final long serialVersionUID = -2295538706810864538L;
|
||||
public static void main(String[] args) {
|
||||
// Perform startup initialization on platforms that require it.
|
||||
if (!CefApp.startup(args)) {
|
||||
System.out.println("Startup initialization failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// OSR mode is enabled by default on Linux.
|
||||
// and disabled by default on Windows and Mac OS X.
|
||||
boolean osrEnabledArg = false;
|
||||
boolean transparentPaintingEnabledArg = false;
|
||||
boolean createImmediately = false;
|
||||
int windowless_frame_rate = 0;
|
||||
for (String arg : args) {
|
||||
arg = arg.toLowerCase();
|
||||
if (arg.equals("--off-screen-rendering-enabled")) {
|
||||
osrEnabledArg = true;
|
||||
} else if (arg.equals("--transparent-painting-enabled")) {
|
||||
transparentPaintingEnabledArg = true;
|
||||
} else if (arg.equals("--create-immediately")) {
|
||||
createImmediately = true;
|
||||
} else if (arg.equals("--windowless-frame-rate-60")) {
|
||||
windowless_frame_rate = 60;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Offscreen rendering " + (osrEnabledArg ? "enabled" : "disabled"));
|
||||
|
||||
// MainFrame keeps all the knowledge to display the embedded browser
|
||||
// frame.
|
||||
final MainFrame frame = new MainFrame(osrEnabledArg, transparentPaintingEnabledArg,
|
||||
createImmediately, windowless_frame_rate, args);
|
||||
frame.setSize(800, 600);
|
||||
frame.setVisible(true);
|
||||
|
||||
if (osrEnabledArg && windowless_frame_rate != 0) {
|
||||
frame.getBrowser().getWindowlessFrameRate().thenAccept(
|
||||
framerate -> System.out.println("Framerate is:" + framerate));
|
||||
|
||||
frame.getBrowser().setWindowlessFrameRate(2);
|
||||
frame.getBrowser().getWindowlessFrameRate().thenAccept(
|
||||
framerate -> System.out.println("Framerate is:" + framerate));
|
||||
|
||||
frame.getBrowser().setWindowlessFrameRate(windowless_frame_rate);
|
||||
}
|
||||
}
|
||||
|
||||
private final CefClient client_;
|
||||
private String errorMsg_ = "";
|
||||
private ControlPanel control_pane_;
|
||||
private StatusPanel status_panel_;
|
||||
private boolean browserFocus_ = true;
|
||||
private boolean osr_enabled_;
|
||||
private boolean transparent_painting_enabled_;
|
||||
private JPanel contentPanel_;
|
||||
private JFrame fullscreenFrame_;
|
||||
|
||||
public MainFrame(boolean osrEnabled, boolean transparentPaintingEnabled,
|
||||
boolean createImmediately, int windowless_frame_rate, String[] args) {
|
||||
this.osr_enabled_ = osrEnabled;
|
||||
this.transparent_painting_enabled_ = transparentPaintingEnabled;
|
||||
|
||||
CefApp myApp;
|
||||
if (CefApp.getState() != CefApp.CefAppState.INITIALIZED) {
|
||||
// 1) CefApp is the entry point for JCEF. You can pass
|
||||
// application arguments to it, if you want to handle any
|
||||
// chromium or CEF related switches/attributes in
|
||||
// the native world.
|
||||
CefSettings settings = new CefSettings();
|
||||
settings.windowless_rendering_enabled = osrEnabled;
|
||||
// try to load URL "about:blank" to see the background color
|
||||
settings.background_color = settings.new ColorType(100, 255, 242, 211);
|
||||
myApp = CefApp.getInstance(args, settings);
|
||||
|
||||
CefVersion version = myApp.getVersion();
|
||||
System.out.println("Using:\n" + version);
|
||||
|
||||
// We're registering our own AppHandler because we want to
|
||||
// add an own schemes (search:// and client://) and its corresponding
|
||||
// protocol handlers. So if you enter "search:something on the web", your
|
||||
// search request "something on the web" is forwarded to www.google.com
|
||||
CefApp.addAppHandler(new AppHandler(args));
|
||||
} else {
|
||||
myApp = CefApp.getInstance();
|
||||
}
|
||||
|
||||
// By calling the method createClient() the native part
|
||||
// of JCEF/CEF will be initialized and an instance of
|
||||
// CefClient will be created. You can create one to many
|
||||
// instances of CefClient.
|
||||
client_ = myApp.createClient();
|
||||
|
||||
// 2) You have the ability to pass different handlers to your
|
||||
// instance of CefClient. Each handler is responsible to
|
||||
// deal with different informations (e.g. keyboard input).
|
||||
//
|
||||
// For each handler (with more than one method) adapter
|
||||
// classes exists. So you don't need to override methods
|
||||
// you're not interested in.
|
||||
DownloadDialog downloadDialog = new DownloadDialog(this);
|
||||
client_.addContextMenuHandler(new ContextMenuHandler(this));
|
||||
client_.addDownloadHandler(downloadDialog);
|
||||
client_.addDragHandler(new DragHandler());
|
||||
client_.addJSDialogHandler(new JSDialogHandler());
|
||||
client_.addKeyboardHandler(new KeyboardHandler());
|
||||
client_.addRequestHandler(new RequestHandler(this));
|
||||
|
||||
// Beside the normal handler instances, we're registering a MessageRouter
|
||||
// as well. That gives us the opportunity to reply to JavaScript method
|
||||
// calls (JavaScript binding). We're using the default configuration, so
|
||||
// that the JavaScript binding methods "cefQuery" and "cefQueryCancel"
|
||||
// are used.
|
||||
CefMessageRouter msgRouter = CefMessageRouter.create();
|
||||
msgRouter.addHandler(new MessageRouterHandler(), true);
|
||||
msgRouter.addHandler(new MessageRouterHandlerEx(client_), false);
|
||||
client_.addMessageRouter(msgRouter);
|
||||
|
||||
// 2.1) We're overriding CefDisplayHandler as nested anonymous class
|
||||
// to update our address-field, the title of the panel as well
|
||||
// as for updating the status-bar on the bottom of the browser
|
||||
client_.addDisplayHandler(new CefDisplayHandlerAdapter() {
|
||||
@Override
|
||||
public void onAddressChange(CefBrowser browser, CefFrame frame, String url) {
|
||||
control_pane_.setAddress(browser, url);
|
||||
}
|
||||
@Override
|
||||
public void onTitleChange(CefBrowser browser, String title) {
|
||||
setTitle(title);
|
||||
}
|
||||
@Override
|
||||
public void onStatusMessage(CefBrowser browser, String value) {
|
||||
status_panel_.setStatusText(value);
|
||||
}
|
||||
@Override
|
||||
public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen) {
|
||||
setBrowserFullscreen(fullscreen);
|
||||
}
|
||||
});
|
||||
|
||||
// 2.2) To disable/enable navigation buttons and to display a prgress bar
|
||||
// which indicates the load state of our website, we're overloading
|
||||
// the CefLoadHandler as nested anonymous class. Beside this, the
|
||||
// load handler is responsible to deal with (load) errors as well.
|
||||
// For example if you navigate to a URL which does not exist, the
|
||||
// browser will show up an error message.
|
||||
client_.addLoadHandler(new CefLoadHandlerAdapter() {
|
||||
@Override
|
||||
public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
|
||||
boolean canGoBack, boolean canGoForward) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
control_pane_.update(browser, isLoading, canGoBack, canGoForward);
|
||||
status_panel_.setIsInProgress(isLoading);
|
||||
|
||||
if (!isLoading && !errorMsg_.isEmpty()) {
|
||||
browser.loadURL(DataUri.create("text/html", errorMsg_));
|
||||
errorMsg_ = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode,
|
||||
String errorText, String failedUrl) {
|
||||
if (errorCode != ErrorCode.ERR_NONE && errorCode != ErrorCode.ERR_ABORTED
|
||||
&& frame == browser.getMainFrame()) {
|
||||
errorMsg_ = "<html><head>";
|
||||
errorMsg_ += "<title>Error while loading</title>";
|
||||
errorMsg_ += "</head><body>";
|
||||
errorMsg_ += "<h1>" + errorCode + "</h1>";
|
||||
errorMsg_ += "<h3>Failed to load " + failedUrl + "</h3>";
|
||||
errorMsg_ += "<p>" + (errorText == null ? "" : errorText) + "</p>";
|
||||
errorMsg_ += "</body></html>";
|
||||
browser.stopLoad();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CefBrowserSettings browserSettings = new CefBrowserSettings();
|
||||
browserSettings.windowless_frame_rate = windowless_frame_rate;
|
||||
|
||||
// Create the browser.
|
||||
CefBrowser browser = client_.createBrowser("http://www.google.com", osrEnabled,
|
||||
transparentPaintingEnabled, null, browserSettings);
|
||||
setBrowser(browser);
|
||||
|
||||
// Set up the UI for this example implementation.
|
||||
contentPanel_ = createContentPanel();
|
||||
getContentPane().add(contentPanel_, BorderLayout.CENTER);
|
||||
|
||||
// Clear focus from the browser when the address field gains focus.
|
||||
control_pane_.getAddressField().addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (!browserFocus_) return;
|
||||
browserFocus_ = false;
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
|
||||
control_pane_.getAddressField().requestFocus();
|
||||
}
|
||||
});
|
||||
|
||||
// Clear focus from the address field when the browser gains focus.
|
||||
client_.addFocusHandler(new CefFocusHandlerAdapter() {
|
||||
@Override
|
||||
public void onGotFocus(CefBrowser browser) {
|
||||
if (browserFocus_) return;
|
||||
browserFocus_ = true;
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
|
||||
browser.setFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeFocus(CefBrowser browser, boolean next) {
|
||||
browserFocus_ = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (createImmediately) browser.createImmediately();
|
||||
|
||||
// Add the browser to the UI.
|
||||
contentPanel_.add(getBrowser().getUIComponent(), BorderLayout.CENTER);
|
||||
|
||||
MenuBar menuBar = new MenuBar(
|
||||
this, browser, control_pane_, downloadDialog, CefCookieManager.getGlobalManager());
|
||||
|
||||
menuBar.addBookmark("Binding Test", "client://tests/binding_test.html");
|
||||
menuBar.addBookmark("Binding Test 2", "client://tests/binding_test2.html");
|
||||
menuBar.addBookmark("Download Test", "https://cef-builds.spotifycdn.com/index.html");
|
||||
menuBar.addBookmark("Login Test (username:pumpkin, password:pie)",
|
||||
"http://www.colostate.edu/~ric/protect/your.html");
|
||||
menuBar.addBookmark("Certificate-error Test", "https://www.k2go.de");
|
||||
menuBar.addBookmark("Resource-Handler Test", "http://www.foo.bar/");
|
||||
menuBar.addBookmark("Resource-Handler Set Error Test", "http://seterror.test/");
|
||||
menuBar.addBookmark(
|
||||
"Scheme-Handler Test 1: (scheme \"client\")", "client://tests/handler.html");
|
||||
menuBar.addBookmark(
|
||||
"Scheme-Handler Test 2: (scheme \"search\")", "search://do a barrel roll/");
|
||||
menuBar.addBookmark("Spellcheck Test", "client://tests/spellcheck.html");
|
||||
menuBar.addBookmark("LocalStorage Test", "client://tests/localstorage.html");
|
||||
menuBar.addBookmark("Transparency Test", "client://tests/transparency.html");
|
||||
menuBar.addBookmark("Fullscreen Test",
|
||||
"https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_fullscreen2");
|
||||
menuBar.addBookmarkSeparator();
|
||||
menuBar.addBookmark(
|
||||
"javachromiumembedded", "https://github.com/chromiumembedded/java-cef");
|
||||
menuBar.addBookmark("chromiumembedded", "https://github.com/chromiumembedded/cef");
|
||||
setJMenuBar(menuBar);
|
||||
}
|
||||
|
||||
private JPanel createContentPanel() {
|
||||
JPanel contentPanel = new JPanel(new BorderLayout());
|
||||
control_pane_ = new ControlPanel(getBrowser());
|
||||
status_panel_ = new StatusPanel();
|
||||
contentPanel.add(control_pane_, BorderLayout.NORTH);
|
||||
contentPanel.add(status_panel_, BorderLayout.SOUTH);
|
||||
return contentPanel;
|
||||
}
|
||||
|
||||
public boolean isOsrEnabled() {
|
||||
return osr_enabled_;
|
||||
}
|
||||
|
||||
public boolean isTransparentPaintingEnabled() {
|
||||
return transparent_painting_enabled_;
|
||||
}
|
||||
|
||||
public void setBrowserFullscreen(boolean fullscreen) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Component browserUI = getBrowser().getUIComponent();
|
||||
if (fullscreen) {
|
||||
if (fullscreenFrame_ == null) {
|
||||
fullscreenFrame_ = new JFrame();
|
||||
fullscreenFrame_.setUndecorated(true);
|
||||
fullscreenFrame_.setResizable(true);
|
||||
}
|
||||
GraphicsConfiguration gc = MainFrame.this.getGraphicsConfiguration();
|
||||
fullscreenFrame_.setBounds(gc.getBounds());
|
||||
gc.getDevice().setFullScreenWindow(fullscreenFrame_);
|
||||
|
||||
contentPanel_.remove(browserUI);
|
||||
fullscreenFrame_.add(browserUI);
|
||||
fullscreenFrame_.setVisible(true);
|
||||
fullscreenFrame_.validate();
|
||||
} else {
|
||||
fullscreenFrame_.remove(browserUI);
|
||||
fullscreenFrame_.setVisible(false);
|
||||
contentPanel_.add(browserUI, BorderLayout.CENTER);
|
||||
contentPanel_.validate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefLoadHandler.ErrorCode;
|
||||
|
||||
import java.awt.Frame;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class CertErrorDialog implements Runnable {
|
||||
private final Frame owner_;
|
||||
private final ErrorCode cert_error_;
|
||||
private final String request_url_;
|
||||
private final CefCallback callback_;
|
||||
|
||||
public CertErrorDialog(
|
||||
Frame owner, ErrorCode cert_error, String request_url, CefCallback callback) {
|
||||
owner_ = owner;
|
||||
cert_error_ = cert_error;
|
||||
request_url_ = request_url;
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int dialogResult = JOptionPane.showConfirmDialog(owner_,
|
||||
"An certificate error (" + cert_error_ + ") occurreed "
|
||||
+ "while requesting\n" + request_url_ + "\nDo you want to proceed anyway?",
|
||||
"Certificate error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE);
|
||||
if (dialogResult == JOptionPane.YES_OPTION) {
|
||||
callback_.Continue();
|
||||
} else {
|
||||
callback_.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.callback.CefCookieVisitor;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.network.CefCookie;
|
||||
import org.cef.network.CefCookieManager;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class CookieManagerDialog extends JDialog {
|
||||
private static int testCookieId = 1;
|
||||
private final CefCookieManager manager;
|
||||
private final CookieTableModel tblModel = new CookieTableModel();
|
||||
|
||||
public CookieManagerDialog(Frame owner, String title, CefCookieManager cookieManager) {
|
||||
super(owner, title, false);
|
||||
setLayout(new BorderLayout());
|
||||
setSize(800, 600);
|
||||
manager = cookieManager;
|
||||
|
||||
JTable cookieTable = new JTable(tblModel);
|
||||
cookieTable.setFillsViewportHeight(true);
|
||||
|
||||
JPanel controlPanel = new JPanel();
|
||||
controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
|
||||
JButton delButton = new JButton("Delete cookies");
|
||||
delButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tblModel.removeCookies();
|
||||
}
|
||||
});
|
||||
controlPanel.add(delButton);
|
||||
|
||||
JButton testCreateCookie = new JButton("Add test cookie");
|
||||
testCreateCookie.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Date now = new Date();
|
||||
Date expires = new Date(now.getTime() + 86400000);
|
||||
String name = "testNo" + testCookieId++;
|
||||
CefCookie cookie = new CefCookie(name, "testCookie", ".test.cookie", "/", false,
|
||||
true, now, now, true, expires);
|
||||
if (manager.setCookie("http://my.test.cookie", cookie)) {
|
||||
tblModel.visit(cookie, 1, 1, new BoolRef());
|
||||
}
|
||||
}
|
||||
});
|
||||
controlPanel.add(testCreateCookie);
|
||||
|
||||
JButton doneButton = new JButton("Done");
|
||||
doneButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
controlPanel.add(doneButton);
|
||||
|
||||
add(new JScrollPane(cookieTable));
|
||||
add(controlPanel, BorderLayout.SOUTH);
|
||||
|
||||
if (manager == null) throw new NullPointerException("Cookie manager is null");
|
||||
manager.visitAllCookies(tblModel);
|
||||
}
|
||||
|
||||
private class CookieTableModel extends AbstractTableModel implements CefCookieVisitor {
|
||||
private final String[] columnNames;
|
||||
private Vector<Object[]> rowData = new Vector<>();
|
||||
|
||||
public CookieTableModel() {
|
||||
super();
|
||||
columnNames = new String[] {"Name", "Value", "Domain", "Path", "Secure", "HTTP only",
|
||||
"Created", "Last Access", "Expires"};
|
||||
}
|
||||
|
||||
// add an entry to the table
|
||||
@Override
|
||||
public boolean visit(CefCookie cookie, int count, int total, BoolRef delete) {
|
||||
Object[] entry = {cookie.name, cookie.value, cookie.domain, cookie.path,
|
||||
new Boolean(cookie.secure), new Boolean(cookie.httponly), cookie.creation,
|
||||
cookie.lastAccess, cookie.expires};
|
||||
int row = rowData.size();
|
||||
rowData.addElement(entry);
|
||||
fireTableRowsInserted(row, row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeCookies() {
|
||||
int cnt = rowData.size();
|
||||
if (cnt > 0) {
|
||||
rowData.clear();
|
||||
manager.deleteCookies("", "");
|
||||
fireTableRowsDeleted(0, cnt - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return rowData.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnNames[column];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
if (rowData.size() > 0) return rowData.get(0)[columnIndex].getClass();
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return rowData.get(rowIndex)[columnIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.callback.CefBeforeDownloadCallback;
|
||||
import org.cef.callback.CefDownloadItem;
|
||||
import org.cef.callback.CefDownloadItemCallback;
|
||||
import org.cef.handler.CefDownloadHandler;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DownloadDialog extends JDialog implements CefDownloadHandler {
|
||||
private final Frame owner_;
|
||||
private final Map<Integer, DownloadObject> downloadObjects_ =
|
||||
new HashMap<Integer, DownloadObject>();
|
||||
private final JPanel downloadPanel_ = new JPanel();
|
||||
private final DownloadDialog dialog_;
|
||||
|
||||
public DownloadDialog(Frame owner) {
|
||||
super(owner, "Downloads", false);
|
||||
setVisible(false);
|
||||
setSize(400, 300);
|
||||
|
||||
owner_ = owner;
|
||||
dialog_ = this;
|
||||
downloadPanel_.setLayout(new BoxLayout(downloadPanel_, BoxLayout.Y_AXIS));
|
||||
add(downloadPanel_);
|
||||
}
|
||||
|
||||
private class DownloadObject extends JPanel {
|
||||
private boolean isHidden_ = true;
|
||||
private final int identifier_;
|
||||
private JLabel fileName_ = new JLabel();
|
||||
private JLabel status_ = new JLabel();
|
||||
private JButton dlAbort_ = new JButton();
|
||||
private JButton dlRemoveEntry_ = new JButton("x");
|
||||
private CefDownloadItemCallback callback_;
|
||||
private Color bgColor_;
|
||||
|
||||
DownloadObject(CefDownloadItem downloadItem, String suggestedName) {
|
||||
super();
|
||||
setOpaque(true);
|
||||
setLayout(new BorderLayout());
|
||||
setMaximumSize(new Dimension(dialog_.getWidth() - 10, 80));
|
||||
identifier_ = downloadItem.getId();
|
||||
bgColor_ = identifier_ % 2 == 0 ? Color.WHITE : Color.YELLOW;
|
||||
setBackground(bgColor_);
|
||||
|
||||
fileName_.setText(suggestedName);
|
||||
add(fileName_, BorderLayout.NORTH);
|
||||
|
||||
status_.setAlignmentX(LEFT_ALIGNMENT);
|
||||
add(status_, BorderLayout.CENTER);
|
||||
|
||||
JPanel controlPane = new JPanel();
|
||||
controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.X_AXIS));
|
||||
controlPane.setOpaque(true);
|
||||
controlPane.setBackground(bgColor_);
|
||||
dlAbort_.setText("Abort");
|
||||
dlAbort_.setEnabled(false);
|
||||
dlAbort_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (callback_ != null) {
|
||||
fileName_.setText("ABORTED - " + fileName_.getText());
|
||||
callback_.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
controlPane.add(dlAbort_);
|
||||
|
||||
dlRemoveEntry_.setEnabled(false);
|
||||
dlRemoveEntry_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DownloadObject removed = downloadObjects_.remove(identifier_);
|
||||
if (removed != null) {
|
||||
downloadPanel_.remove(removed);
|
||||
dialog_.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
controlPane.add(dlRemoveEntry_);
|
||||
add(controlPane, BorderLayout.SOUTH);
|
||||
|
||||
update(downloadItem, null);
|
||||
}
|
||||
|
||||
// The method humanReadableByteCount() is based on
|
||||
// http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
|
||||
String humanReadableByteCount(long bytes) {
|
||||
int unit = 1024;
|
||||
if (bytes < unit) return bytes + " B";
|
||||
|
||||
int exp = (int) (Math.log(bytes) / Math.log(unit));
|
||||
String pre = "" + ("kMGTPE").charAt(exp - 1);
|
||||
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
|
||||
}
|
||||
|
||||
void update(CefDownloadItem downloadItem, CefDownloadItemCallback callback) {
|
||||
int percentComplete = downloadItem.getPercentComplete();
|
||||
String rcvBytes = humanReadableByteCount(downloadItem.getReceivedBytes());
|
||||
String totalBytes = humanReadableByteCount(downloadItem.getTotalBytes());
|
||||
String speed = humanReadableByteCount(downloadItem.getCurrentSpeed()) + "it/s";
|
||||
|
||||
if (downloadItem.getReceivedBytes() >= 5 && isHidden_) {
|
||||
dialog_.setVisible(true);
|
||||
dialog_.toFront();
|
||||
owner_.toBack();
|
||||
isHidden_ = false;
|
||||
}
|
||||
Runtime.getRuntime().runFinalization();
|
||||
|
||||
callback_ = callback;
|
||||
status_.setText(rcvBytes + " of " + totalBytes + " - " + percentComplete + "%"
|
||||
+ " - " + speed);
|
||||
dlAbort_.setEnabled(downloadItem.isInProgress());
|
||||
dlRemoveEntry_.setEnabled(!downloadItem.isInProgress() || downloadItem.isCanceled()
|
||||
|| downloadItem.isComplete());
|
||||
if (!downloadItem.isInProgress() && !downloadItem.isCanceled()
|
||||
&& !downloadItem.isComplete()) {
|
||||
fileName_.setText("FAILED - " + fileName_.getText());
|
||||
callback.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBeforeDownload(CefBrowser browser, CefDownloadItem downloadItem,
|
||||
String suggestedName, CefBeforeDownloadCallback callback) {
|
||||
callback.Continue(suggestedName, true);
|
||||
|
||||
DownloadObject dlObject = new DownloadObject(downloadItem, suggestedName);
|
||||
downloadObjects_.put(downloadItem.getId(), dlObject);
|
||||
downloadPanel_.add(dlObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadUpdated(
|
||||
CefBrowser browser, CefDownloadItem downloadItem, CefDownloadItemCallback callback) {
|
||||
DownloadObject dlObject = downloadObjects_.get(downloadItem.getId());
|
||||
if (dlObject == null) return;
|
||||
dlObject.update(downloadItem, callback);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.callback.CefAuthCallback;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PasswordDialog extends JDialog implements Runnable {
|
||||
private final JTextField username_ = new JTextField(20);
|
||||
private final JPasswordField password_ = new JPasswordField(20);
|
||||
private final CefAuthCallback callback_;
|
||||
|
||||
public PasswordDialog(Frame owner, CefAuthCallback callback) {
|
||||
super(owner, "Authentication required", true);
|
||||
callback_ = callback;
|
||||
setSize(400, 100);
|
||||
setLayout(new GridLayout(0, 2));
|
||||
add(new JLabel("Username:"));
|
||||
add(username_);
|
||||
add(new JLabel("Password:"));
|
||||
add(password_);
|
||||
|
||||
JButton abortButton = new JButton("Abort");
|
||||
abortButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
callback_.cancel();
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
add(abortButton);
|
||||
|
||||
JButton okButton = new JButton("OK");
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (username_.getText().isEmpty()) return;
|
||||
String password = new String(password_.getPassword());
|
||||
callback_.Continue(username_.getText(), password);
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
add(okButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class SearchDialog extends JDialog {
|
||||
private final CefBrowser browser_;
|
||||
private final JTextField searchField_ = new JTextField(30);
|
||||
private final JCheckBox caseCheckBox_ = new JCheckBox("Case sensitive");
|
||||
private final JButton prevButton_ = new JButton("Prev");
|
||||
private final JButton nextButton_ = new JButton("Next");
|
||||
|
||||
public SearchDialog(Frame owner, CefBrowser browser) {
|
||||
super(owner, "Find...", false);
|
||||
browser_ = browser;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setSize(400, 100);
|
||||
|
||||
JPanel searchPanel = new JPanel();
|
||||
searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.X_AXIS));
|
||||
searchPanel.add(Box.createHorizontalStrut(5));
|
||||
searchPanel.add(new JLabel("Search:"));
|
||||
searchPanel.add(searchField_);
|
||||
|
||||
JPanel controlPanel = new JPanel();
|
||||
controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
|
||||
controlPanel.add(Box.createHorizontalStrut(5));
|
||||
|
||||
JButton searchButton = new JButton("Search");
|
||||
searchButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (searchField_.getText() == null || searchField_.getText().isEmpty()) return;
|
||||
|
||||
setTitle("Find \"" + searchField_.getText() + "\"");
|
||||
boolean matchCase = caseCheckBox_.isSelected();
|
||||
browser_.find(searchField_.getText(), true, matchCase, false);
|
||||
prevButton_.setEnabled(true);
|
||||
nextButton_.setEnabled(true);
|
||||
}
|
||||
});
|
||||
controlPanel.add(searchButton);
|
||||
|
||||
prevButton_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
boolean matchCase = caseCheckBox_.isSelected();
|
||||
setTitle("Find \"" + searchField_.getText() + "\"");
|
||||
browser_.find(searchField_.getText(), false, matchCase, true);
|
||||
}
|
||||
});
|
||||
prevButton_.setEnabled(false);
|
||||
controlPanel.add(prevButton_);
|
||||
|
||||
nextButton_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
boolean matchCase = caseCheckBox_.isSelected();
|
||||
setTitle("Find \"" + searchField_.getText() + "\"");
|
||||
browser_.find(searchField_.getText(), true, matchCase, true);
|
||||
}
|
||||
});
|
||||
nextButton_.setEnabled(false);
|
||||
controlPanel.add(nextButton_);
|
||||
|
||||
controlPanel.add(Box.createHorizontalStrut(50));
|
||||
|
||||
JButton doneButton = new JButton("Done");
|
||||
doneButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
controlPanel.add(doneButton);
|
||||
|
||||
add(searchPanel, BorderLayout.NORTH);
|
||||
add(caseCheckBox_);
|
||||
add(controlPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
browser_.stopFinding(true);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.callback.CefStringVisitor;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ShowTextDialog extends JDialog implements CefStringVisitor {
|
||||
private final JTextArea textArea_ = new JTextArea();
|
||||
|
||||
public ShowTextDialog(Frame owner, String title) {
|
||||
super(owner, title, false);
|
||||
setLayout(new BorderLayout());
|
||||
setSize(800, 600);
|
||||
|
||||
JPanel controlPanel = new JPanel();
|
||||
controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
|
||||
JButton doneButton = new JButton("Done");
|
||||
doneButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
controlPanel.add(doneButton);
|
||||
|
||||
add(new JScrollPane(textArea_));
|
||||
add(controlPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String string) {
|
||||
if (!isVisible()) {
|
||||
setVisible(true);
|
||||
}
|
||||
textArea_.append(string);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.network.CefPostData;
|
||||
import org.cef.network.CefPostDataElement;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefRequest.CefUrlRequestFlags;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class UrlRequestDialog extends JDialog {
|
||||
private final Vector<JRadioButton> requestMethods = new Vector<>();
|
||||
private final Map<JCheckBox, Integer> requestFlags = new HashMap<>();
|
||||
private final TableModel headerTblModel = new TableModel(true);
|
||||
private final TableModel postDataModel = new TableModel(false);
|
||||
private final JTextField urlField;
|
||||
private final JTextField cookieUrl;
|
||||
private final Frame owner_;
|
||||
|
||||
private CefRequest createRequest() {
|
||||
String url = urlField.getText();
|
||||
if (url.isEmpty() || url.trim().equalsIgnoreCase("http://")) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(owner_,
|
||||
"Please specify at least an URL. Otherwise the CefRequest is invalid");
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
CefRequest request = CefRequest.create();
|
||||
if (request == null) return null;
|
||||
|
||||
String firstPartyForCookie = cookieUrl.getText();
|
||||
if (firstPartyForCookie.isEmpty() || firstPartyForCookie.trim().equalsIgnoreCase("http://"))
|
||||
firstPartyForCookie = url;
|
||||
|
||||
String method = "GET";
|
||||
for (int i = 0; i < requestMethods.size(); i++) {
|
||||
JRadioButton button = requestMethods.get(i);
|
||||
if (button.isSelected()) {
|
||||
method = button.getText();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CefPostData postData = null;
|
||||
int postDataRows = postDataModel.getRowCount();
|
||||
if (postDataRows > 0) {
|
||||
postData = CefPostData.create();
|
||||
} else if (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("PUT")) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(
|
||||
owner_, "The methods POST and PUT require at least one row of data.");
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
if (postData != null) {
|
||||
for (int i = 0; i < postDataRows; i++) {
|
||||
String value = (String) postDataModel.getValueAt(i, 0);
|
||||
if (value.trim().isEmpty()) continue;
|
||||
|
||||
CefPostDataElement elem = CefPostDataElement.create();
|
||||
if (elem != null) {
|
||||
File f = new File(value);
|
||||
if (f.isFile()) {
|
||||
elem.setToFile(value);
|
||||
} else {
|
||||
byte[] byteStr = value.getBytes();
|
||||
elem.setToBytes(byteStr.length, byteStr);
|
||||
}
|
||||
postData.addElement(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> headerMap = null;
|
||||
int headerRows = headerTblModel.getRowCount();
|
||||
if (headerRows > 0) {
|
||||
headerMap = new HashMap<>();
|
||||
for (int i = 0; i < headerRows; i++) {
|
||||
String key = (String) headerTblModel.getValueAt(i, 0);
|
||||
String value = (String) headerTblModel.getValueAt(i, 1);
|
||||
if (key.trim().isEmpty()) continue;
|
||||
|
||||
headerMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
Set<Entry<JCheckBox, Integer>> entrySet = requestFlags.entrySet();
|
||||
for (Entry<JCheckBox, Integer> entry : entrySet) {
|
||||
if (entry.getKey().isSelected()) {
|
||||
flags |= entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
request.set(url, method, postData, headerMap);
|
||||
request.setFirstPartyForCookies(firstPartyForCookie);
|
||||
request.setFlags(flags);
|
||||
return request;
|
||||
}
|
||||
|
||||
public UrlRequestDialog(Frame owner, String title) {
|
||||
super(owner, title, false);
|
||||
setSize(1200, 600);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
owner_ = owner;
|
||||
|
||||
// URL for the request
|
||||
urlField = new JTextField("http://");
|
||||
JPanel urlPanel = createPanelWithTitle("Request URL", 1, 0);
|
||||
urlPanel.add(urlField);
|
||||
|
||||
// URL for the cookies
|
||||
cookieUrl = new JTextField("http://");
|
||||
JPanel cookiePanel = createPanelWithTitle("Cookie-URL", 1, 0);
|
||||
cookiePanel.add(cookieUrl);
|
||||
|
||||
// Radio buttons for the request method
|
||||
ButtonGroup requestModeGrp = new ButtonGroup();
|
||||
JPanel requestModePanel = createPanelWithTitle("HTTP Request Mode", 1, 0);
|
||||
addRequestMode(requestModePanel, requestModeGrp, "GET", true);
|
||||
addRequestMode(requestModePanel, requestModeGrp, "HEAD", false);
|
||||
addRequestMode(requestModePanel, requestModeGrp, "POST", false);
|
||||
addRequestMode(requestModePanel, requestModeGrp, "PUT", false);
|
||||
addRequestMode(requestModePanel, requestModeGrp, "DELETE", false);
|
||||
|
||||
// Checkboxes for the flags
|
||||
JPanel flagsPanel = createPanelWithTitle("Flags", 0, 1);
|
||||
addRequestFlag(flagsPanel, "Skip cache", CefUrlRequestFlags.UR_FLAG_SKIP_CACHE,
|
||||
"If set the cache will be skipped when handling the request", false);
|
||||
addRequestFlag(flagsPanel, "Allow cached credentials",
|
||||
CefUrlRequestFlags.UR_FLAG_ALLOW_CACHED_CREDENTIALS,
|
||||
"If set user name, password, and cookies may be sent with the request, "
|
||||
+ "and cookies may be saved from the response.",
|
||||
false);
|
||||
addRequestFlag(flagsPanel, "Report Upload Progress",
|
||||
CefUrlRequestFlags.UR_FLAG_REPORT_UPLOAD_PROGRESS,
|
||||
"If set upload progress events will be generated when a request has a body", false);
|
||||
addRequestFlag(flagsPanel, "Report RawHeaders",
|
||||
CefUrlRequestFlags.UR_FLAG_REPORT_RAW_HEADERS,
|
||||
"If set the headers sent and received for the request will be recorded", false);
|
||||
addRequestFlag(flagsPanel, "No download data", CefUrlRequestFlags.UR_FLAG_NO_DOWNLOAD_DATA,
|
||||
"If set the CefURLRequestClient.onDownloadData method will not be called", false);
|
||||
addRequestFlag(flagsPanel, "No retry on 5xx", CefUrlRequestFlags.UR_FLAG_NO_RETRY_ON_5XX,
|
||||
"If set 5XX redirect errors will be propagated to the observer instead of automatically re-tried.",
|
||||
false);
|
||||
|
||||
// Table for header values
|
||||
JPanel headerValues = createPanelWithTable("Header Values", headerTblModel);
|
||||
headerTblModel.addEntry("User-Agent", "Mozilla/5.0 JCEF Example Agent");
|
||||
headerTblModel.addEntry("Accept",
|
||||
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
|
||||
// Table for post-data
|
||||
JPanel postData = createPanelWithTable("Post Data", postDataModel);
|
||||
|
||||
// Create view
|
||||
JPanel headerPanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.weightx = 0.5;
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
headerPanel.add(urlPanel, c);
|
||||
c.gridx = 1;
|
||||
headerPanel.add(cookiePanel, c);
|
||||
c.gridx = 0;
|
||||
c.gridy = 1;
|
||||
c.gridwidth = 2;
|
||||
c.weightx = 0.0;
|
||||
headerPanel.add(requestModePanel, c);
|
||||
|
||||
JPanel centerPanel = new JPanel(new GridLayout(2, 0));
|
||||
centerPanel.add(headerValues);
|
||||
centerPanel.add(postData);
|
||||
|
||||
JButton abortButton = new JButton("Abort");
|
||||
abortButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
JButton sendButton = new JButton("Send");
|
||||
sendButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CefRequest request = createRequest();
|
||||
if (request == null) return;
|
||||
|
||||
UrlRequestDialogReply handleRequest =
|
||||
new UrlRequestDialogReply(owner_, getTitle() + " - Result");
|
||||
handleRequest.send(request);
|
||||
handleRequest.setVisible(true);
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
JPanel bottomPanel = new JPanel(new GridLayout(0, 2));
|
||||
bottomPanel.add(abortButton);
|
||||
bottomPanel.add(sendButton);
|
||||
|
||||
add(headerPanel, BorderLayout.PAGE_START);
|
||||
add(flagsPanel, BorderLayout.LINE_START);
|
||||
add(centerPanel, BorderLayout.CENTER);
|
||||
add(bottomPanel, BorderLayout.PAGE_END);
|
||||
}
|
||||
|
||||
private void addRequestMode(
|
||||
JPanel panel, ButtonGroup buttonGrp, String requestMode, boolean selected) {
|
||||
JRadioButton button = new JRadioButton(requestMode, selected);
|
||||
buttonGrp.add(button);
|
||||
panel.add(button);
|
||||
requestMethods.addElement(button);
|
||||
}
|
||||
|
||||
private void addRequestFlag(
|
||||
JPanel panel, String flag, int value, String tooltip, boolean selected) {
|
||||
JCheckBox checkBox = new JCheckBox(flag, selected);
|
||||
checkBox.setToolTipText(tooltip);
|
||||
panel.add(checkBox);
|
||||
requestFlags.put(checkBox, value);
|
||||
}
|
||||
|
||||
private JPanel createPanelWithTitle(String title, int rows, int cols) {
|
||||
JPanel result = new JPanel(new GridLayout(rows, cols));
|
||||
result.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(title),
|
||||
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
|
||||
return result;
|
||||
}
|
||||
|
||||
private JPanel createPanelWithTable(String title, TableModel tblModel) {
|
||||
final TableModel localTblModel = tblModel;
|
||||
JPanel result = new JPanel(new BorderLayout());
|
||||
result.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(title),
|
||||
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
|
||||
|
||||
JTable table = new JTable(tblModel);
|
||||
table.setFillsViewportHeight(true);
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
|
||||
JPanel buttonPane = new JPanel(new GridLayout(0, 2));
|
||||
JButton addButton = new JButton("Add entry");
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
localTblModel.newDefaultEntry();
|
||||
}
|
||||
});
|
||||
buttonPane.add(addButton);
|
||||
|
||||
JButton delButton = new JButton("Remove entry");
|
||||
delButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
localTblModel.removeSelected();
|
||||
}
|
||||
});
|
||||
buttonPane.add(delButton);
|
||||
|
||||
result.add(scrollPane, BorderLayout.CENTER);
|
||||
result.add(buttonPane, BorderLayout.PAGE_END);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private class TableModel extends AbstractTableModel {
|
||||
private final String[] columnNames;
|
||||
private Vector<Object[]> rowData = new Vector<>();
|
||||
private final boolean hasKeyColumn_;
|
||||
|
||||
public TableModel(boolean hasKeyColumn) {
|
||||
super();
|
||||
hasKeyColumn_ = hasKeyColumn;
|
||||
if (hasKeyColumn)
|
||||
columnNames = new String[] {"Key", "Value", ""};
|
||||
else
|
||||
columnNames = new String[] {"Value", ""};
|
||||
}
|
||||
|
||||
public void newDefaultEntry() {
|
||||
int row = rowData.size();
|
||||
if (hasKeyColumn_) {
|
||||
Object[] rowEntry = {"key", "value", new Boolean(false)};
|
||||
rowData.addElement(rowEntry);
|
||||
} else {
|
||||
Object[] rowEntry = {"value", new Boolean(false)};
|
||||
rowData.addElement(rowEntry);
|
||||
}
|
||||
fireTableRowsInserted(row, row);
|
||||
}
|
||||
|
||||
public void removeSelected() {
|
||||
int idx = hasKeyColumn_ ? 2 : 1;
|
||||
for (int i = 0; i < rowData.size(); ++i) {
|
||||
if ((Boolean) rowData.get(i)[idx]) {
|
||||
rowData.remove(i);
|
||||
fireTableRowsDeleted(i, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addEntry(String key, String value) {
|
||||
int row = rowData.size();
|
||||
if (hasKeyColumn_) {
|
||||
Object[] rowEntry = {key, value, new Boolean(false)};
|
||||
rowData.addElement(rowEntry);
|
||||
} else {
|
||||
Object[] rowEntry = {value, new Boolean(false)};
|
||||
rowData.addElement(rowEntry);
|
||||
}
|
||||
fireTableRowsInserted(row, row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return rowData.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnNames[column];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
if (rowData.size() > 0) return rowData.get(0)[columnIndex].getClass();
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return rowData.get(rowIndex)[columnIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
rowData.get(rowIndex)[columnIndex] = aValue;
|
||||
fireTableCellUpdated(rowIndex, columnIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.dialog;
|
||||
|
||||
import org.cef.callback.CefAuthCallback;
|
||||
import org.cef.callback.CefURLRequestClient;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefResponse;
|
||||
import org.cef.network.CefURLRequest;
|
||||
import org.cef.network.CefURLRequest.Status;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class UrlRequestDialogReply extends JDialog implements CefURLRequestClient {
|
||||
private long nativeRef_ = 0;
|
||||
private final JLabel statusLabel_ = new JLabel("HTTP-Request status: ");
|
||||
private final JTextArea sentRequest_ = new JTextArea();
|
||||
private final JTextArea repliedResult_ = new JTextArea();
|
||||
private final JButton cancelButton_ = new JButton("Cancel");
|
||||
private CefURLRequest urlRequest_ = null;
|
||||
private final Frame owner_;
|
||||
private ByteArrayOutputStream byteStream_ = new ByteArrayOutputStream();
|
||||
|
||||
public UrlRequestDialogReply(Frame owner, String title) {
|
||||
super(owner, title, false);
|
||||
setLayout(new BorderLayout());
|
||||
setSize(800, 600);
|
||||
|
||||
owner_ = owner;
|
||||
|
||||
JPanel controlPanel = new JPanel();
|
||||
controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
|
||||
JButton doneButton = new JButton("Done");
|
||||
doneButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
urlRequest_.dispose();
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
controlPanel.add(doneButton);
|
||||
|
||||
cancelButton_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (urlRequest_ != null) {
|
||||
urlRequest_.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
cancelButton_.setEnabled(false);
|
||||
controlPanel.add(cancelButton_);
|
||||
|
||||
JPanel requestPane = createPanelWithTitle("Sent HTTP-Request", 1, 0);
|
||||
requestPane.add(new JScrollPane(sentRequest_));
|
||||
|
||||
JPanel replyPane = createPanelWithTitle("Reply from the server", 1, 0);
|
||||
replyPane.add(new JScrollPane(repliedResult_));
|
||||
|
||||
JPanel contentPane = new JPanel(new GridLayout(2, 0));
|
||||
contentPane.add(requestPane);
|
||||
contentPane.add(replyPane);
|
||||
|
||||
add(statusLabel_, BorderLayout.PAGE_START);
|
||||
add(contentPane, BorderLayout.CENTER);
|
||||
add(controlPanel, BorderLayout.PAGE_END);
|
||||
}
|
||||
|
||||
private JPanel createPanelWithTitle(String title, int rows, int cols) {
|
||||
JPanel result = new JPanel(new GridLayout(rows, cols));
|
||||
result.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(title),
|
||||
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public void send(CefRequest request) {
|
||||
if (request == null) {
|
||||
statusLabel_.setText("HTTP-Request status: FAILED");
|
||||
sentRequest_.append("Can't send CefRequest because it is NULL");
|
||||
cancelButton_.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
urlRequest_ = CefURLRequest.create(request, this);
|
||||
if (urlRequest_ == null) {
|
||||
statusLabel_.setText("HTTP-Request status: FAILED");
|
||||
sentRequest_.append("Can't send CefRequest because creation of CefURLRequest failed.");
|
||||
repliedResult_.append(
|
||||
"The native code (CEF) returned a NULL-Pointer for CefURLRequest.");
|
||||
cancelButton_.setEnabled(false);
|
||||
} else {
|
||||
sentRequest_.append(request.toString());
|
||||
cancelButton_.setEnabled(true);
|
||||
updateStatus("", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStatus(final String updateMsg, final boolean printByteStream) {
|
||||
final Status status = urlRequest_.getRequestStatus();
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
statusLabel_.setText("HTTP-Request status: " + status);
|
||||
if (status != Status.UR_UNKNOWN && status != Status.UR_IO_PENDING) {
|
||||
cancelButton_.setEnabled(false);
|
||||
}
|
||||
repliedResult_.append(updateMsg);
|
||||
if (printByteStream) {
|
||||
try {
|
||||
repliedResult_.append("\n\n" + byteStream_.toString("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
repliedResult_.append("\n\n" + byteStream_.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
// CefURLRequestClient
|
||||
|
||||
@Override
|
||||
public void setNativeRef(String identifer, long nativeRef) {
|
||||
nativeRef_ = nativeRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNativeRef(String identifer) {
|
||||
return nativeRef_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestComplete(CefURLRequest request) {
|
||||
String updateStr = "onRequestCompleted\n\n";
|
||||
CefResponse response = request.getResponse();
|
||||
boolean isText = response.getHeaderByName("Content-Type").startsWith("text");
|
||||
updateStr += response.toString();
|
||||
updateStatus(updateStr, isText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUploadProgress(CefURLRequest request, int current, int total) {
|
||||
updateStatus("onUploadProgress: " + current + "/" + total + " bytes\n", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadProgress(CefURLRequest request, int current, int total) {
|
||||
updateStatus("onDownloadProgress: " + current + "/" + total + " bytes\n", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadData(CefURLRequest request, byte[] data, int data_length) {
|
||||
byteStream_.write(data, 0, data_length);
|
||||
updateStatus("onDownloadData: " + data_length + " bytes\n", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAuthCredentials(boolean isProxy, String host, int port, String realm,
|
||||
String scheme, CefAuthCallback callback) {
|
||||
SwingUtilities.invokeLater(new PasswordDialog(owner_, callback));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.CefApp;
|
||||
import org.cef.CefApp.CefAppState;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.callback.CefSchemeHandlerFactory;
|
||||
import org.cef.callback.CefSchemeRegistrar;
|
||||
import org.cef.handler.CefAppHandlerAdapter;
|
||||
import org.cef.handler.CefResourceHandler;
|
||||
import org.cef.network.CefRequest;
|
||||
|
||||
public class AppHandler extends CefAppHandlerAdapter {
|
||||
// We're registering our own schemes to demonstrate how to use
|
||||
// CefAppHandler.onRegisterCustomSchemes() in combination with
|
||||
// CefApp.registerSchemeHandlerFactory().
|
||||
public AppHandler(String[] args) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
// (1) First of all we have to register our custom schemes by implementing
|
||||
// the method "onRegisterCustomSchemes. The scheme names are added by
|
||||
// calling CefSchemeRegistrar.addCustomScheme.
|
||||
@Override
|
||||
public void onRegisterCustomSchemes(CefSchemeRegistrar registrar) {
|
||||
if (registrar.addCustomScheme(
|
||||
SearchSchemeHandler.scheme, true, false, false, false, true, false, false)) {
|
||||
System.out.println("Added scheme " + SearchSchemeHandler.scheme + "://");
|
||||
}
|
||||
if (registrar.addCustomScheme(
|
||||
ClientSchemeHandler.scheme, true, false, false, false, true, false, false)) {
|
||||
System.out.println("Added scheme " + ClientSchemeHandler.scheme + "://");
|
||||
}
|
||||
}
|
||||
|
||||
// (2) At the next step we have to register a SchemeHandlerFactory which is
|
||||
// called if an user enters our registered scheme.
|
||||
//
|
||||
// This is done via the CefApp.registerSchemeHandlerFactory() method.
|
||||
// A good place to call this function is from
|
||||
// CefAppHandler.onContextInitialized().
|
||||
//
|
||||
// The empty |domain_name| value will cause the factory to match all
|
||||
// domain names. A set |domain_name| will only be valid for the entered
|
||||
// domain.
|
||||
@Override
|
||||
public void onContextInitialized() {
|
||||
CefApp cefApp = CefApp.getInstance();
|
||||
cefApp.registerSchemeHandlerFactory(
|
||||
SearchSchemeHandler.scheme, SearchSchemeHandler.domain, new SchemeHandlerFactory());
|
||||
cefApp.registerSchemeHandlerFactory(
|
||||
ClientSchemeHandler.scheme, ClientSchemeHandler.domain, new SchemeHandlerFactory());
|
||||
}
|
||||
|
||||
// (3) The SchemeHandlerFactory creates a new ResourceHandler instance for each
|
||||
// request the user has send to the browser. The ResourceHandler is the
|
||||
// responsible class to process and return the result of a received
|
||||
// request.
|
||||
private class SchemeHandlerFactory implements CefSchemeHandlerFactory {
|
||||
@Override
|
||||
public CefResourceHandler create(
|
||||
CefBrowser browser, CefFrame frame, String schemeName, CefRequest request) {
|
||||
if (schemeName.equals(SearchSchemeHandler.scheme))
|
||||
return new SearchSchemeHandler(browser);
|
||||
else if (schemeName.equals(ClientSchemeHandler.scheme))
|
||||
return new ClientSchemeHandler();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateHasChanged(CefAppState state) {
|
||||
System.out.println("AppHandler.stateHasChanged: " + state);
|
||||
if (state == CefAppState.TERMINATED) System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.callback.CefResourceReadCallback;
|
||||
import org.cef.handler.CefResourceHandlerAdapter;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.misc.IntRef;
|
||||
import org.cef.misc.StringRef;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefResponse;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* The example for the second scheme with domain handling is a more
|
||||
* complex example and is taken from the parent project CEF. Please
|
||||
* see CEF: "cefclient/scheme_test.cpp" for futher details
|
||||
*/
|
||||
public class ClientSchemeHandler extends CefResourceHandlerAdapter {
|
||||
public static final String scheme = "client";
|
||||
public static final String domain = "tests";
|
||||
|
||||
private byte[] data_;
|
||||
private String mime_type_;
|
||||
private int offset_ = 0;
|
||||
|
||||
public ClientSchemeHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean open(
|
||||
CefRequest request, BoolRef handleRequest, CefCallback callback) {
|
||||
boolean handled = false;
|
||||
String url = request.getURL();
|
||||
if (url.indexOf("handler.html") != -1) {
|
||||
// Build the response html
|
||||
String html;
|
||||
html = "<html><head><title>Client Scheme Handler</title></head>"
|
||||
+ "<body bgcolor=\"white\">"
|
||||
+ "This contents of this page page are served by the "
|
||||
+ "ClientSchemeHandler class handling the client:// protocol."
|
||||
+ "<br/>You should see an image:"
|
||||
+ "<br/><img src=\"client://tests/logo.png\"><pre>";
|
||||
|
||||
// Output a string representation of the request
|
||||
html += request.toString();
|
||||
|
||||
html += "</pre><br/>Try the test form:"
|
||||
+ "<form method=\"POST\" action=\"handler.html\">"
|
||||
+ "<input type=\"text\" name=\"field1\">"
|
||||
+ "<input type=\"text\" name=\"field2\">"
|
||||
+ "<input type=\"submit\">"
|
||||
+ "</form></body></html>";
|
||||
|
||||
data_ = html.getBytes();
|
||||
|
||||
handled = true;
|
||||
// Set the resulting mime type
|
||||
mime_type_ = "text/html";
|
||||
} else if (url.endsWith(".png")) {
|
||||
handled = loadContent(url.substring(url.lastIndexOf('/') + 1));
|
||||
mime_type_ = "image/png";
|
||||
} else if (url.endsWith(".html")) {
|
||||
handled = loadContent(url.substring(url.lastIndexOf('/') + 1));
|
||||
mime_type_ = "text/html";
|
||||
if (!handled) {
|
||||
String html = "<html><head><title>Error 404</title></head>";
|
||||
html += "<body><h1>Error 404</h1>";
|
||||
html += "File " + url.substring(url.lastIndexOf('/') + 1) + " ";
|
||||
html += "does not exist</body></html>";
|
||||
data_ = html.getBytes();
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// All requests are handled immediately
|
||||
handleRequest.set(true);
|
||||
|
||||
if (handled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResponseHeaders(
|
||||
CefResponse response, IntRef response_length, StringRef redirectUrl) {
|
||||
response.setMimeType(mime_type_);
|
||||
response.setStatus(200);
|
||||
|
||||
// Set the resulting response length
|
||||
response_length.set(data_.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean read(byte[] data_out, int bytes_to_read, IntRef bytes_read,
|
||||
CefResourceReadCallback callback) {
|
||||
boolean has_data = false;
|
||||
|
||||
if (offset_ < data_.length) {
|
||||
// Copy the next block of data into the buffer.
|
||||
int transfer_size = Math.min(bytes_to_read, (data_.length - offset_));
|
||||
System.arraycopy(data_, offset_, data_out, 0, transfer_size);
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read.set(transfer_size);
|
||||
has_data = true;
|
||||
} else {
|
||||
offset_ = 0;
|
||||
bytes_read.set(0);
|
||||
}
|
||||
|
||||
return has_data;
|
||||
}
|
||||
|
||||
private boolean loadContent(String resName) {
|
||||
InputStream inStream = getClass().getResourceAsStream(resName);
|
||||
if (inStream != null) {
|
||||
try {
|
||||
ByteArrayOutputStream outFile = new ByteArrayOutputStream();
|
||||
int readByte = -1;
|
||||
while ((readByte = inStream.read()) >= 0) outFile.write(readByte);
|
||||
data_ = outFile.toByteArray();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.callback.CefContextMenuParams;
|
||||
import org.cef.callback.CefMenuModel;
|
||||
import org.cef.callback.CefMenuModel.MenuId;
|
||||
import org.cef.handler.CefContextMenuHandler;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import tests.detailed.dialog.SearchDialog;
|
||||
import tests.detailed.dialog.ShowTextDialog;
|
||||
|
||||
public class ContextMenuHandler implements CefContextMenuHandler {
|
||||
private final Frame owner_;
|
||||
private Map<Integer, String> suggestions_ = new HashMap<Integer, String>();
|
||||
|
||||
public ContextMenuHandler(Frame owner) {
|
||||
owner_ = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeContextMenu(
|
||||
CefBrowser browser, CefFrame frame, CefContextMenuParams params, CefMenuModel model) {
|
||||
model.clear();
|
||||
|
||||
// Navigation menu
|
||||
model.addItem(MenuId.MENU_ID_BACK, "Back");
|
||||
model.setEnabled(MenuId.MENU_ID_BACK, browser.canGoBack());
|
||||
|
||||
model.addItem(MenuId.MENU_ID_FORWARD, "Forward");
|
||||
model.setEnabled(MenuId.MENU_ID_FORWARD, browser.canGoForward());
|
||||
|
||||
model.addSeparator();
|
||||
model.addItem(MenuId.MENU_ID_FIND, "Find...");
|
||||
if (params.hasImageContents() && params.getSourceUrl() != null)
|
||||
model.addItem(MenuId.MENU_ID_USER_FIRST, "Download Image...");
|
||||
model.addItem(MenuId.MENU_ID_VIEW_SOURCE, "View Source...");
|
||||
|
||||
Vector<String> suggestions = new Vector<String>();
|
||||
params.getDictionarySuggestions(suggestions);
|
||||
|
||||
// Spell checking menu
|
||||
model.addSeparator();
|
||||
if (suggestions.size() == 0) {
|
||||
model.addItem(MenuId.MENU_ID_NO_SPELLING_SUGGESTIONS, "No suggestions");
|
||||
model.setEnabled(MenuId.MENU_ID_NO_SPELLING_SUGGESTIONS, false);
|
||||
return;
|
||||
}
|
||||
|
||||
int id = MenuId.MENU_ID_SPELLCHECK_SUGGESTION_0;
|
||||
for (String suggestedWord : suggestions) {
|
||||
model.addItem(id, suggestedWord);
|
||||
suggestions_.put(id, suggestedWord);
|
||||
if (++id > MenuId.MENU_ID_SPELLCHECK_SUGGESTION_LAST) break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextMenuCommand(CefBrowser browser, CefFrame frame,
|
||||
CefContextMenuParams params, int commandId, int eventFlags) {
|
||||
switch (commandId) {
|
||||
case MenuId.MENU_ID_VIEW_SOURCE:
|
||||
ShowTextDialog visitor =
|
||||
new ShowTextDialog(owner_, "Source of \"" + browser.getURL() + "\"");
|
||||
browser.getSource(visitor);
|
||||
return true;
|
||||
case MenuId.MENU_ID_FIND:
|
||||
SearchDialog search = new SearchDialog(owner_, browser);
|
||||
search.setVisible(true);
|
||||
return true;
|
||||
case MenuId.MENU_ID_USER_FIRST:
|
||||
browser.startDownload(params.getSourceUrl());
|
||||
return true;
|
||||
default:
|
||||
if (commandId >= MenuId.MENU_ID_SPELLCHECK_SUGGESTION_0) {
|
||||
String newWord = suggestions_.get(commandId);
|
||||
if (newWord != null) {
|
||||
System.err.println(
|
||||
"replacing " + params.getMisspelledWord() + " with " + newWord);
|
||||
browser.replaceMisspelling(newWord);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextMenuDismissed(CefBrowser browser, CefFrame frame) {
|
||||
suggestions_.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.callback.CefDragData;
|
||||
import org.cef.handler.CefDragHandler;
|
||||
|
||||
public class DragHandler implements CefDragHandler {
|
||||
@Override
|
||||
public boolean onDragEnter(CefBrowser browser, CefDragData dragData, int mask) {
|
||||
System.out.println("DRAG:");
|
||||
System.out.print(" flags:");
|
||||
if ((mask & CefDragHandler.DragOperationMask.DRAG_OPERATION_COPY) != 0)
|
||||
System.out.print(" COPY");
|
||||
if ((mask & CefDragHandler.DragOperationMask.DRAG_OPERATION_LINK) != 0)
|
||||
System.out.print(" LINK");
|
||||
if ((mask & CefDragHandler.DragOperationMask.DRAG_OPERATION_GENERIC) != 0)
|
||||
System.out.print(" GENERIC");
|
||||
if ((mask & CefDragHandler.DragOperationMask.DRAG_OPERATION_PRIVATE) != 0)
|
||||
System.out.print(" PRIVATE");
|
||||
if ((mask & CefDragHandler.DragOperationMask.DRAG_OPERATION_MOVE) != 0)
|
||||
System.out.print(" MOVE");
|
||||
if ((mask & CefDragHandler.DragOperationMask.DRAG_OPERATION_DELETE) != 0)
|
||||
System.out.print(" DELETE");
|
||||
System.out.println("\n " + dragData);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.callback.CefJSDialogCallback;
|
||||
import org.cef.handler.CefJSDialogHandlerAdapter;
|
||||
import org.cef.misc.BoolRef;
|
||||
|
||||
public class JSDialogHandler extends CefJSDialogHandlerAdapter {
|
||||
@Override
|
||||
public boolean onJSDialog(CefBrowser browser, String origin_url, JSDialogType dialog_type,
|
||||
String message_text, String default_prompt_text, CefJSDialogCallback callback,
|
||||
BoolRef suppress_message) {
|
||||
if (message_text.equalsIgnoreCase("Never displayed")) {
|
||||
suppress_message.set(true);
|
||||
System.out.println(
|
||||
"The " + dialog_type + " from origin \"" + origin_url + "\" was suppressed.");
|
||||
System.out.println(
|
||||
" The content of the suppressed dialog was: \"" + message_text + "\"");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.handler.CefKeyboardHandlerAdapter;
|
||||
|
||||
public class KeyboardHandler extends CefKeyboardHandlerAdapter {
|
||||
@Override
|
||||
public boolean onKeyEvent(CefBrowser browser, CefKeyEvent event) {
|
||||
if (!event.focus_on_editable_field && event.windows_key_code == 0x20) {
|
||||
// Special handling for the space character when an input element does not
|
||||
// have focus. Handling the event in OnPreKeyEvent() keeps the event from
|
||||
// being processed in the renderer. If we instead handled the event in the
|
||||
// OnKeyEvent() method the space key would cause the window to scroll in
|
||||
// addition to showing the alert box.
|
||||
if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN) {
|
||||
browser.executeJavaScript("alert('You pressed the space bar!');", "", 0);
|
||||
}
|
||||
return true;
|
||||
} else if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN && event.is_system_key) {
|
||||
// CMD+[key] is not working on a Mac.
|
||||
// This switch statement delegates the common keyboard shortcuts to the browser
|
||||
switch (event.unmodified_character) {
|
||||
case 'a':
|
||||
browser.getFocusedFrame().selectAll();
|
||||
break;
|
||||
case 'c':
|
||||
browser.getFocusedFrame().copy();
|
||||
break;
|
||||
case 'v':
|
||||
browser.getFocusedFrame().paste();
|
||||
break;
|
||||
case 'x':
|
||||
browser.getFocusedFrame().cut();
|
||||
break;
|
||||
case 'z':
|
||||
browser.getFocusedFrame().undo();
|
||||
break;
|
||||
case 'Z':
|
||||
browser.getFocusedFrame().redo();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.callback.CefQueryCallback;
|
||||
import org.cef.handler.CefMessageRouterHandlerAdapter;
|
||||
|
||||
public class MessageRouterHandler extends CefMessageRouterHandlerAdapter {
|
||||
@Override
|
||||
public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String request,
|
||||
boolean persistent, CefQueryCallback callback) {
|
||||
if (request.indexOf("BindingTest:") == 0) {
|
||||
// Reverse the message and return it to the JavaScript caller.
|
||||
String msg = request.substring(12);
|
||||
callback.success(new StringBuilder(msg).reverse().toString());
|
||||
return true;
|
||||
}
|
||||
// Not handled.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.CefClient;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.browser.CefMessageRouter;
|
||||
import org.cef.browser.CefMessageRouter.CefMessageRouterConfig;
|
||||
import org.cef.callback.CefQueryCallback;
|
||||
import org.cef.handler.CefMessageRouterHandlerAdapter;
|
||||
|
||||
public class MessageRouterHandlerEx extends CefMessageRouterHandlerAdapter {
|
||||
private final CefClient client_;
|
||||
private final CefMessageRouterConfig config_ =
|
||||
new CefMessageRouterConfig("myQuery", "myQueryAbort");
|
||||
private CefMessageRouter router_ = null;
|
||||
|
||||
public MessageRouterHandlerEx(final CefClient client) {
|
||||
client_ = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String request,
|
||||
boolean persistent, CefQueryCallback callback) {
|
||||
if (request.startsWith("hasExtension")) {
|
||||
if (router_ != null)
|
||||
callback.success("");
|
||||
else
|
||||
callback.failure(0, "");
|
||||
} else if (request.startsWith("enableExt")) {
|
||||
if (router_ != null) {
|
||||
callback.failure(-1, "Already enabled");
|
||||
} else {
|
||||
router_ = CefMessageRouter.create(config_, new JavaVersionMessageRouter());
|
||||
client_.addMessageRouter(router_);
|
||||
callback.success("");
|
||||
}
|
||||
} else if (request.startsWith("disableExt")) {
|
||||
if (router_ == null) {
|
||||
callback.failure(-2, "Already disabled");
|
||||
} else {
|
||||
client_.removeMessageRouter(router_);
|
||||
router_.dispose();
|
||||
router_ = null;
|
||||
callback.success("");
|
||||
}
|
||||
} else {
|
||||
// not handled
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private class JavaVersionMessageRouter extends CefMessageRouterHandlerAdapter {
|
||||
@Override
|
||||
public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String request,
|
||||
boolean persistent, CefQueryCallback callback) {
|
||||
if (request.startsWith("jcefJava")) {
|
||||
callback.success(System.getProperty("java.version"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.callback.CefAuthCallback;
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefLoadHandler.ErrorCode;
|
||||
import org.cef.handler.CefRequestHandler;
|
||||
import org.cef.handler.CefResourceHandler;
|
||||
import org.cef.handler.CefResourceRequestHandler;
|
||||
import org.cef.handler.CefResourceRequestHandlerAdapter;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.network.CefPostData;
|
||||
import org.cef.network.CefPostDataElement;
|
||||
import org.cef.network.CefRequest;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.util.HashMap;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import tests.detailed.dialog.CertErrorDialog;
|
||||
import tests.detailed.dialog.PasswordDialog;
|
||||
|
||||
public class RequestHandler extends CefResourceRequestHandlerAdapter implements CefRequestHandler {
|
||||
private final Frame owner_;
|
||||
|
||||
public RequestHandler(Frame owner) {
|
||||
owner_ = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBeforeBrowse(CefBrowser browser, CefFrame frame, CefRequest request,
|
||||
boolean user_gesture, boolean is_redirect) {
|
||||
CefPostData postData = request.getPostData();
|
||||
if (postData != null) {
|
||||
Vector<CefPostDataElement> elements = new Vector<CefPostDataElement>();
|
||||
postData.getElements(elements);
|
||||
for (CefPostDataElement el : elements) {
|
||||
int numBytes = el.getBytesCount();
|
||||
if (numBytes <= 0) continue;
|
||||
|
||||
byte[] readBytes = new byte[numBytes];
|
||||
if (el.getBytes(numBytes, readBytes) <= 0) continue;
|
||||
|
||||
String readString = new String(readBytes);
|
||||
if (readString.indexOf("ignore") > -1) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(owner_,
|
||||
"The request was rejected because you've entered \"ignore\" into the form.");
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOpenURLFromTab(
|
||||
CefBrowser browser, CefFrame frame, String target_url, boolean user_gesture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame,
|
||||
CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator,
|
||||
BoolRef disableDefaultHandling) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBeforeResourceLoad(CefBrowser browser, CefFrame frame, CefRequest request) {
|
||||
// If you send a HTTP-POST request to http://www.google.com/
|
||||
// google rejects your request because they don't allow HTTP-POST.
|
||||
//
|
||||
// This test extracts the value of the test form.
|
||||
// (see "Show Form" entry within BrowserMenuBar)
|
||||
// and sends its value as HTTP-GET request to Google.
|
||||
if (request.getMethod().equalsIgnoreCase("POST")
|
||||
&& request.getURL().equals("http://www.google.com/")) {
|
||||
String forwardTo = "http://www.google.com/#q=";
|
||||
CefPostData postData = request.getPostData();
|
||||
boolean sendAsGet = false;
|
||||
if (postData != null) {
|
||||
Vector<CefPostDataElement> elements = new Vector<CefPostDataElement>();
|
||||
postData.getElements(elements);
|
||||
for (CefPostDataElement el : elements) {
|
||||
int numBytes = el.getBytesCount();
|
||||
if (numBytes <= 0) continue;
|
||||
|
||||
byte[] readBytes = new byte[numBytes];
|
||||
if (el.getBytes(numBytes, readBytes) <= 0) continue;
|
||||
|
||||
String readString = new String(readBytes).trim();
|
||||
String[] stringPairs = readString.split("&");
|
||||
for (String s : stringPairs) {
|
||||
int startPos = s.indexOf('=');
|
||||
if (s.startsWith("searchFor"))
|
||||
forwardTo += s.substring(startPos + 1);
|
||||
else if (s.startsWith("sendAsGet")) {
|
||||
sendAsGet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sendAsGet) postData.removeElements();
|
||||
}
|
||||
if (sendAsGet) {
|
||||
request.setFlags(0);
|
||||
request.setMethod("GET");
|
||||
request.setURL(forwardTo);
|
||||
request.setFirstPartyForCookies(forwardTo);
|
||||
HashMap<String, String> headerMap = new HashMap<>();
|
||||
request.getHeaderMap(headerMap);
|
||||
headerMap.remove("Content-Type");
|
||||
headerMap.remove("Origin");
|
||||
request.setHeaderMap(headerMap);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CefResourceHandler getResourceHandler(
|
||||
CefBrowser browser, CefFrame frame, CefRequest request) {
|
||||
// the non existing domain "foo.bar" is handled by the ResourceHandler implementation
|
||||
// E.g. if you try to load the URL http://www.foo.bar, you'll be forwarded
|
||||
// to the ResourceHandler class.
|
||||
if (request.getURL().endsWith("foo.bar/")) {
|
||||
return new ResourceHandler();
|
||||
}
|
||||
|
||||
if (request.getURL().endsWith("seterror.test/")) {
|
||||
return new ResourceSetErrorHandler();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy,
|
||||
String host, int port, String realm, String scheme, CefAuthCallback callback) {
|
||||
SwingUtilities.invokeLater(new PasswordDialog(owner_, callback));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCertificateError(
|
||||
CefBrowser browser, ErrorCode cert_error, String request_url, CefCallback callback) {
|
||||
SwingUtilities.invokeLater(new CertErrorDialog(owner_, cert_error, request_url, callback));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderProcessTerminated(
|
||||
CefBrowser browser, TerminationStatus status, int error_code, String error_string) {
|
||||
System.out.println("render process terminated: " + status + " errorCode: " + error_code
|
||||
+ " errorString: " + error_string);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.callback.CefResourceReadCallback;
|
||||
import org.cef.handler.CefLoadHandler;
|
||||
import org.cef.handler.CefResourceHandlerAdapter;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.misc.IntRef;
|
||||
import org.cef.misc.StringRef;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefResponse;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ResourceHandler extends CefResourceHandlerAdapter {
|
||||
private int startPos = 0;
|
||||
private static final String html = new String("<html>\n"
|
||||
+ " <head>\n"
|
||||
+ " <title>ResourceHandler Test</title>\n"
|
||||
+ " </head>\n"
|
||||
+ " <body>\n"
|
||||
+ " <h1>ResourceHandler Test</h1>\n"
|
||||
+ " <p>You have entered the URL: http://www.foo.bar. This page is generated by the application itself and<br/>\n"
|
||||
+ " no HTTP request was sent to the internet.\n"
|
||||
+ " <p>See class <u>tests.handler.ResourceHandler</u> and the <u>RequestHandler</u> implementation for details.</p>\n"
|
||||
+ " </body>\n"
|
||||
+ "</html>");
|
||||
|
||||
@Override
|
||||
public boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback) {
|
||||
System.out.println("processRequest: " + request);
|
||||
|
||||
startPos = 0;
|
||||
handleRequest.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResponseHeaders(
|
||||
CefResponse response, IntRef response_length, StringRef redirectUrl) {
|
||||
System.out.println("getResponseHeaders: " + response);
|
||||
|
||||
response_length.set(html.length());
|
||||
response.setMimeType("text/html");
|
||||
response.setStatus(200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean read(byte[] data_out, int bytes_to_read, IntRef bytes_read,
|
||||
CefResourceReadCallback callback) {
|
||||
int length = html.length();
|
||||
if (startPos >= length) return false;
|
||||
|
||||
// Extract up to bytes_to_read bytes from the html data
|
||||
int endPos = startPos + bytes_to_read;
|
||||
String dataToSend =
|
||||
(endPos > length) ? html.substring(startPos) : html.substring(startPos, endPos);
|
||||
|
||||
// Copy extracted bytes into data_out and set the read length
|
||||
// to bytes_read.
|
||||
ByteBuffer result = ByteBuffer.wrap(data_out);
|
||||
result.put(dataToSend.getBytes());
|
||||
bytes_read.set(dataToSend.length());
|
||||
|
||||
startPos = endPos;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
System.out.println("cancel");
|
||||
startPos = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefLoadHandler.ErrorCode;
|
||||
import org.cef.handler.CefResourceHandlerAdapter;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.misc.IntRef;
|
||||
import org.cef.misc.StringRef;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefResponse;
|
||||
|
||||
public class ResourceSetErrorHandler extends CefResourceHandlerAdapter {
|
||||
@Override
|
||||
public boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback) {
|
||||
System.out.println("processRequest: " + request);
|
||||
handleRequest.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResponseHeaders(
|
||||
CefResponse response, IntRef response_length, StringRef redirectUrl) {
|
||||
response.setError(ErrorCode.ERR_NOT_IMPLEMENTED);
|
||||
System.out.println("getResponseHeaders: " + response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.handler;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefResourceHandlerAdapter;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.network.CefRequest;
|
||||
|
||||
/**
|
||||
* In this case we create a new CefRequest object with
|
||||
* http://www.google.com/#q=<entered value without scheme search>
|
||||
* as target and forward it to the CefBrowser instance.
|
||||
* The "search://"-request is aborted by returning false.
|
||||
*/
|
||||
public class SearchSchemeHandler extends CefResourceHandlerAdapter {
|
||||
public static final String scheme = "search";
|
||||
public static final String domain = "";
|
||||
|
||||
private final CefBrowser browser_;
|
||||
|
||||
public SearchSchemeHandler(CefBrowser browser) {
|
||||
browser_ = browser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(CefRequest request, BoolRef handleRequest, CefCallback callback) {
|
||||
// cut away "scheme://"
|
||||
String requestUrl = request.getURL();
|
||||
String newUrl = requestUrl.substring(scheme.length() + 3);
|
||||
// cut away a trailing "/" if any
|
||||
if (newUrl.indexOf('/') == newUrl.length() - 1) {
|
||||
newUrl = newUrl.substring(0, newUrl.length() - 1);
|
||||
}
|
||||
newUrl = "http://www.google.com/#q=" + newUrl;
|
||||
|
||||
CefRequest newRequest = CefRequest.create();
|
||||
if (newRequest != null) {
|
||||
newRequest.setMethod("GET");
|
||||
newRequest.setURL(newUrl);
|
||||
newRequest.setFirstPartyForCookies(newUrl);
|
||||
browser_.loadRequest(newRequest);
|
||||
}
|
||||
handleRequest.set(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Binding Test</title>
|
||||
<script language="JavaScript">
|
||||
|
||||
// Send a query to the browser process.
|
||||
function sendMessage() {
|
||||
// Results in a call to the OnQuery method in binding_test.cpp
|
||||
window.cefQuery({
|
||||
request: 'BindingTest:' + document.getElementById("message").value,
|
||||
onSuccess: function(response) {
|
||||
document.getElementById('result').value = 'Response: '+response;
|
||||
},
|
||||
onFailure: function(error_code, error_message) {}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<form>
|
||||
Message: <input type="text" id="message" value="My Message">
|
||||
<br/><input type="button" onclick="sendMessage();" value="Send Message">
|
||||
<br/>You should see the reverse of your message below:
|
||||
<br/><textarea rows="10" cols="40" id="result"></textarea>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,81 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Binding Test - Part 2</title>
|
||||
<script language="JavaScript">
|
||||
|
||||
function toggleButton() {
|
||||
window.cefQuery({
|
||||
request: 'hasExtension',
|
||||
onSuccess: function(response) {
|
||||
document.getElementById('jcefOn').disabled = true;
|
||||
document.getElementById('jcefOff').disabled = false;
|
||||
},
|
||||
onFailure: function(error_code, error_message) {
|
||||
document.getElementById('jcefOn').disabled = false;
|
||||
document.getElementById('jcefOff').disabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function execute(cmd) {
|
||||
window.cefQuery({
|
||||
request: cmd,
|
||||
onSuccess: function(response) {
|
||||
location.reload();
|
||||
},
|
||||
onFailure: function(error_code, error_message) {
|
||||
document.getElementById('result').value = 'Error: '+error_message;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getJavaVersion() {
|
||||
if ("myQuery" in window) {
|
||||
window.myQuery({
|
||||
request: 'jcefJava',
|
||||
onSuccess: function(response) {
|
||||
document.getElementById('result').value = 'Java Version: '+response;
|
||||
},
|
||||
onFailure: function(error_code, error_message) {
|
||||
document.getElementById('result').value = 'Error: '+error_message;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
document.getElementById('result').value = 'Error: myQuery isn\'t enabled';
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<head>
|
||||
|
||||
<body bgcolor="white" onload="toggleButton()">
|
||||
|
||||
<form>
|
||||
<h1>JavaScript Binding Test - Part 2</h1>
|
||||
<p>While this page was loaded, the JavaScript function
|
||||
<pre>window.cefRequest(request: 'hasExtension')</pre>
|
||||
was executed for enabling/disabling the buttons below.
|
||||
<br/> <br/>
|
||||
If you press "Enable myQuery", the JavaScript function
|
||||
<pre>window.cefRequest(request: 'enableExt')</pre>
|
||||
is executed. This causes Java to create a second instance of
|
||||
<pre>CefMessageRouter</pre>
|
||||
In this case the name of the JavaScript query function is set to "myQuery" and
|
||||
<br/>a handler for the request 'jcefJava' is registered. Pressing the "Test"
|
||||
<br/>button will execute the JavaScript code
|
||||
<pre>window.myRequest(request: 'jcefJava')</pre>
|
||||
which returns your current Java version on success or an error message in case
|
||||
<br/>of an error.
|
||||
</p>
|
||||
<p><b>Please note:</b> If you leave this page (myQuery enabled) and you return
|
||||
<br/>after a while - without closing the browser - the JavaScript binding is
|
||||
<br/>still enabled.</p>
|
||||
Second message router:
|
||||
<input type="button" id="jcefOn" value="Enable myQuery" onclick="execute('enableExt');" />
|
||||
<input type="button" id="jcefOff" value="Disable myQuery" onclick="execute('disableExt');" />
|
||||
<br/><input type="button" onclick="getJavaVersion();" value="Test"/>
|
||||
<input type="text" id="result" size="80" readonly />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<body bgcolor="white">
|
||||
<script language="JavaScript">
|
||||
var val = window.localStorage.getItem('val');
|
||||
function addLine() {
|
||||
if(val == null)
|
||||
val = '<br/>One Line.';
|
||||
else
|
||||
val += '<br/>Another Line.';
|
||||
window.localStorage.setItem('val', val);
|
||||
document.getElementById('out').innerHTML = val;
|
||||
}
|
||||
</script>
|
||||
Click the "Add Line" button to add a line or the "Clear" button to clear.<br/>
|
||||
This data will persist across sessions if a cache path was specified.<br/>
|
||||
<input type="button" value="Add Line" onClick="addLine();"/>
|
||||
<input type="button" value="Clear" onClick="window.localStorage.removeItem('val'); window.location.reload();"/>
|
||||
<div id="out"></div>
|
||||
<script language="JavaScript">
|
||||
if(val != null)
|
||||
document.getElementById('out').innerHTML = val;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,14 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Spellcheck Test</title>
|
||||
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
The next paragraph contains some text to be validated against the spell-checker.
|
||||
<br/> Click into the following box. To replace a misspelled word use the
|
||||
right-mouse-click.<br/>
|
||||
<p contenteditable="true" spellcheck="true" style="background-color:#F6E3CE">
|
||||
This is a misspelled paragrapph. Withh maany errors<br/> Click into this bogx
|
||||
to ttest it.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Transparency Examples</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Verdana, Arial;
|
||||
}
|
||||
img {
|
||||
opacity:0.4;
|
||||
}
|
||||
img:hover {
|
||||
opacity:1.0;
|
||||
}
|
||||
.box_white, .box_black {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
}
|
||||
.box_white {
|
||||
background-color: white;
|
||||
border: 2px solid black;
|
||||
color: black;
|
||||
}
|
||||
.box_black {
|
||||
background-color: black;
|
||||
border: 2px solid white;
|
||||
color: white;
|
||||
}
|
||||
.box_0 {
|
||||
opacity: 1.0;
|
||||
}
|
||||
.box_25 {
|
||||
opacity: 0.75;
|
||||
}
|
||||
.box_50 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.box_75 {
|
||||
opacity: 0.25;
|
||||
}
|
||||
.box_100 {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Image Transparency</h1>
|
||||
Hover over an image to make it fully opaque.<br>
|
||||
<img src="http://www.w3schools.com/css/klematis.jpg" width="150" height="113" alt="klematis" />
|
||||
<img src="http://www.w3schools.com/css/klematis2.jpg" width="150" height="113" alt="klematis" />
|
||||
|
||||
<h1>Block Transparency</h1>
|
||||
<span class="box_white box_0">White 0%</span> <span class="box_white box_25">White 25%</span> <span class="box_white box_50">White 50%</span> <span class="box_white box_75">White 75%</span> <span class="box_white box_100">White 100%</span>
|
||||
<br>
|
||||
<span class="box_black box_0">Black 0%</span> <span class="box_black box_25">Black 25%</span> <span class="box_black box_50">Black 50%</span> <span class="box_black box_75">Black 75%</span> <span class="box_black box_100">Black 100%</span>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,182 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.ui;
|
||||
|
||||
import org.cef.OS;
|
||||
import org.cef.browser.CefBrowser;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ControlPanel extends JPanel {
|
||||
private final JButton backButton_;
|
||||
private final JButton forwardButton_;
|
||||
private final JButton reloadButton_;
|
||||
private final JTextField address_field_;
|
||||
private final JLabel zoom_label_;
|
||||
private double zoomLevel_ = 0;
|
||||
private final CefBrowser browser_;
|
||||
|
||||
public ControlPanel(CefBrowser browser) {
|
||||
assert browser != null;
|
||||
browser_ = browser;
|
||||
|
||||
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||
|
||||
add(Box.createHorizontalStrut(5));
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
backButton_ = new JButton("Back");
|
||||
backButton_.setFocusable(false);
|
||||
backButton_.setAlignmentX(LEFT_ALIGNMENT);
|
||||
backButton_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.goBack();
|
||||
}
|
||||
});
|
||||
add(backButton_);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
forwardButton_ = new JButton("Forward");
|
||||
forwardButton_.setFocusable(false);
|
||||
forwardButton_.setAlignmentX(LEFT_ALIGNMENT);
|
||||
forwardButton_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.goForward();
|
||||
}
|
||||
});
|
||||
add(forwardButton_);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
reloadButton_ = new JButton("Reload");
|
||||
reloadButton_.setFocusable(false);
|
||||
reloadButton_.setAlignmentX(LEFT_ALIGNMENT);
|
||||
reloadButton_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (reloadButton_.getText().equalsIgnoreCase("reload")) {
|
||||
int mask = OS.isMacintosh() ? ActionEvent.META_MASK : ActionEvent.CTRL_MASK;
|
||||
if ((e.getModifiers() & mask) != 0) {
|
||||
System.out.println("Reloading - ignoring cached values");
|
||||
browser_.reloadIgnoreCache();
|
||||
} else {
|
||||
System.out.println("Reloading - using cached values");
|
||||
browser_.reload();
|
||||
}
|
||||
} else {
|
||||
browser_.stopLoad();
|
||||
}
|
||||
}
|
||||
});
|
||||
add(reloadButton_);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
JLabel addressLabel = new JLabel("Address:");
|
||||
addressLabel.setAlignmentX(LEFT_ALIGNMENT);
|
||||
add(addressLabel);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
address_field_ = new JTextField(100);
|
||||
address_field_.setAlignmentX(LEFT_ALIGNMENT);
|
||||
address_field_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.loadURL(getAddress());
|
||||
}
|
||||
});
|
||||
add(address_field_);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
JButton goButton = new JButton("Go");
|
||||
goButton.setFocusable(false);
|
||||
goButton.setAlignmentX(LEFT_ALIGNMENT);
|
||||
goButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.loadURL(getAddress());
|
||||
}
|
||||
});
|
||||
add(goButton);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
JButton minusButton = new JButton("-");
|
||||
minusButton.setFocusable(false);
|
||||
minusButton.setAlignmentX(CENTER_ALIGNMENT);
|
||||
minusButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.setZoomLevel(--zoomLevel_);
|
||||
zoom_label_.setText(new Double(zoomLevel_).toString());
|
||||
}
|
||||
});
|
||||
add(minusButton);
|
||||
|
||||
zoom_label_ = new JLabel("0.0");
|
||||
add(zoom_label_);
|
||||
|
||||
JButton plusButton = new JButton("+");
|
||||
plusButton.setFocusable(false);
|
||||
plusButton.setAlignmentX(CENTER_ALIGNMENT);
|
||||
plusButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.setZoomLevel(++zoomLevel_);
|
||||
zoom_label_.setText(new Double(zoomLevel_).toString());
|
||||
}
|
||||
});
|
||||
add(plusButton);
|
||||
}
|
||||
|
||||
public void update(
|
||||
CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) {
|
||||
if (browser == browser_) {
|
||||
backButton_.setEnabled(canGoBack);
|
||||
forwardButton_.setEnabled(canGoForward);
|
||||
reloadButton_.setText(isLoading ? "Abort" : "Reload");
|
||||
}
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
String address = address_field_.getText();
|
||||
// If the URI format is unknown "new URI" will throw an
|
||||
// exception. In this case we interpret the value of the
|
||||
// address field as search request. Therefore we simply add
|
||||
// the "search" scheme.
|
||||
try {
|
||||
address = address.replaceAll(" ", "%20");
|
||||
URI test = new URI(address);
|
||||
if (test.getScheme() != null) return address;
|
||||
if (test.getHost() != null && test.getPath() != null) return address;
|
||||
String specific = test.getSchemeSpecificPart();
|
||||
if (specific.indexOf('.') == -1)
|
||||
throw new URISyntaxException(specific, "No dot inside domain");
|
||||
} catch (URISyntaxException e1) {
|
||||
address = "search://" + address;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(CefBrowser browser, String address) {
|
||||
if (browser == browser_) address_field_.setText(address);
|
||||
}
|
||||
|
||||
public JTextField getAddressField() {
|
||||
return address_field_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,601 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.ui;
|
||||
|
||||
import org.cef.OS;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefDevToolsClient;
|
||||
import org.cef.callback.CefPdfPrintCallback;
|
||||
import org.cef.callback.CefRunFileDialogCallback;
|
||||
import org.cef.callback.CefStringVisitor;
|
||||
import org.cef.handler.CefDialogHandler.FileDialogMode;
|
||||
import org.cef.misc.CefPdfPrintSettings;
|
||||
import org.cef.network.CefCookieManager;
|
||||
import org.cef.network.CefRequest;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import tests.detailed.BrowserFrame;
|
||||
import tests.detailed.MainFrame;
|
||||
import tests.detailed.dialog.CookieManagerDialog;
|
||||
import tests.detailed.dialog.DownloadDialog;
|
||||
import tests.detailed.dialog.SearchDialog;
|
||||
import tests.detailed.dialog.ShowTextDialog;
|
||||
import tests.detailed.dialog.UrlRequestDialog;
|
||||
import tests.detailed.util.DataUri;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class MenuBar extends JMenuBar {
|
||||
class SaveAs implements CefStringVisitor {
|
||||
private final PrintWriter fileWriter_;
|
||||
|
||||
public SaveAs(String fName) throws FileNotFoundException, UnsupportedEncodingException {
|
||||
fileWriter_ = new PrintWriter(fName, "UTF-8");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String string) {
|
||||
fileWriter_.write(string);
|
||||
fileWriter_.close();
|
||||
}
|
||||
}
|
||||
|
||||
private final MainFrame owner_;
|
||||
private final CefBrowser browser_;
|
||||
private String last_selected_file_ = "";
|
||||
private final JMenu bookmarkMenu_;
|
||||
private final ControlPanel control_pane_;
|
||||
private final DownloadDialog downloadDialog_;
|
||||
private final CefCookieManager cookieManager_;
|
||||
private boolean reparentPending_ = false;
|
||||
private CefDevToolsClient devToolsClient_;
|
||||
|
||||
public MenuBar(MainFrame owner, CefBrowser browser, ControlPanel control_pane,
|
||||
DownloadDialog downloadDialog, CefCookieManager cookieManager) {
|
||||
owner_ = owner;
|
||||
browser_ = browser;
|
||||
control_pane_ = control_pane;
|
||||
downloadDialog_ = downloadDialog;
|
||||
cookieManager_ = cookieManager;
|
||||
|
||||
setEnabled(browser_ != null);
|
||||
|
||||
JMenu fileMenu = new JMenu("File");
|
||||
|
||||
JMenuItem openFileItem = new JMenuItem("Open file...");
|
||||
openFileItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
JFileChooser fc = new JFileChooser(new File(last_selected_file_));
|
||||
// Show open dialog; this method does not return until the dialog is closed.
|
||||
fc.showOpenDialog(owner_);
|
||||
File selectedFile = fc.getSelectedFile();
|
||||
if (selectedFile != null) {
|
||||
last_selected_file_ = selectedFile.getAbsolutePath();
|
||||
browser_.loadURL("file:///" + selectedFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
});
|
||||
fileMenu.add(openFileItem);
|
||||
|
||||
JMenuItem openFileDialog = new JMenuItem("Save as...");
|
||||
openFileDialog.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CefRunFileDialogCallback callback = new CefRunFileDialogCallback() {
|
||||
@Override
|
||||
public void onFileDialogDismissed(Vector<String> filePaths) {
|
||||
if (!filePaths.isEmpty()) {
|
||||
try {
|
||||
SaveAs saveContent = new SaveAs(filePaths.get(0));
|
||||
browser_.getSource(saveContent);
|
||||
} catch (FileNotFoundException | UnsupportedEncodingException e) {
|
||||
browser_.executeJavaScript("alert(\"Can't save file\");",
|
||||
control_pane_.getAddress(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
browser_.runFileDialog(FileDialogMode.FILE_DIALOG_SAVE, owner_.getTitle(),
|
||||
"index.html", null, 0, callback);
|
||||
}
|
||||
});
|
||||
fileMenu.add(openFileDialog);
|
||||
|
||||
JMenuItem printItem = new JMenuItem("Print...");
|
||||
printItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.print();
|
||||
}
|
||||
});
|
||||
fileMenu.add(printItem);
|
||||
|
||||
JMenuItem printToPdfItem = new JMenuItem("Print to PDF");
|
||||
printToPdfItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.showSaveDialog(owner_);
|
||||
File selectedFile = fc.getSelectedFile();
|
||||
if (selectedFile != null) {
|
||||
CefPdfPrintSettings pdfSettings = new CefPdfPrintSettings();
|
||||
pdfSettings.display_header_footer = true;
|
||||
// letter page size
|
||||
pdfSettings.paper_width = 8.5;
|
||||
pdfSettings.paper_height = 11;
|
||||
browser.printToPDF(
|
||||
selectedFile.getAbsolutePath(), pdfSettings, new CefPdfPrintCallback() {
|
||||
@Override
|
||||
public void onPdfPrintFinished(String path, boolean ok) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ok) {
|
||||
JOptionPane.showMessageDialog(owner_,
|
||||
"PDF saved to " + path, "Success",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(owner_, "PDF failed",
|
||||
"Failed", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
fileMenu.add(printToPdfItem);
|
||||
|
||||
JMenuItem searchItem = new JMenuItem("Search...");
|
||||
searchItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new SearchDialog(owner_, browser_).setVisible(true);
|
||||
}
|
||||
});
|
||||
fileMenu.add(searchItem);
|
||||
|
||||
fileMenu.addSeparator();
|
||||
|
||||
JMenuItem viewSource = new JMenuItem("View source");
|
||||
viewSource.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.viewSource();
|
||||
}
|
||||
});
|
||||
fileMenu.add(viewSource);
|
||||
|
||||
JMenuItem getSource = new JMenuItem("Get source...");
|
||||
getSource.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ShowTextDialog visitor = new ShowTextDialog(
|
||||
owner_, "Source of \"" + control_pane_.getAddress() + "\"");
|
||||
browser_.getSource(visitor);
|
||||
}
|
||||
});
|
||||
fileMenu.add(getSource);
|
||||
|
||||
JMenuItem getText = new JMenuItem("Get text...");
|
||||
getText.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ShowTextDialog visitor = new ShowTextDialog(
|
||||
owner_, "Content of \"" + control_pane_.getAddress() + "\"");
|
||||
browser_.getText(visitor);
|
||||
}
|
||||
});
|
||||
fileMenu.add(getText);
|
||||
|
||||
fileMenu.addSeparator();
|
||||
|
||||
JMenuItem showDownloads = new JMenuItem("Show Downloads");
|
||||
showDownloads.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
downloadDialog_.setVisible(true);
|
||||
}
|
||||
});
|
||||
fileMenu.add(showDownloads);
|
||||
|
||||
JMenuItem showCookies = new JMenuItem("Show Cookies");
|
||||
showCookies.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CookieManagerDialog cookieManager =
|
||||
new CookieManagerDialog(owner_, "Cookie Manager", cookieManager_);
|
||||
cookieManager.setVisible(true);
|
||||
}
|
||||
});
|
||||
fileMenu.add(showCookies);
|
||||
|
||||
fileMenu.addSeparator();
|
||||
|
||||
JMenuItem exitItem = new JMenuItem("Exit");
|
||||
exitItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
owner_.dispatchEvent(new WindowEvent(owner_, WindowEvent.WINDOW_CLOSING));
|
||||
}
|
||||
});
|
||||
fileMenu.add(exitItem);
|
||||
|
||||
bookmarkMenu_ = new JMenu("Bookmarks");
|
||||
|
||||
JMenuItem addBookmarkItem = new JMenuItem("Add bookmark");
|
||||
addBookmarkItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addBookmark(owner_.getTitle(), control_pane_.getAddress());
|
||||
}
|
||||
});
|
||||
bookmarkMenu_.add(addBookmarkItem);
|
||||
bookmarkMenu_.addSeparator();
|
||||
|
||||
JMenu testMenu = new JMenu("Tests");
|
||||
|
||||
JMenuItem testJSItem = new JMenuItem("JavaScript alert");
|
||||
testJSItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.executeJavaScript("alert('Hello World');", control_pane_.getAddress(), 1);
|
||||
}
|
||||
});
|
||||
testMenu.add(testJSItem);
|
||||
|
||||
JMenuItem jsAlertItem = new JMenuItem("JavaScript alert (will be suppressed)");
|
||||
jsAlertItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.executeJavaScript("alert('Never displayed');", "http://dontshow.me", 1);
|
||||
}
|
||||
});
|
||||
testMenu.add(jsAlertItem);
|
||||
|
||||
JMenuItem testShowText = new JMenuItem("Show Text");
|
||||
testShowText.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.loadURL(DataUri.create(
|
||||
"text/html", "<html><body><h1>Hello World</h1></body></html>"));
|
||||
}
|
||||
});
|
||||
testMenu.add(testShowText);
|
||||
|
||||
JMenuItem showForm = new JMenuItem("RequestHandler Test");
|
||||
showForm.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String form = "<html><head><title>RequestHandler test</title></head>";
|
||||
form += "<body><h1>RequestHandler test</h1>";
|
||||
form += "<form action=\"http://www.google.com/\" method=\"post\">";
|
||||
form += "<input type=\"text\" name=\"searchFor\"/>";
|
||||
form += "<input type=\"submit\"/><br/>";
|
||||
form += "<input type=\"checkbox\" name=\"sendAsGet\"> Use GET instead of POST";
|
||||
form += "<p>This form tries to send the content of the text field as HTTP-POST request to http://www.google.com.</p>";
|
||||
form += "<h2>Testcase 1</h2>";
|
||||
form += "Try to enter the word <b>\"ignore\"</b> into the text field and press \"submit\".<br />";
|
||||
form += "The request will be rejected by the application.";
|
||||
form += "<p>See implementation of <u>tests.RequestHandler.onBeforeBrowse(CefBrowser, CefRequest, boolean)</u> for details</p>";
|
||||
form += "<h2>Testcase 2</h2>";
|
||||
form += "Due Google doesn't allow the POST method, the server replies with a 405 error.</br>";
|
||||
form += "If you activate the checkbox \"Use GET instead of POST\", the application will change the POST request into a GET request.";
|
||||
form += "<p>See implementation of <u>tests.RequestHandler.onBeforeResourceLoad(CefBrowser, CefRequest)</u> for details</p>";
|
||||
form += "</form>";
|
||||
form += "</body></html>";
|
||||
browser_.loadURL(DataUri.create("text/html", form));
|
||||
}
|
||||
});
|
||||
testMenu.add(showForm);
|
||||
|
||||
JMenuItem httpRequest = new JMenuItem("Manual HTTP request");
|
||||
httpRequest.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String searchFor = JOptionPane.showInputDialog(owner_, "Search on google:");
|
||||
if (searchFor != null && !searchFor.isEmpty()) {
|
||||
CefRequest myRequest = CefRequest.create();
|
||||
myRequest.setMethod("GET");
|
||||
myRequest.setURL("http://www.google.com/#q=" + searchFor);
|
||||
myRequest.setFirstPartyForCookies("http://www.google.com/#q=" + searchFor);
|
||||
browser_.loadRequest(myRequest);
|
||||
}
|
||||
}
|
||||
});
|
||||
testMenu.add(httpRequest);
|
||||
|
||||
JMenuItem showInfo = new JMenuItem("Show Info");
|
||||
showInfo.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String info = "<html><head><title>Browser status</title></head>";
|
||||
info += "<body><h1>Browser status</h1><table border=\"0\">";
|
||||
info += "<tr><td>CanGoBack</td><td>" + browser_.canGoBack() + "</td></tr>";
|
||||
info += "<tr><td>CanGoForward</td><td>" + browser_.canGoForward() + "</td></tr>";
|
||||
info += "<tr><td>IsLoading</td><td>" + browser_.isLoading() + "</td></tr>";
|
||||
info += "<tr><td>isPopup</td><td>" + browser_.isPopup() + "</td></tr>";
|
||||
info += "<tr><td>hasDocument</td><td>" + browser_.hasDocument() + "</td></tr>";
|
||||
info += "<tr><td>Url</td><td>" + browser_.getURL() + "</td></tr>";
|
||||
info += "<tr><td>Zoom-Level</td><td>" + browser_.getZoomLevel() + "</td></tr>";
|
||||
info += "</table></body></html>";
|
||||
String js = "var x=window.open(); x.document.open(); x.document.write('" + info
|
||||
+ "'); x.document.close();";
|
||||
browser_.executeJavaScript(js, "", 0);
|
||||
}
|
||||
});
|
||||
testMenu.add(showInfo);
|
||||
|
||||
final JMenuItem showDevTools = new JMenuItem("Show DevTools");
|
||||
showDevTools.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser.openDevTools();
|
||||
}
|
||||
});
|
||||
testMenu.add(showDevTools);
|
||||
|
||||
JMenu devToolsProtocolMenu = new JMenu("DevTools Protocol");
|
||||
JMenuItem autoDarkMode = devToolsProtocolMenu.add(new JCheckBoxMenuItem("Auto Dark Mode"));
|
||||
autoDarkMode.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Toggle the auto dark mode override
|
||||
String params = String.format("{ \"enabled\": %s }", autoDarkMode.isSelected());
|
||||
executeDevToolsMethod("Emulation.setAutoDarkModeOverride", params);
|
||||
}
|
||||
});
|
||||
JMenuItem checkContrast = devToolsProtocolMenu.add(new JMenuItem("Check Contrast"));
|
||||
checkContrast.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Check contrast, which usually triggers a series of Audits.issueAdded events
|
||||
executeDevToolsMethod("Audits.checkContrast");
|
||||
}
|
||||
});
|
||||
JMenuItem enableCSS = devToolsProtocolMenu.add(new JMenuItem("Enable CSS Agent"));
|
||||
enableCSS.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Enable the CSS agent, which usually triggers a series of CSS.styleSheetAdded
|
||||
// events. We can only enable the CSS agent if the DOM agent is enabled first, so we
|
||||
// need to chain the two commands.
|
||||
executeDevToolsMethod("DOM.enable")
|
||||
.thenCompose(unused -> executeDevToolsMethod("CSS.enable"));
|
||||
}
|
||||
});
|
||||
testMenu.add(devToolsProtocolMenu);
|
||||
|
||||
JMenuItem testURLRequest = new JMenuItem("URL Request");
|
||||
testURLRequest.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
UrlRequestDialog dlg = new UrlRequestDialog(owner_, "URL Request Test");
|
||||
dlg.setVisible(true);
|
||||
}
|
||||
});
|
||||
testMenu.add(testURLRequest);
|
||||
|
||||
JMenuItem reparent = new JMenuItem("Reparent");
|
||||
reparent.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final BrowserFrame newFrame = new BrowserFrame("New Window");
|
||||
newFrame.setLayout(new BorderLayout());
|
||||
final JButton reparentButton = new JButton("Reparent <");
|
||||
reparentButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (reparentPending_) {
|
||||
return;
|
||||
}
|
||||
reparentPending_ = true;
|
||||
|
||||
if (reparentButton.getText().equals("Reparent <")) {
|
||||
owner_.removeBrowser(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
newFrame.add(browser_.getUIComponent(), BorderLayout.CENTER);
|
||||
newFrame.setBrowser(browser_);
|
||||
reparentButton.setText("Reparent >");
|
||||
reparentPending_ = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
newFrame.removeBrowser(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JRootPane rootPane = (JRootPane) owner_.getComponent(0);
|
||||
Container container = rootPane.getContentPane();
|
||||
JPanel panel = (JPanel) container.getComponent(0);
|
||||
panel.add(browser_.getUIComponent());
|
||||
owner_.setBrowser(browser_);
|
||||
owner_.revalidate();
|
||||
reparentButton.setText("Reparent <");
|
||||
reparentPending_ = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
newFrame.add(reparentButton, BorderLayout.NORTH);
|
||||
newFrame.setSize(400, 400);
|
||||
newFrame.setVisible(true);
|
||||
}
|
||||
});
|
||||
testMenu.add(reparent);
|
||||
|
||||
JMenuItem newwindow = new JMenuItem("New window");
|
||||
newwindow.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final MainFrame frame = new MainFrame(OS.isLinux(), false, false, 0, null);
|
||||
frame.setSize(800, 600);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
testMenu.add(newwindow);
|
||||
|
||||
JMenuItem screenshotSync = new JMenuItem("Screenshot (on AWT thread, native res)");
|
||||
screenshotSync.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
long start = System.nanoTime();
|
||||
CompletableFuture<BufferedImage> shot = browser.createScreenshot(true);
|
||||
System.out.println("Took screenshot from the AWT event thread in "
|
||||
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " msecs");
|
||||
try {
|
||||
displayScreenshot(shot.get());
|
||||
} catch (InterruptedException | ExecutionException exc) {
|
||||
// cannot happen, future is already resolved in this case
|
||||
}
|
||||
}
|
||||
});
|
||||
screenshotSync.setEnabled(owner.isOsrEnabled());
|
||||
testMenu.add(screenshotSync);
|
||||
|
||||
JMenuItem screenshotSyncScaled = new JMenuItem("Screenshot (on AWT thread, scaled)");
|
||||
screenshotSyncScaled.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
long start = System.nanoTime();
|
||||
CompletableFuture<BufferedImage> shot = browser.createScreenshot(false);
|
||||
System.out.println("Took screenshot from the AWT event thread in "
|
||||
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " msecs");
|
||||
try {
|
||||
displayScreenshot(shot.get());
|
||||
} catch (InterruptedException | ExecutionException exc) {
|
||||
// cannot happen, future is already resolved in this case
|
||||
}
|
||||
}
|
||||
});
|
||||
screenshotSyncScaled.setEnabled(owner.isOsrEnabled());
|
||||
testMenu.add(screenshotSyncScaled);
|
||||
|
||||
JMenuItem screenshotAsync = new JMenuItem("Screenshot (from other thread, scaled)");
|
||||
screenshotAsync.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
long start = System.nanoTime();
|
||||
CompletableFuture<BufferedImage> shot = browser.createScreenshot(false);
|
||||
shot.thenAccept((image) -> {
|
||||
System.out.println("Took screenshot asynchronously in "
|
||||
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) + " msecs");
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
displayScreenshot(image);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
screenshotAsync.setEnabled(owner.isOsrEnabled());
|
||||
testMenu.add(screenshotAsync);
|
||||
|
||||
add(fileMenu);
|
||||
add(bookmarkMenu_);
|
||||
add(testMenu);
|
||||
}
|
||||
|
||||
public void addBookmark(String name, String URL) {
|
||||
if (bookmarkMenu_ == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test if the bookmark already exists. If yes, update URL
|
||||
Component[] entries = bookmarkMenu_.getMenuComponents();
|
||||
for (Component itemEntry : entries) {
|
||||
if (!(itemEntry instanceof JMenuItem)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JMenuItem item = (JMenuItem) itemEntry;
|
||||
if (item.getText().equals(name)) {
|
||||
item.setActionCommand(URL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JMenuItem menuItem = new JMenuItem(name);
|
||||
menuItem.setActionCommand(URL);
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.loadURL(e.getActionCommand());
|
||||
}
|
||||
});
|
||||
bookmarkMenu_.add(menuItem);
|
||||
validate();
|
||||
}
|
||||
|
||||
private void displayScreenshot(BufferedImage aScreenshot) {
|
||||
JFrame frame = new JFrame("Screenshot");
|
||||
ImageIcon image = new ImageIcon();
|
||||
image.setImage(aScreenshot);
|
||||
frame.setLayout(new FlowLayout());
|
||||
JLabel label = new JLabel(image);
|
||||
label.setPreferredSize(new Dimension(aScreenshot.getWidth(), aScreenshot.getHeight()));
|
||||
frame.add(label);
|
||||
frame.setVisible(true);
|
||||
frame.pack();
|
||||
}
|
||||
|
||||
private CompletableFuture<String> executeDevToolsMethod(String methodName) {
|
||||
return executeDevToolsMethod(methodName, null);
|
||||
}
|
||||
|
||||
private CompletableFuture<String> executeDevToolsMethod(
|
||||
String methodName, String paramsAsJson) {
|
||||
if (devToolsClient_ == null) {
|
||||
devToolsClient_ = browser_.getDevToolsClient();
|
||||
devToolsClient_.addEventListener(
|
||||
(method, json) -> System.out.println("CDP event " + method + ": " + json));
|
||||
}
|
||||
|
||||
return devToolsClient_.executeDevToolsMethod(methodName, paramsAsJson)
|
||||
.handle((error, json) -> {
|
||||
System.out.println(
|
||||
"CDP result of " + methodName + ": " + (error != null ? error : json));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public void addBookmarkSeparator() {
|
||||
bookmarkMenu_.addSeparator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.ui;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class StatusPanel extends JPanel {
|
||||
private final JProgressBar progressBar_;
|
||||
private final JLabel status_field_;
|
||||
|
||||
public StatusPanel() {
|
||||
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||
|
||||
add(Box.createHorizontalStrut(5));
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
progressBar_ = new JProgressBar();
|
||||
Dimension progressBarSize = progressBar_.getMaximumSize();
|
||||
progressBarSize.width = 100;
|
||||
progressBar_.setMinimumSize(progressBarSize);
|
||||
progressBar_.setMaximumSize(progressBarSize);
|
||||
add(progressBar_);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
|
||||
status_field_ = new JLabel("Info");
|
||||
status_field_.setAlignmentX(LEFT_ALIGNMENT);
|
||||
add(status_field_);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
add(Box.createVerticalStrut(21));
|
||||
}
|
||||
|
||||
public void setIsInProgress(boolean inProgress) {
|
||||
progressBar_.setIndeterminate(inProgress);
|
||||
}
|
||||
|
||||
public void setStatusText(String text) {
|
||||
status_field_.setText(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.detailed.util;
|
||||
|
||||
/**
|
||||
* Utility class for creating data: URIs that can be passed to CefBrowser.loadURL.
|
||||
*/
|
||||
public class DataUri {
|
||||
public static String create(String mimeType, String contents) {
|
||||
return "data:" + mimeType + ";base64,"
|
||||
+ java.util.Base64.getEncoder().encodeToString(contents.getBytes());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.handler.CefDisplayHandlerAdapter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
// Test the DisplayHandler implementation.
|
||||
@ExtendWith(TestSetupExtension.class)
|
||||
class DisplayHandlerTest {
|
||||
private final String testUrl_ = "http://test.com/test.html";
|
||||
private final String testContent_ =
|
||||
"<html><head><title>Test Title</title></head><body>Test!</body></html>";
|
||||
|
||||
private boolean gotCallback_ = false;
|
||||
|
||||
@Test
|
||||
void onTitleChange() {
|
||||
TestFrame frame = new TestFrame() {
|
||||
@Override
|
||||
protected void setupTest() {
|
||||
client_.addDisplayHandler(new CefDisplayHandlerAdapter() {
|
||||
@Override
|
||||
public void onTitleChange(CefBrowser browser, String title) {
|
||||
assertFalse(gotCallback_);
|
||||
gotCallback_ = true;
|
||||
assertEquals("Test Title", title);
|
||||
terminateTest();
|
||||
}
|
||||
});
|
||||
|
||||
addResource(testUrl_, testContent_, "text/html");
|
||||
|
||||
createBrowser(testUrl_);
|
||||
|
||||
super.setupTest();
|
||||
}
|
||||
};
|
||||
|
||||
frame.awaitCompletion();
|
||||
|
||||
assertTrue(gotCallback_);
|
||||
}
|
||||
|
||||
@Test
|
||||
void onAddressChange() {
|
||||
TestFrame frame = new TestFrame() {
|
||||
@Override
|
||||
protected void setupTest() {
|
||||
client_.addDisplayHandler(new CefDisplayHandlerAdapter() {
|
||||
@Override
|
||||
public void onAddressChange(CefBrowser browser, CefFrame frame, String url) {
|
||||
assertFalse(gotCallback_);
|
||||
gotCallback_ = true;
|
||||
assertEquals(url, testUrl_);
|
||||
terminateTest();
|
||||
}
|
||||
});
|
||||
|
||||
addResource(testUrl_, testContent_, "text/html");
|
||||
|
||||
createBrowser(testUrl_);
|
||||
|
||||
super.setupTest();
|
||||
}
|
||||
};
|
||||
|
||||
frame.awaitCompletion();
|
||||
|
||||
assertTrue(gotCallback_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.cef.callback.CefDragData;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
// Test the TestFrame implementation.
|
||||
@ExtendWith(TestSetupExtension.class)
|
||||
class DragDataTest {
|
||||
@Test
|
||||
void createEmpty() {
|
||||
CefDragData dragData = CefDragData.create();
|
||||
assertNotNull(dragData);
|
||||
assertFalse(dragData.isReadOnly());
|
||||
|
||||
assertFalse(dragData.isLink());
|
||||
assertFalse(dragData.isFile());
|
||||
assertTrue(dragData.isFragment()); // Default state.
|
||||
|
||||
assertEquals("", dragData.getLinkURL());
|
||||
assertEquals("", dragData.getLinkTitle());
|
||||
assertEquals("", dragData.getLinkMetadata());
|
||||
assertEquals("", dragData.getFragmentText());
|
||||
assertEquals("", dragData.getFragmentHtml());
|
||||
assertEquals("", dragData.getFragmentBaseURL());
|
||||
assertEquals(0, dragData.getFileContents(null));
|
||||
assertEquals("", dragData.getFileName());
|
||||
assertFalse(dragData.getFileNames(null));
|
||||
|
||||
// Explicit cleanup to avoid memory leaks.
|
||||
dragData.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createLink() {
|
||||
CefDragData dragData = CefDragData.create();
|
||||
assertNotNull(dragData);
|
||||
assertFalse(dragData.isReadOnly());
|
||||
|
||||
final String linkURL = "http://test.com/test.html";
|
||||
dragData.setLinkURL(linkURL);
|
||||
assertEquals(linkURL, dragData.getLinkURL());
|
||||
|
||||
final String linkTitle = "Test Title";
|
||||
dragData.setLinkTitle(linkTitle);
|
||||
assertEquals(linkTitle, dragData.getLinkTitle());
|
||||
|
||||
final String linkMetadata = "something";
|
||||
dragData.setLinkMetadata(linkMetadata);
|
||||
assertEquals(linkMetadata, dragData.getLinkMetadata());
|
||||
|
||||
assertTrue(dragData.isLink());
|
||||
assertFalse(dragData.isFile());
|
||||
assertFalse(dragData.isFragment());
|
||||
|
||||
// Explicit cleanup to avoid memory leaks.
|
||||
dragData.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createFile() {
|
||||
CefDragData dragData = CefDragData.create();
|
||||
assertNotNull(dragData);
|
||||
assertFalse(dragData.isReadOnly());
|
||||
|
||||
final String path1 = "/path/to/file1.txt";
|
||||
final String path2 = "/path/to/file2.txt";
|
||||
|
||||
dragData.addFile(path1, "File 1");
|
||||
dragData.addFile(path2, "File 2");
|
||||
|
||||
Vector<String> fileNames = new Vector<>();
|
||||
assertTrue(dragData.getFileNames(fileNames));
|
||||
|
||||
assertEquals(2, fileNames.size());
|
||||
assertEquals(path1, fileNames.get(0));
|
||||
assertEquals(path2, fileNames.get(1));
|
||||
|
||||
assertFalse(dragData.isLink());
|
||||
assertTrue(dragData.isFile());
|
||||
assertFalse(dragData.isFragment());
|
||||
|
||||
// Explicit cleanup to avoid memory leaks.
|
||||
dragData.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createFragment() {
|
||||
CefDragData dragData = CefDragData.create();
|
||||
assertNotNull(dragData);
|
||||
assertFalse(dragData.isReadOnly());
|
||||
|
||||
final String fragmentText = "something";
|
||||
dragData.setFragmentText(fragmentText);
|
||||
assertEquals(fragmentText, dragData.getFragmentText());
|
||||
|
||||
final String fragmentHtml = "<span>something</span>";
|
||||
dragData.setFragmentHtml(fragmentHtml);
|
||||
assertEquals(fragmentHtml, dragData.getFragmentHtml());
|
||||
|
||||
final String fragmentBaseURL = "http://test.com/test.html";
|
||||
dragData.setFragmentBaseURL(fragmentBaseURL);
|
||||
assertEquals(fragmentBaseURL, dragData.getFragmentBaseURL());
|
||||
|
||||
assertFalse(dragData.isLink());
|
||||
assertFalse(dragData.isFile());
|
||||
assertTrue(dragData.isFragment());
|
||||
|
||||
// Explicit cleanup to avoid memory leaks.
|
||||
dragData.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void cloneObject() {
|
||||
CefDragData dragData = CefDragData.create();
|
||||
assertNotNull(dragData);
|
||||
assertFalse(dragData.isReadOnly());
|
||||
|
||||
final String fragmentText = "something";
|
||||
final String fragmentBaseURL = "http://test.com/test.html";
|
||||
dragData.setFragmentText(fragmentText);
|
||||
dragData.setFragmentBaseURL(fragmentBaseURL);
|
||||
|
||||
CefDragData dragData2 = dragData.clone();
|
||||
assertFalse(dragData2.isReadOnly());
|
||||
assertEquals(fragmentText, dragData2.getFragmentText());
|
||||
assertEquals(fragmentBaseURL, dragData2.getFragmentBaseURL());
|
||||
|
||||
assertFalse(dragData2.isLink());
|
||||
assertFalse(dragData2.isFile());
|
||||
assertTrue(dragData2.isFragment());
|
||||
|
||||
// Explicit cleanup to avoid memory leaks.
|
||||
dragData.dispose();
|
||||
dragData2.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void disposeObject() {
|
||||
CefDragData dragData = CefDragData.create();
|
||||
assertNotNull(dragData);
|
||||
assertFalse(dragData.isReadOnly());
|
||||
|
||||
final String fragmentText = "something";
|
||||
dragData.setFragmentText(fragmentText);
|
||||
assertEquals(fragmentText, dragData.getFragmentText());
|
||||
|
||||
// Explicit cleanup to avoid memory leaks.
|
||||
// After dispose() the Java object is no longer backed by a CEF object.
|
||||
dragData.dispose();
|
||||
|
||||
assertEquals(null, dragData.getFragmentText());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
import static tests.junittests.TestSetupContext.debugPrint;
|
||||
|
||||
import org.cef.CefApp;
|
||||
import org.cef.CefClient;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.callback.CefAuthCallback;
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefCookieAccessFilter;
|
||||
import org.cef.handler.CefLifeSpanHandler;
|
||||
import org.cef.handler.CefLoadHandler;
|
||||
import org.cef.handler.CefRequestHandler;
|
||||
import org.cef.handler.CefResourceHandler;
|
||||
import org.cef.handler.CefResourceRequestHandler;
|
||||
import org.cef.misc.BoolRef;
|
||||
import org.cef.misc.StringRef;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefRequest.TransitionType;
|
||||
import org.cef.network.CefResponse;
|
||||
import org.cef.network.CefURLRequest;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
// Base class for browsers that run tests.
|
||||
class TestFrame extends JFrame implements CefLifeSpanHandler, CefLoadHandler, CefRequestHandler,
|
||||
CefResourceRequestHandler {
|
||||
private static final long serialVersionUID = -5570653778104813836L;
|
||||
private boolean isClosed_ = false;
|
||||
private CountDownLatch countdown_ = new CountDownLatch(1);
|
||||
|
||||
// Resources that have been populated for the test.
|
||||
private class ResourceContent {
|
||||
String content;
|
||||
String mimeType;
|
||||
HashMap<String, String> headerMap;
|
||||
}
|
||||
private HashMap<String, ResourceContent> resourceMap_ = null;
|
||||
|
||||
protected final CefClient client_;
|
||||
protected CefBrowser browser_ = null;
|
||||
|
||||
TestFrame() {
|
||||
client_ = CefApp.getInstance().createClient();
|
||||
assertNotNull(client_);
|
||||
|
||||
// Browser window closing works as follows:
|
||||
// 1. Sending WindowEvent.WINDOW_CLOSING calls WindowAdapter.windowClosing.
|
||||
// 2. WindowAdapter.windowClosing calls CefBrowser.close(false).
|
||||
// 3. CEF calls CefLifeSpanHandler.doClose() which calls CefBrowser.doClose()
|
||||
// which returns true (canceling the close).
|
||||
// 4. CefBrowser.doClose() triggers another call to WindowAdapter.windowClosing.
|
||||
// 5. WindowAdapter.windowClosing calls CefBrowser.close(true).
|
||||
// 6. For windowed browsers CEF destroys the native window handle. For OSR
|
||||
// browsers CEF calls CefLifeSpanHandler.doClose() which calls
|
||||
// CefBrowser.doClose() again which returns false (allowing the close).
|
||||
// 7. CEF calls CefLifeSpanHandler.onBeforeClose and the browser is destroyed.
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
boolean isClosed = isClosed_;
|
||||
|
||||
if (isClosed) {
|
||||
// Cause browser.doClose() to return false so that OSR browsers
|
||||
// can close.
|
||||
browser_.setCloseAllowed();
|
||||
}
|
||||
|
||||
// Results in another call to this method.
|
||||
if (debugPrint())
|
||||
System.out.println("windowClosing CefBrowser.close(" + isClosed + ")");
|
||||
browser_.close(isClosed);
|
||||
if (!isClosed_) {
|
||||
isClosed_ = true;
|
||||
}
|
||||
if (isClosed) {
|
||||
// Dispose after the 2nd call to this method.
|
||||
if (debugPrint()) System.out.println("windowClosing Frame.dispose");
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
client_.addLifeSpanHandler(this);
|
||||
client_.addLoadHandler(this);
|
||||
client_.addRequestHandler(this);
|
||||
|
||||
setupTest();
|
||||
}
|
||||
|
||||
protected void createBrowser(String startURL) {
|
||||
assertNull(browser_);
|
||||
browser_ = client_.createBrowser(startURL, false /* useOSR */, false /* isTransparent */);
|
||||
assertNotNull(browser_);
|
||||
|
||||
getContentPane().add(browser_.getUIComponent(), BorderLayout.CENTER);
|
||||
pack();
|
||||
setSize(800, 600);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Override this method to perform test setup.
|
||||
protected void setupTest() {}
|
||||
|
||||
// Override this method to perform test cleanup.
|
||||
protected void cleanupTest() {
|
||||
if (debugPrint()) System.out.println("cleanupTest");
|
||||
client_.dispose();
|
||||
// Allow the test to complete.
|
||||
countdown_.countDown();
|
||||
}
|
||||
|
||||
// Call this method to terminate the test by dispatching a window close event.
|
||||
protected final void terminateTest() {
|
||||
if (debugPrint()) System.out.println("terminateTest");
|
||||
if (!isClosed_) {
|
||||
dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
|
||||
}
|
||||
}
|
||||
|
||||
// Block until the test completes.
|
||||
public final void awaitCompletion() {
|
||||
try {
|
||||
countdown_.await();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
if (debugPrint()) System.out.println("awaitCompletion returned");
|
||||
}
|
||||
|
||||
protected void addResource(String url, String content, String mimeType) {
|
||||
addResource(url, content, mimeType, null);
|
||||
}
|
||||
|
||||
// Add a resource that will be returned via getResourceHandler().
|
||||
protected void addResource(
|
||||
String url, String content, String mimeType, HashMap<String, String> headerMap) {
|
||||
if (resourceMap_ == null) resourceMap_ = new HashMap<>();
|
||||
|
||||
assertNull(resourceMap_.get(url));
|
||||
|
||||
ResourceContent rc = new ResourceContent();
|
||||
rc.content = content;
|
||||
rc.mimeType = mimeType;
|
||||
rc.headerMap = headerMap;
|
||||
|
||||
resourceMap_.put(url, rc);
|
||||
}
|
||||
|
||||
// CefLifeSpanHandler methods:
|
||||
|
||||
@Override
|
||||
public void onAfterCreated(CefBrowser browser) {
|
||||
if (debugPrint()) System.out.println("onAfterCreated id=" + browser.getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBeforePopup(
|
||||
CefBrowser browser, CefFrame frame, String target_url, String target_frame_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterParentChanged(CefBrowser browser) {}
|
||||
|
||||
@Override
|
||||
public boolean doClose(CefBrowser browser) {
|
||||
boolean result = browser.doClose();
|
||||
if (debugPrint()) {
|
||||
System.out.println(
|
||||
"doClose id=" + browser.getIdentifier() + " CefBrowser.doClose=" + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeClose(CefBrowser browser) {
|
||||
if (debugPrint()) System.out.println("onBeforeClose id=" + browser.getIdentifier());
|
||||
cleanupTest();
|
||||
}
|
||||
|
||||
// CefLoadHandler methods:
|
||||
|
||||
@Override
|
||||
public void onLoadingStateChange(
|
||||
CefBrowser browser, boolean isLoading, boolean canGoBack, boolean canGoForward) {}
|
||||
|
||||
@Override
|
||||
public void onLoadStart(CefBrowser browser, CefFrame frame, TransitionType transitionType) {}
|
||||
|
||||
@Override
|
||||
public void onLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode) {}
|
||||
|
||||
@Override
|
||||
public void onLoadError(CefBrowser browser, CefFrame frame, ErrorCode errorCode,
|
||||
String errorText, String failedUrl) {}
|
||||
|
||||
// CefRequestHandler methods:
|
||||
|
||||
@Override
|
||||
public boolean onBeforeBrowse(CefBrowser browser, CefFrame frame, CefRequest request,
|
||||
boolean user_gesture, boolean is_redirect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOpenURLFromTab(
|
||||
CefBrowser browser, CefFrame frame, String target_url, boolean user_gesture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame,
|
||||
CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator,
|
||||
BoolRef disableDefaultHandling) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy,
|
||||
String host, int port, String realm, String scheme, CefAuthCallback callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCertificateError(CefBrowser browser, CefLoadHandler.ErrorCode cert_error,
|
||||
String request_url, CefCallback callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderProcessTerminated(
|
||||
CefBrowser browser, TerminationStatus status, int error_code, String error_string) {}
|
||||
|
||||
// CefResourceRequestHandler methods:
|
||||
|
||||
@Override
|
||||
public CefCookieAccessFilter getCookieAccessFilter(
|
||||
CefBrowser browser, CefFrame frame, CefRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBeforeResourceLoad(CefBrowser browser, CefFrame frame, CefRequest request) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CefResourceHandler getResourceHandler(
|
||||
CefBrowser browser, CefFrame frame, CefRequest request) {
|
||||
if (resourceMap_ != null) {
|
||||
String url = request.getURL();
|
||||
|
||||
// Ignore the query component, if any.
|
||||
int idx = url.indexOf('?');
|
||||
if (idx > 0) url = url.substring(0, idx);
|
||||
|
||||
ResourceContent rc = resourceMap_.get(url);
|
||||
if (rc != null) {
|
||||
if (debugPrint()) System.out.println("Found resource for: " + url);
|
||||
return new TestResourceHandler(rc.content, rc.mimeType, rc.headerMap);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceRedirect(CefBrowser browser, CefFrame frame, CefRequest request,
|
||||
CefResponse response, StringRef new_url) {}
|
||||
|
||||
@Override
|
||||
public boolean onResourceResponse(
|
||||
CefBrowser browser, CefFrame frame, CefRequest request, CefResponse response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceLoadComplete(CefBrowser browser, CefFrame frame, CefRequest request,
|
||||
CefResponse response, CefURLRequest.Status status, long receivedContentLength) {}
|
||||
|
||||
@Override
|
||||
public void onProtocolExecution(
|
||||
CefBrowser browser, CefFrame frame, CefRequest request, BoolRef allowOsExecution) {}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
// Test the TestFrame implementation.
|
||||
@ExtendWith(TestSetupExtension.class)
|
||||
class TestFrameTest {
|
||||
private boolean gotSetupTest_ = false;
|
||||
private boolean gotCleanupTest_ = false;
|
||||
private boolean gotLoadingStateChange_ = false;
|
||||
|
||||
@Test
|
||||
void minimal() {
|
||||
final String testUrl = "http://test.com/test.html";
|
||||
TestFrame frame = new TestFrame() {
|
||||
@Override
|
||||
protected void setupTest() {
|
||||
assertFalse(gotSetupTest_);
|
||||
gotSetupTest_ = true;
|
||||
|
||||
addResource(testUrl, "<html><body>Test!</body></html>", "text/html");
|
||||
|
||||
createBrowser(testUrl);
|
||||
|
||||
super.setupTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanupTest() {
|
||||
assertFalse(gotCleanupTest_);
|
||||
gotCleanupTest_ = true;
|
||||
|
||||
super.cleanupTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
|
||||
boolean canGoBack, boolean canGoForward) {
|
||||
if (!isLoading) {
|
||||
assertFalse(gotLoadingStateChange_);
|
||||
gotLoadingStateChange_ = true;
|
||||
terminateTest();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
frame.awaitCompletion();
|
||||
|
||||
assertTrue(gotSetupTest_);
|
||||
assertTrue(gotLoadingStateChange_);
|
||||
assertTrue(gotCleanupTest_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefResourceHandlerAdapter;
|
||||
import org.cef.misc.IntRef;
|
||||
import org.cef.misc.StringRef;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefResponse;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
|
||||
class TestResourceHandler extends CefResourceHandlerAdapter {
|
||||
private int offset_ = 0;
|
||||
private final String content_;
|
||||
private final String mimeType_;
|
||||
private final HashMap<String, String> headerMap_;
|
||||
|
||||
TestResourceHandler(String content, String mimeType, HashMap<String, String> headerMap) {
|
||||
content_ = content;
|
||||
mimeType_ = mimeType;
|
||||
headerMap_ = headerMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processRequest(CefRequest request, CefCallback callback) {
|
||||
callback.Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResponseHeaders(
|
||||
CefResponse response, IntRef response_length, StringRef redirectUrl) {
|
||||
response_length.set(content_.length());
|
||||
response.setMimeType(mimeType_);
|
||||
response.setStatus(200);
|
||||
|
||||
if (headerMap_ != null) {
|
||||
HashMap<String, String> headerMap = new HashMap<>();
|
||||
response.getHeaderMap(headerMap);
|
||||
headerMap.putAll(headerMap_);
|
||||
response.setHeaderMap(headerMap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readResponse(
|
||||
byte[] data_out, int bytes_to_read, IntRef bytes_read, CefCallback callback) {
|
||||
int length = content_.length();
|
||||
if (offset_ >= length) return false;
|
||||
|
||||
// Extract up to |bytes_to_read| bytes from |content_|.
|
||||
int endPos = offset_ + bytes_to_read;
|
||||
String dataToSend = (endPos > length) ? content_.substring(offset_)
|
||||
: content_.substring(offset_, endPos);
|
||||
|
||||
// Copy extracted bytes into |data_out| and set the read length to |bytes_read|.
|
||||
ByteBuffer result = ByteBuffer.wrap(data_out);
|
||||
result.put(dataToSend.getBytes());
|
||||
bytes_read.set(dataToSend.length());
|
||||
|
||||
offset_ = endPos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
// Stores global test setup state for access from package classes.
|
||||
class TestSetupContext {
|
||||
private static boolean debugPrint_ = false;
|
||||
|
||||
// Debug print statements may be enabled via `--config debugPrint=true`.
|
||||
static boolean debugPrint() {
|
||||
return debugPrint_;
|
||||
}
|
||||
|
||||
// Initialize from global configuration parameters.
|
||||
static void initialize(ExtensionContext context) {
|
||||
Optional<String> debugPrint = context.getConfigurationParameter("debugPrint");
|
||||
if (debugPrint.isPresent() && debugPrint.get().equalsIgnoreCase("true")) {
|
||||
debugPrint_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.junittests;
|
||||
|
||||
import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL;
|
||||
|
||||
import org.cef.CefApp;
|
||||
import org.cef.CefApp.CefAppState;
|
||||
import org.cef.CefSettings;
|
||||
import org.cef.handler.CefAppHandlerAdapter;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
// All test cases must install this extension for CEF to be properly initialized
|
||||
// and shut down.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// @ExtendWith(TestSetupExtension.class)
|
||||
// class FooTest {
|
||||
// @Test
|
||||
// void testCaseThatRequiresCEF() {}
|
||||
// }
|
||||
//
|
||||
// This code is based on https://stackoverflow.com/a/51556718.
|
||||
public class TestSetupExtension
|
||||
implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
|
||||
private static boolean initialized_ = false;
|
||||
private static CountDownLatch countdown_ = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) {
|
||||
if (!initialized_) {
|
||||
initialized_ = true;
|
||||
initialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Executed before any tests are run.
|
||||
private void initialize(ExtensionContext context) {
|
||||
TestSetupContext.initialize(context);
|
||||
|
||||
if (TestSetupContext.debugPrint()) {
|
||||
System.out.println("TestSetupExtension.initialize");
|
||||
}
|
||||
|
||||
// Register a callback hook for when the root test context is shut down.
|
||||
context.getRoot().getStore(GLOBAL).put("jcef_test_setup", this);
|
||||
|
||||
// Perform startup initialization on platforms that require it.
|
||||
if (!CefApp.startup(null)) {
|
||||
System.out.println("Startup initialization failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
|
||||
@Override
|
||||
public void stateHasChanged(org.cef.CefApp.CefAppState state) {
|
||||
if (state == CefAppState.TERMINATED) {
|
||||
// Signal completion of CEF shutdown.
|
||||
countdown_.countDown();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the singleton CefApp instance.
|
||||
CefSettings settings = new CefSettings();
|
||||
CefApp.getInstance(settings);
|
||||
}
|
||||
|
||||
// Executed after all tests have completed.
|
||||
@Override
|
||||
public void close() {
|
||||
if (TestSetupContext.debugPrint()) {
|
||||
System.out.println("TestSetupExtension.close");
|
||||
}
|
||||
|
||||
CefApp.getInstance().dispose();
|
||||
|
||||
// Wait for CEF shutdown to complete.
|
||||
try {
|
||||
countdown_.await();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package tests.simple;
|
||||
|
||||
import org.cef.CefApp;
|
||||
import org.cef.CefApp.CefAppState;
|
||||
import org.cef.CefClient;
|
||||
import org.cef.CefSettings;
|
||||
import org.cef.OS;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.browser.CefFrame;
|
||||
import org.cef.handler.CefAppHandlerAdapter;
|
||||
import org.cef.handler.CefDisplayHandlerAdapter;
|
||||
import org.cef.handler.CefFocusHandlerAdapter;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* This is a simple example application using JCEF.
|
||||
* It displays a JFrame with a JTextField at its top and a CefBrowser in its
|
||||
* center. The JTextField is used to enter and assign an URL to the browser UI.
|
||||
* No additional handlers or callbacks are used in this example.
|
||||
*
|
||||
* The number of used JCEF classes is reduced (nearly) to its minimum and should
|
||||
* assist you to get familiar with JCEF.
|
||||
*
|
||||
* For a more feature complete example have also a look onto the example code
|
||||
* within the package "tests.detailed".
|
||||
*/
|
||||
public class MainFrame extends JFrame {
|
||||
private static final long serialVersionUID = -5570653778104813836L;
|
||||
private final JTextField address_;
|
||||
private final CefApp cefApp_;
|
||||
private final CefClient client_;
|
||||
private final CefBrowser browser_;
|
||||
private final Component browserUI_;
|
||||
private boolean browserFocus_ = true;
|
||||
private JFrame fullscreenFrame_;
|
||||
|
||||
/**
|
||||
* To display a simple browser window, it suffices completely to create an
|
||||
* instance of the class CefBrowser and to assign its UI component to your
|
||||
* application (e.g. to your content pane).
|
||||
* But to be more verbose, this CTOR keeps an instance of each object on the
|
||||
* way to the browser UI.
|
||||
*/
|
||||
private MainFrame(String startURL, boolean useOSR, boolean isTransparent) {
|
||||
// (1) The entry point to JCEF is always the class CefApp. There is only one
|
||||
// instance per application and therefore you have to call the method
|
||||
// "getInstance()" instead of a CTOR.
|
||||
//
|
||||
// CefApp is responsible for the global CEF context. It loads all
|
||||
// required native libraries, initializes CEF accordingly, starts a
|
||||
// background task to handle CEF's message loop and takes care of
|
||||
// shutting down CEF after disposing it.
|
||||
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
|
||||
@Override
|
||||
public void stateHasChanged(org.cef.CefApp.CefAppState state) {
|
||||
// Shutdown the app if the native CEF part is terminated
|
||||
if (state == CefAppState.TERMINATED) System.exit(0);
|
||||
}
|
||||
});
|
||||
CefSettings settings = new CefSettings();
|
||||
settings.windowless_rendering_enabled = useOSR;
|
||||
cefApp_ = CefApp.getInstance(settings);
|
||||
|
||||
// (2) JCEF can handle one to many browser instances simultaneous. These
|
||||
// browser instances are logically grouped together by an instance of
|
||||
// the class CefClient. In your application you can create one to many
|
||||
// instances of CefClient with one to many CefBrowser instances per
|
||||
// client. To get an instance of CefClient you have to use the method
|
||||
// "createClient()" of your CefApp instance. Calling an CTOR of
|
||||
// CefClient is not supported.
|
||||
//
|
||||
// CefClient is a connector to all possible events which come from the
|
||||
// CefBrowser instances. Those events could be simple things like the
|
||||
// change of the browser title or more complex ones like context menu
|
||||
// events. By assigning handlers to CefClient you can control the
|
||||
// behavior of the browser. See tests.detailed.MainFrame for an example
|
||||
// of how to use these handlers.
|
||||
client_ = cefApp_.createClient();
|
||||
|
||||
// (3) One CefBrowser instance is responsible to control what you'll see on
|
||||
// the UI component of the instance. It can be displayed off-screen
|
||||
// rendered or windowed rendered. To get an instance of CefBrowser you
|
||||
// have to call the method "createBrowser()" of your CefClient
|
||||
// instances.
|
||||
//
|
||||
// CefBrowser has methods like "goBack()", "goForward()", "loadURL()",
|
||||
// and many more which are used to control the behavior of the displayed
|
||||
// content. The UI is held within a UI-Compontent which can be accessed
|
||||
// by calling the method "getUIComponent()" on the instance of CefBrowser.
|
||||
// The UI component is inherited from a java.awt.Component and therefore
|
||||
// it can be embedded into any AWT UI.
|
||||
browser_ = client_.createBrowser(startURL, useOSR, isTransparent);
|
||||
browserUI_ = browser_.getUIComponent();
|
||||
|
||||
// (4) For this minimal browser, we need only a text field to enter an URL
|
||||
// we want to navigate to and a CefBrowser window to display the content
|
||||
// of the URL. To respond to the input of the user, we're registering an
|
||||
// anonymous ActionListener. This listener is performed each time the
|
||||
// user presses the "ENTER" key within the address field.
|
||||
// If this happens, the entered value is passed to the CefBrowser
|
||||
// instance to be loaded as URL.
|
||||
address_ = new JTextField(startURL, 100);
|
||||
address_.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browser_.loadURL(address_.getText());
|
||||
}
|
||||
});
|
||||
|
||||
// Update the address field when the browser URL changes.
|
||||
client_.addDisplayHandler(new CefDisplayHandlerAdapter() {
|
||||
@Override
|
||||
public void onAddressChange(CefBrowser browser, CefFrame frame, String url) {
|
||||
address_.setText(url);
|
||||
}
|
||||
@Override
|
||||
public void onFullscreenModeChange(CefBrowser browser, boolean fullscreen) {
|
||||
setBrowserFullscreen(fullscreen);
|
||||
}
|
||||
});
|
||||
|
||||
// Clear focus from the browser when the address field gains focus.
|
||||
address_.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (!browserFocus_) return;
|
||||
browserFocus_ = false;
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
|
||||
address_.requestFocus();
|
||||
}
|
||||
});
|
||||
|
||||
// Clear focus from the address field when the browser gains focus.
|
||||
client_.addFocusHandler(new CefFocusHandlerAdapter() {
|
||||
@Override
|
||||
public void onGotFocus(CefBrowser browser) {
|
||||
if (browserFocus_) return;
|
||||
browserFocus_ = true;
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
|
||||
browser.setFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeFocus(CefBrowser browser, boolean next) {
|
||||
browserFocus_ = false;
|
||||
}
|
||||
});
|
||||
|
||||
// (5) All UI components are assigned to the default content pane of this
|
||||
// JFrame and afterwards the frame is made visible to the user.
|
||||
getContentPane().add(address_, BorderLayout.NORTH);
|
||||
getContentPane().add(browserUI_, BorderLayout.CENTER);
|
||||
pack();
|
||||
setSize(800, 600);
|
||||
setVisible(true);
|
||||
|
||||
// (6) To take care of shutting down CEF accordingly, it's important to call
|
||||
// the method "dispose()" of the CefApp instance if the Java
|
||||
// application will be closed. Otherwise you'll get asserts from CEF.
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
CefApp.getInstance().dispose();
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setBrowserFullscreen(boolean fullscreen) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (fullscreen) {
|
||||
if (fullscreenFrame_ == null) {
|
||||
fullscreenFrame_ = new JFrame();
|
||||
fullscreenFrame_.setUndecorated(true);
|
||||
fullscreenFrame_.setResizable(true);
|
||||
}
|
||||
GraphicsConfiguration gc = MainFrame.this.getGraphicsConfiguration();
|
||||
fullscreenFrame_.setBounds(gc.getBounds());
|
||||
gc.getDevice().setFullScreenWindow(fullscreenFrame_);
|
||||
|
||||
getContentPane().remove(browserUI_);
|
||||
fullscreenFrame_.add(browserUI_);
|
||||
fullscreenFrame_.setVisible(true);
|
||||
fullscreenFrame_.validate();
|
||||
} else {
|
||||
fullscreenFrame_.remove(browserUI_);
|
||||
fullscreenFrame_.setVisible(false);
|
||||
getContentPane().add(browserUI_, BorderLayout.CENTER);
|
||||
getContentPane().validate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Perform startup initialization on platforms that require it.
|
||||
if (!CefApp.startup(args)) {
|
||||
System.out.println("Startup initialization failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// The simple example application is created as anonymous class and points
|
||||
// to Google as the very first loaded page. Windowed rendering mode is used by
|
||||
// default. If you want to test OSR mode set |useOsr| to true and recompile.
|
||||
boolean useOsr = false;
|
||||
new MainFrame("http://www.google.com", useOsr, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user