int-test mqtt <-> prediction

This commit is contained in:
naumueller
2026-02-19 21:31:49 +01:00
parent 701cc0a8b6
commit 5ed5008def
461 changed files with 53944 additions and 11 deletions
@@ -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_;
}
}
+349
View File
@@ -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/>&nbsp;<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) {
}
}
}
+229
View File
@@ -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);
}
}