Проблема с встраиванием IE JDICplus в Java - PullRequest
0 голосов
/ 16 июля 2009

Я создаю приложение Java Swing, которое должно поддерживать как встроенный браузер, так и ActiveX. Простой способ сделать это - использовать JDICplus , который просто встраивает IE в ваше приложение. Это покрыло бы оба требования.

Мне также нужно наложить некоторые кнопки поверх этого представления браузера, чтобы пользователь мог перемещаться между представлениями. Для этого у меня есть JLayeredPane , к которому я добавляю представления, а на более высоком уровне - кнопки. Это работает в моих чистых представлениях Java. Однако, на мой взгляд в Интернете, Интернет рисует поверх кнопок. Другими словами, кажется, что он не уважает JLayeredPane. Я предполагаю, что это потому, что это нативный компонент, а не компонент Java.

Конечно, я помещаю панель Интернета в JInternalFrame и кнопки в другой, и помещаю обе внутренние рамки в JDesktopPane. Когда я перетаскиваю рамку кнопки поверх рамки Интернета, рамка Интернета переходит на передний план и закрывает другой кадр. Это как если бы встроенный IE крадет фокус и ставит себя на передний план других моих окон.

У меня такой вопрос: есть ли способ надежно нарисовать компоненты Java поверх этих компонентов Windows / IE? Или я не собираюсь никуда смешивать Java с IE? Существуют ли другие варианты удовлетворения моего требования встроенного браузера и поддержки ActiveX (что технически может быть другим представлением - другими словами, у меня может быть представление в Интернете и другое представление, которое просто поддерживает ActiveX). Я открыт для предложений. Я посмотрел на другие бесплатные компоненты браузера для Java, и, как все скажут, это обескураживает.

1 Ответ

2 голосов
/ 16 июля 2009

Ознакомьтесь с статьей Sun о смешивании тяжелых и легких компонентов - поскольку 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 слева - обратите внимание, что вы также не сможете делать какие-либо крутые эффекты прозрачности, поскольку имеете дело с тяжеловесными компонентами.

screenshot of code

...