Java GUI中的浏览器集成

Introduction

我几年前必须面对的挑战之一是将Java桌面应用程序从32位迁移到64位架构,这可能就像使用正确的JDK一样简单,切换到适当的外部库版本并获得 摆脱不推荐使用的代码实际上还有一个额外的问题。 该应用程序在面板上嵌入了32位PDF阅读器,并且这种限制已经使这种迁移停止了一段时间。

我几年前必须面对的挑战之一是将Java桌面应用程序从32位迁移到64位架构,这可能就像使用正确的JDK一样简单,切换到适当的外部库版本并获得 摆脱不推荐使用的代码实际上还有一个额外的问题。 该应用程序在面板上嵌入了32位PDF阅读器,并且这种限制已经使这种迁移停止了一段时间。

在代码本身中,它使用的是XULRunner,这是Firefox引擎的组件之一,因此它实际上所做的是“使用嵌入式的32位Firefox浏览器”。 它还使用Adobe Acrobat生成的交互式表单,实际上需要正确呈现Adobe Acrobat Reader本身,这使Apache PDFBox脱颖而出以完成此任务。

当我研究运行嵌入式浏览器的原理时,我试图了解笔记本电脑中发生的情况:当我上网浏览并打开Firefox 32位浏览器的PDF文件时,我没有使用某些浏览器代码:我委托了此代码 在浏览器的Adobe Acrobat Reader X插件中。 那么,为什么我们不应该再进一步一步,通过集成使用相同的插件呢? Adobe本身提供了该系统,因此不会出现不兼容问题,我只需要通过操作系统配置进行设置即可获得解决方法,并为我们当前正在运行该程序的计算机体系结构获取正确的版本。

因此,让我们认识一下DJNativeSwing,这是一个基于SWT(标准小工具工具包)的库,它使我们能够在代码中拥有自己的嵌入式浏览器。 强烈建议使用SWT库,因为它具有可移植性,因为它可以访问本机操作系统GUI,而这正是我们为此类问题所需要的。 它也是Java Swing的下一个包装级别,并且实际上更轻,更快,并且我在一天中早就使用它来避免不得不处理Macromedia Flash插件集成时出现的问题。

作为如何配置此示例,我们将遵循2个基本步骤:

  • 在Java swing组件上设置浏览器选项卡。能够在该浏览器标签上打开PDF。

Process

1. Previous set up: the Maven dependecies required

让我们从基础开始:首先,我们将获得Maven依赖项。

was这是最初撰写帖子时的稳定版本。

<dependecy>
  <group>chrriis.dj.nativeswing</group>
  <artifactId>DJNativeSwing</artifactId>
  <version>1.0.2</version>
</dependecy>

2. Building a basic Swing interface

之后,我们将定义基本的窗口框架,并通过按钮选择文件(通过FileChooser)和显示结果的面板。

all将所有文本字符串设置为常量可以使它们更容易发现它们,以便在需要时替换它们。 确实不是必需的,但是这样做可以提高可重用性。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.Map;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

import nativeSwing.BrowserPanel;
import pdfHandler.PdfReader;
import xmlHandler.XMLHandler;
import chrriis.common.UIUtils;
import chrriis.dj.nativeswing.swtimpl.NativeInterface;

public class DemoPDFRenderLauncher {

 private static final String TITLE = "PDF Renderer demo";
 private static final String NO_OUTPUT_MESSAGE = "No output available";
 private static final String NO_DATA_MESSAGE = "There is no data available from form";
 private static final int LENGTH = 800;
 private static final int WIDTH = 600;
 private static final String FILTER_FILES "PDF files";
 private static final String FILE_EXTENSION "pdf";

 /**
  * The main app window
  */
 private JFrame window;
 /**
  * The path of the file we will open
  */
 private String path;
 /**
  * Button for open file function
  */
 private JButton buttonOpen;
 /**
  * A browser panel
  */
 private BrowserPanel browserPanel;

/**
  * Constructor method, creates the GUI
  */
 public Launcher() {
  window = new JFrame(TITLE);
  window.getContentPane().setLayout(new BorderLayout());
  window.setSize(LENGTH, WIDTH);
  window.add(createButtonsPanel(), BorderLayout.NORTH);
  window.add(createContentPanel(), BorderLayout.CENTER);
  window.setVisible(true);
  window.addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    NativeInterface.close();
    System.exit(0);
   }
  });
 }

/**
  * Creates a button panel with the action button: open a file 
  * @return the buttons panel
  */
 private Component createButtonsPanel() {
  JPanel panel = new JPanel();
  panel.setLayout(new FlowLayout());
  buttonOpen = new JButton("Open file");
  buttonOpen.addActionListener(new ButtonOpenController());
  panel.add(buttonOpen);
  return panel;
 }

/**
  * Creates a panel to render the content
  * 
  * @return the buttons panel
  */
 private Component createContentPanel() {
  JPanel panel = new JPanel();
  panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
  JScrollPane scrollPaneText = new JScrollPane(textPanel);
  panel.add(scrollPaneText);
  //here we will insert the DJNativeSwing panle
  browserPanel = new BrowserPanel();
  JScrollPane scrollPaneBrowser = new JScrollPane(browserPanel);
  panel.add(scrollPaneBrowser);
  return panel;
 }

