我正在构建一个需要同时支持嵌入式浏览器和ActiveX的Java Swing应用程序。这样做的简单方法似乎是使用JDICplus,它只是在您的应用程序中嵌入IE。那将涵盖两个要求。
我还需要在浏览器视图的顶部覆盖一些按钮,以便用户可以在视图之间导航。要做到这一点,我有一个JLayeredPane我添加视图,在更高层,按钮。这适用于我的纯Java视图。但是,在我的Internet视图中,Internet会在按钮之上绘制。换句话说,它似乎并不尊重JLayeredPane。我猜这是因为它是本机组件而不是Java组件。
可以肯定的是,我将Internet窗格放入JInternalFrame,将另一个窗口放在按钮中,并将两个内部框架放入JDesktopPane。当我在Internet框架顶部拖动按钮框架时,Internet框架会跳转到前景并覆盖另一个框架。这就好像嵌入式IE窃取焦点并将自己置于其他窗口的最前沿。
我的问题是:有没有办法可靠地在这些Windows / IE组件上绘制Java组件?或者,我不会将Java与IE混合在一起吗?还有其他选择来满足我对嵌入式浏览器和ActiveX支持的要求(从技术上讲,可能是一个不同的视图 - 换句话说,我可以有一个Internet视图和另一个只支持ActiveX的视图)。我愿意接受建议。我已经查看了Java的其他免费浏览器组件,并且每个人都会告诉你,这令人沮丧。
查看Sun关于mixing heavy and light components的文章 - 由于JDICPlus基本上将IE嵌入到您的应用程序中,因此它是一个重量级组件。
您可以通过使用其他重量级组件(即AWT按钮)在浏览器窗口上放置按钮,或者执行类似将按钮放置在浏览器上的JPopupMenu的设置,并在其上设置setDefaultLightWeightPopupEnabled(false)以使其成为重量级。
编辑
我写了一个使用JPopupMenu在重量级组件上显示JButton的例子 - JPopupMenu可以工作,但是当弹出窗口中的弹出窗口或组件失去焦点时,它确实具有内置行为来关闭菜单。我向重量级组件添加了一个MouseMotionListener,以便在鼠标进入按钮所在位置附近的边界框时显示弹出窗口。不确定这是否适合您,因为并不总是显示按钮。
包括代码示例和截图 -
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
public class LightHeavy extends JFrame {
private Component heavyweightComponent;
private JPopupMenu backButton, forwardButton;
public LightHeavy() {
super("LightHeavy");
heavyweightComponent = buildHeavyweightComponent();
heavyweightComponent.setBackground(Color.ORANGE);
heavyweightComponent.setSize(640, 480);
getContentPane().add(heavyweightComponent, BorderLayout.CENTER);
ImageIcon backArrow = new ImageIcon("left_arrow_128.png");
backButton = buildPopup(backArrow);
ImageIcon forwardArrow = new ImageIcon("right_arrow_128.png");
forwardButton = buildPopup(forwardArrow);
heavyweightComponent.addMouseMotionListener(new MouseInputAdapter() {
public void mouseMoved(MouseEvent e) {
Rectangle backHotSpot = new Rectangle(0, 0, 200, 200);
Rectangle forwardHotSpot = new Rectangle(heavyweightComponent.getWidth() - 200, 0, 200, 200);
if (backHotSpot.contains(e.getPoint())) {
backButton.show(heavyweightComponent, 0, 0);
} else if (forwardHotSpot.contains(e.getPoint())) {
forwardButton.show(heavyweightComponent,
heavyweightComponent.getWidth() - forwardButton.getWidth(), 0);
}
}
});
}
private Component buildHeavyweightComponent() {
return new Canvas() {
public void paint(Graphics og) {
super.paint(og);
Graphics2D g = (Graphics2D)og;
String big = "Heavyweight Component";
g.setFont(getFont().deriveFont(20F));
Rectangle2D bigBounds = g.getFontMetrics().getStringBounds(big, g);
g.drawString(big,
(this.getWidth() - (int)bigBounds.getWidth()) / 2,
(this.getHeight() - (int)bigBounds.getHeight()) / 2);
String little = "(assume this is JDICplus)";
g.setFont(getFont().deriveFont(10F));
Rectangle2D littleBounds = g.getFontMetrics().getStringBounds(little, g);
g.drawString(little,
(this.getWidth() - (int)littleBounds.getWidth()) / 2,
(this.getHeight() + (int)littleBounds.getHeight()) / 2);
}
};
}
private JPopupMenu buildPopup(Icon icon) {
JButton button = new JButton(icon);
JPopupMenu popup = new JPopupMenu();
popup.add(button);
popup.setBorderPainted(false);
popup.setLightWeightPopupEnabled(false);
return popup;
}
public static void main(String[] args) {
JFrame f = new LightHeavy();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
这是左边JButton的屏幕截图 - 注意你也不能做任何很酷的透明效果,因为你正在处理重量级组件。