/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.awt.swingpeers;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Window;
import java.awt.Cursor;
import java.awt.Dialog;
import java.beans.PropertyVetoException;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JRootPane;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
/**
* Base class for peer implementation that subclass {@link java.awt.Window}.
*
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
abstract class SwingBaseWindow<awtT extends Window, swingPeerT extends SwingBaseWindow<awtT, swingPeerT>>
extends JInternalFrame implements ISwingPeer<awtT> {
private static final long serialVersionUID = 1L;
/**
* The AWT component this is a peer for
*/
protected final awtT target;
/**
* The swing peer implementation
*/
private SwingBaseWindowPeer<awtT, swingPeerT> swingPeer;
boolean requestingFocus = false;
public SwingBaseWindow(awtT target) {
this.target = target;
}
/**
* Initialize this instance.
*
* @param target
*/
public SwingBaseWindow(awtT target, String title) {
super(title, true, true, true, true);
this.target = target;
}
/**
* @see javax.swing.JInternalFrame#reshape(int, int, int, int)
*/
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
target.reshape(x, y, width, height);
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (target instanceof RootPaneContainer && isVisible()) {
target.paint(g);
//todo isolates related
//swingPeer.postPaintEvent();
//JRootPane rp = ((RootPaneContainer) target).getRootPane();
//JNodeToolkit.postToTarget(new PaintEvent(rp, PaintEvent.UPDATE, rp.getBounds()), rp);
}
}
@Override
public void repaint(long tm, int x, int y, int width, int height) {
super.repaint(tm, x, y, width, height);
if (target instanceof RootPaneContainer && isVisible()) {
target.repaint(tm, x, y, width, height);
//todo isolates related
//swingPeer.postPaintEvent();
//JRootPane rp = ((RootPaneContainer) target).getRootPane();
//JNodeToolkit.postToTarget(new PaintEvent(rp, PaintEvent.PAINT, new Rectangle(x, y, width, height)), rp);
}
}
@Override
public void update(Graphics g) {
super.update(g);
if (target instanceof RootPaneContainer && isVisible()) {
target.update(g);
//todo isolates related
//swingPeer.postPaintEvent();
//JRootPane rp = ((RootPaneContainer) target).getRootPane();
//JNodeToolkit.postToTarget(new PaintEvent(rp, PaintEvent.UPDATE, rp.getBounds()), rp);
}
}
@Override
public void setMaximum(boolean b) throws PropertyVetoException {
super.setMaximum(b);
target.setBounds(this.getBounds());
}
@Override
protected void validateTree() {
super.validateTree();
if (target instanceof JFrame)
((JFrame) target).getRootPane().validate();
else if (target instanceof JDialog)
((JDialog) target).getRootPane().validate();
}
/**
* @see org.jnode.awt.swingpeers.ISwingPeer#getAWTComponent()
*/
public final awtT getAWTComponent() {
return target;
}
/**
* Pass an event onto the AWT component.
*
* @see java.awt.Component#processEvent(java.awt.AWTEvent)
*/
protected final void processEvent(AWTEvent event) {
AppContext ac = SunToolkit.targetToAppContext(target);
if (ac == null) {
target.dispatchEvent(SwingToolkit.convertEvent(event, target));
} else {
EventQueue eq = (EventQueue) ac.get(AppContext.EVENT_QUEUE_KEY);
if (eq == null) {
target.dispatchEvent(SwingToolkit.convertEvent(event, target));
} else {
eq.postEvent(SwingToolkit.convertEvent(event, target));
}
}
}
/**
* Process an event within this swingpeer
*
* @param event
*/
public final void processAWTEvent(AWTEvent event) {
super.processEvent(event);
}
/**
* @see org.jnode.awt.swingpeers.ISwingPeer#validatePeerOnly()
*/
public final void validatePeerOnly() {
super.validate();
doLayout();
getRootPane().doLayout();
}
/**
* @see javax.swing.JInternalFrame#createRootPane()
*/
protected JRootPane createRootPane() {
return new NoContentRootPane();
}
/**
* Gets the peer implementation.
*/
final SwingBaseWindowPeer<awtT, swingPeerT> getSwingPeer() {
return swingPeer;
}
final void initialize(SwingBaseWindowPeer<awtT, swingPeerT> swingPeer) {
this.swingPeer = swingPeer;
//((ContentPane) getContentPane()).initialize(target,swingPeer);
}
@Override
public void repaint() {
super.repaint();
}
/**
* @see java.awt.Component#invalidate()
*/
public final void invalidate() {
super.invalidate();
if (target != null) {
target.invalidate();
}
}
/**
* @see java.awt.Component#validate()
*/
public final void validate() {
super.validate();
if (target != null) {
target.validate();
}
}
public void updateUI() {
super.updateUI();
//todo review it
//when the laf is changed starting from the peer component
//we enforce the UI update of the target componet
//this can be dangerous, find a better solution
if (target != null)
SwingUtilities.updateComponentTreeUI(target);
}
private boolean settingCursor;
@Override
public void setCursor(Cursor cursor) {
super.setCursor(cursor);
if (!settingCursor) {
settingCursor = true;
target.setCursor(cursor);
settingCursor = false;
}
}
@Override
public void requestFocus() {
if (target instanceof JFrame) {
if (!requestingFocus) {
requestingFocus = true;
target.requestFocus();
requestingFocus = false;
}
} else
super.requestFocus();
}
@Override
public boolean requestFocus(boolean temporary) {
if (target instanceof JFrame) {
if (!requestingFocus) {
requestingFocus = true;
target.requestFocus();
requestingFocus = false;
}
return true;
} else
return super.requestFocus(temporary);
}
@Override
public boolean requestFocusInWindow() {
if (target instanceof JFrame) {
if (!requestingFocus) {
requestingFocus = true;
boolean ret = target.requestFocusInWindow();
requestingFocus = false;
return ret;
}
return true;
} else
return super.requestFocusInWindow();
}
@Override
protected boolean requestFocusInWindow(boolean temporary) {
if (target instanceof JFrame) {
if (!requestingFocus) {
requestingFocus = true;
boolean ret = target.requestFocusInWindow();
requestingFocus = false;
return ret;
}
return true;
} else
return super.requestFocusInWindow(temporary);
}
@Override
public void setIcon(boolean b) throws PropertyVetoException {
super.setIcon(b);
target.setBounds(this.getBounds());
}
final class NullContentPane extends JComponent {
private static final long serialVersionUID = 1L;
@Override
public void update(Graphics g) {
//org.jnode.vm.Unsafe.debug("NullContantPane.update()\n");
}
@Override
public void paint(Graphics g) {
if ((target instanceof Frame && !(target instanceof JFrame)) ||
(target instanceof Dialog && !(target instanceof JDialog))) {
SwingBaseWindow<?, ?> sf = SwingBaseWindow.this;
Window f = target;
Color bg = f.getBackground();
if (bg == null) bg = UIManager.getColor("window");
if (bg == null) bg = UIManager.getColor("control");
if (bg == null) bg = Color.GRAY;
g.setColor(bg);
g.fillRect(0, 0, getWidth(), getHeight());
Point f_loc = sf.getLocationOnScreen();
Point p_loc = this.getLocationOnScreen();
int dx = p_loc.x - f_loc.x;
int dy = p_loc.y - f_loc.y;
for (Component c : f.getComponents()) {
Graphics cg = g.create(c.getX() - dx, c.getY() - dy, c.getWidth(), c.getHeight());
c.paintAll(cg);
cg.dispose();
}
}
}
@Override
public void repaint() {
}
@Override
public void repaint(long tm, int x, int y, int width, int height) {
}
}
final class NoContentRootPane extends JRootPane {
private static final long serialVersionUID = 1L;
/**
* @see javax.swing.JRootPane#createContentPane()
*/
protected Container createContentPane() {
return new NullContentPane();
}
}
@SuppressWarnings("unused")
private final class ContentPane extends JComponent {
private static final long serialVersionUID = 1L;
private awtT target;
private SwingBaseWindowPeer<?, ?> swingPeer;
public void initialize(awtT target, SwingBaseWindowPeer<awtT, swingPeerT> swingPeer) {
this.target = target;
this.swingPeer = swingPeer;
target.invalidate();
}
/**
* @see javax.swing.JComponent#paintChildren(java.awt.Graphics)
*/
protected void paintChildren(Graphics g) {
super.paintChildren(g);
final Insets insets = swingPeer.getInsets();
//SwingToolkit.paintLightWeightChildren(target, g, insets.left,insets.top);
}
@SuppressWarnings("deprecation")
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
if (!swingPeer.isReshapeInProgress) {
Point p = target.isShowing() ? target.getLocationOnScreen() : new Point();
// Point p = awtFrame.getLocationOnScreen();
Insets ins = swingPeer.getInsets();
target.reshape(p.x + x, p.y, width + ins.left + ins.right,
height + ins.bottom + ins.top);
}
}
}
@SuppressWarnings("unused")
private final class RootPane extends JRootPane {
private static final long serialVersionUID = 1L;
/**
* @see javax.swing.JRootPane#createContentPane()
*/
protected Container createContentPane() {
return super.createContentPane();
/*
ContentPane p = new ContentPane();
p.setName(this.getName() + ".contentPane");
p.setLayout(new BorderLayout());
return p;
*/
}
}
}