/**
  * Load button controller, which launches the FileChooser.
  */
 private class ButtonOpenController implements ActionListener {
  @Override
  public void actionPerformed(ActionEvent arg0) {
   launchOpenSelectFile();
  }
 }

/**
  * Launches the FileChooser window, and invokes the pdf opener window.
  */
 private void launchOpenSelectFile() {
  JFileChooser fileChooser = new JFileChooser();
  fileChooser.setAcceptAllFileFilterUsed(false);
  FileNameExtensionFilter filter = new FileNameExtensionFilter(
    FILTER_FILES, FILE_EXTENSION);
  fileChooser.addChoosableFileFilter(filter);
  if (fileChooser.showOpenDialog(window) == JFileChooser.APPROVE_OPTION) {
   path = fileChooser.getSelectedFile().getAbsolutePath();
   browserPanel.navigate(path);
  }
 }

@SuppressWarnings("unused")
 public static void main(String[] args) {
  UIUtils.setPreferredLookAndFeel();
  NativeInterface.open();
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    Launcher demo = new Launcher();
   }
  });
 }
}

3. Embeding a web browser

然后,让我们继续浏览器标签:如果我们只想创建一个浏览器面板,就像编写以下几行一样简单:

import java.awt.BorderLayout;

import javax.swing.BorderFactory;
import javax.swing.JPanel;

import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;

public class BasicBrowserPanel extends JPanel {

 private static final String TITLE = "";

/**
  * The browser will be handled in this specific component
  */
 private JWebBrowser webBrowser;

/**
  * Constructor
  */
 public BrowserPanel() {
  super(new BorderLayout());
  JPanel webBrowserPanel = new JPanel(new BorderLayout());
  webBrowserPanel.setBorder(BorderFactory.createTitledBorder(TITLE));
  webBrowser = new JWebBrowser();
  webBrowser.setBarsVisible(false);
  webBrowser.setStatusBarVisible(false);
  webBrowserPanel.add(webBrowser, BorderLayout.CENTER);
  add(webBrowserPanel, BorderLayout.CENTER);
 }

/**
  * Initializes the browser and sets a value in the URL storage
  * @param path the URL value o file path to open
  */
 public void navigate(String path) {
  webBrowser.setVisible(true);
  webBrowser.navigate(path);
 }

 /**
  * Makes the browser retrieve and render the content from the path previously stored
  */
 public String getAddress(){
  return webBrowser.getHTMLContent();
 }

 /**
  * Hides the browser controls (forward, back, home buttons...)
  */
 public void hideContent() {
  webBrowser.setVisible(false);
 }
}

这样,我们将获得一个功能齐全的Web浏览器,与Eclipse IDE中的浏览器非常相似,但是在此处尝试执行的操作具有太多不必要的功能。 由于只通过在Adobe上委派渲染过程来进行渲染,因此我们可以从整个自定义浏览系统中删除GUI多余的元素,并保留裸面板。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;

/**
 * Allows to launch a JFrame containing an embedded browser.
 */
public class BrowserFrameLauncher {

/**
  * Renders the file content on a browser via DJ Native Swing
  * 
  * @param path
  *            the file url if we pass as a parameter any webpage URL,
  *             the system would try to render it
  * @return a JPanel with a native browser, to render the file content
  */
 private Component createBrowserPanel(String path) {
  JWebBrowser.useXULRunnerRuntime();
  JPanel fileBrowserPanel = new JPanel(new BorderLayout());
  final JWebBrowser fileBrowser = new JWebBrowser();
  fileBrowser.setBarsVisible(false);
  fileBrowser.setStatusBarVisible(false);
  fileBrowser.navigate(path);
  fileBrowserPanel.add(fileBrowser, BorderLayout.CENTER);
  return fileBrowserPanel;
 }

}

4. Setting the last piece of the puzzle: getting the PDF itself

最后,我们来作最后的修改以打开PDF。 实际上,我们正在做的是将PDF文件路径输入浏览器,因此最终我们在旧朋友XULRunner上有了新的层,但这为我们提供了一种通过“正确的架构版本” SWT库集成插件的方法。 因此,作为结论,我们可以连接到“正确的体系结构版本”插件,解决我们的渲染问题,并使我们永久脱离32位平台。

// excerpt from BrowserFrameLauncherPDF.java

private static final String CLOSING_MESSAGE = "Do you really want to close the file?";
 private static final String RENDERED_TITLE = "PDF Renderer demo - Embed Browser";

/**
  * Opens a file and shows it content in a JFrame.
  * 
  * @param path
  *            the url of the file to open in a JFrame
  */
 public static void openPDF(final String path) {
  NativeInterface.open();
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    final JFrame frame = new JFrame(RENDERED_TITLE);
    frame.setLocation(0, 0);
    //we may set up a default size for this test
    //frame.setSize(800, 600);
    frame.setVisible(true);
    frame.add(createBrowserPanel(path));

    //a window listener would allow us to control the closing actions
    frame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
      int i = JOptionPane.showConfirmDialog(frame,CLOSING_MESSAGE);
      if (i == 0) {
       NativeInterface.close();
      }
     }
    });
   }
  });
}

Please️请注意NativeInterface.open()行,以确保正确启动组件以及对该组件的线程化,以避免其他进程干扰渲染。

from: https://dev.to//angelesbroullon/browser-integration-in-java-guis-2nnm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值