in java/org/cef/browser/CefBrowserWr.java [185:376]
private CefBrowserWr(CefClient client, String url, CefRequestContext context,
CefBrowserWr parent, Point inspectAt, CefBrowserSettings settings) {
super(client, url, context, parent, inspectAt, settings);
delayedUpdate_.setRepeats(false);
delayCreationUntilMs_ = Long.getLong("jcef.debug.cefbrowserwr.delay_creation", 0);
if (delayCreationUntilMs_ > 0) delayCreationUntilMs_ += System.currentTimeMillis();
// Disabling lightweight of popup menu is required because
// otherwise it will be displayed behind the content of component_
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
// We're using a JComponent instead of a Canvas now because the
// JComponent has clipping informations, which aren't accessible for Canvas.
component_ = new JPanel(new BorderLayout()) {
private MouseListener mouseListener;
private MouseWheelListener mouseWheelListener;
private MouseMotionListener mouseMotionListener;
private boolean removed_ = true;
{
addPropertyChangeListener("graphicsConfiguration", e -> updateScale());
}
@Override
public void addMouseListener(MouseListener l) {
mouseListener = l;
if (canvas_ != null)
canvas_.addMouseListener(l);
super.addMouseListener(l);
}
@Override
public void addMouseWheelListener(MouseWheelListener l) {
mouseWheelListener = l;
if (canvas_ != null)
canvas_.addMouseWheelListener(l);
super.addMouseWheelListener(l);
}
@Override
public void addMouseMotionListener(MouseMotionListener l) {
mouseMotionListener = l;
if (canvas_ != null)
canvas_.addMouseMotionListener(l);
super.addMouseMotionListener(l);
}
@Override
public void removeMouseListener(MouseListener l) {
mouseListener = null;
if (canvas_ != null)
canvas_.removeMouseListener(l);
super.removeMouseListener(l);
}
@Override
public void removeMouseMotionListener(MouseMotionListener l) {
mouseMotionListener = null;
if (canvas_ != null)
canvas_.removeMouseMotionListener(l);
super.removeMouseMotionListener(l);
}
@Override
public void removeMouseWheelListener(MouseWheelListener l) {
mouseWheelListener = null;
if (canvas_ != null)
canvas_.removeMouseWheelListener(l);
super.removeMouseWheelListener(l);
}
private void addCanvas() {
canvas_ = new BrowserCanvas();
if (mouseListener != null) canvas_.addMouseListener(mouseListener);
if (mouseWheelListener != null) canvas_.addMouseWheelListener(mouseWheelListener);
if (mouseMotionListener != null) canvas_.addMouseMotionListener(mouseMotionListener);
this.add(canvas_, BorderLayout.CENTER);
}
private void removeCanvas() {
if (canvas_ == null) return;
if (mouseListener != null) canvas_.removeMouseListener(mouseListener);
if (mouseWheelListener != null) canvas_.removeMouseWheelListener(mouseWheelListener);
if (mouseMotionListener != null) canvas_.removeMouseMotionListener(mouseMotionListener);
this.remove(canvas_);
canvas_ = null;
}
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
wasResized((int) (width * scaleFactor_), (int) (height * scaleFactor_));
}
@Override
public void setBounds(Rectangle r) {
setBounds(r.x, r.y, r.width, r.height);
}
@Override
public void setSize(int width, int height) {
super.setSize(width, height);
wasResized((int) (width * scaleFactor_), (int) (height * scaleFactor_));
}
@Override
public void setSize(Dimension d) {
setSize(d.width, d.height);
}
@Override
public void paint(Graphics g) {
// If the user resizes the UI component, the new size and clipping
// informations are forwarded to the native code.
// But on Mac the last resize information doesn't resize the native UI
// accurately (sometimes the native UI is too small). An easy way to
// solve this, is to send the last Update-Information again. Therefore
// we're setting up a delayedUpdate timer which is reset each time
// paint is called. This prevents the us of sending the UI update too
// often.
doUpdate();
delayedUpdate_.restart();
}
@Override
public void addNotify() {
super.addNotify();
updateScale();
if (removed_) {
if (USE_CANVAS) {
// Recreate canvas to prevent its blinking at toplevel's [0,0].
// NOTE: generally it's a bad idea to add components inside addNotify
// Also it'd be better to add component before super.addNotify (because it perfroms some processing with
// all children - send notifications, set listeners etc)
addCanvas();
}
setParent(getWindowHandle(this), canvas_);
removed_ = false;
}
delayedUpdate_.restart();
}
@Override
public void removeNotify() {
if (!removed_) {
if (!isClosed()) {
setParent(0, null);
}
removed_ = true;
if (USE_CANVAS) {
removeCanvas();
}
}
super.removeNotify();
}
};
// Initial minimal size of the component. Otherwise the UI won't work
// accordingly in panes like JSplitPane.
component_.setMinimumSize(new Dimension(0, 0));
component_.setFocusable(true);
component_.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
setFocus(false);
}
@Override
public void focusGained(FocusEvent e) {
// Dismiss any Java menus that are currently displayed.
MenuSelectionManager.defaultManager().clearSelectedPath();
setFocus(true);
}
});
component_.addHierarchyBoundsListener(new HierarchyBoundsListener() {
@Override
public void ancestorResized(HierarchyEvent e) {
doUpdate();
}
@Override
public void ancestorMoved(HierarchyEvent e) {
doUpdate();
notifyMoveOrResizeStarted();
}
});
component_.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
setWindowVisibility(e.getChanged().isVisible());
}
}
});
}