!7 import java.beans.*; p { jxBrowser_init(); JDesktopPane desktop = jDesktopPane(); showMaximizedFrame(desktop); final new TabbedPane tabbedPane; insertTab(tabbedPane, TabFactory.createFirstTab()); insertNewTabButton(tabbedPane); Browser browser = new Browser(BrowserType.LIGHTWEIGHT); BrowserView view = new BrowserView(browser); browser.loadURL("https://BotCompany.de"); onInternalFrameClosing(addInternalFrame(desktop, "Browser", tabbedPane), r { tabbedPane.disposeAllTabs() }); } static void insertNewTabButton(final TabbedPane tabbedPane) { TabButton button = new TabButton(Resources.getIcon("new-tab.png"), "New tab"); button.addActionListener(actionListener { insertTab(tabbedPane, TabFactory.createTab()); }); tabbedPane.addTabButton(button); } static void insertTab(TabbedPane tabbedPane, Tab tab) { tabbedPane.addTab(tab); tabbedPane.selectTab(tab); } sclass TabbedPane extends JPanel { private final List tabs; private final TabCaptions captions; private final JComponent contentContainer; public TabbedPane() { this.captions = new TabCaptions(); this.tabs = new ArrayList(); this.contentContainer = new JPanel(new BorderLayout()); setLayout(new BorderLayout()); add(captions, BorderLayout.NORTH); add(contentContainer, BorderLayout.CENTER); } public void disposeAllTabs() { for (Tab tab : getTabs()) { disposeTab(tab); } } private void disposeTab(Tab tab) { tab.getCaption().setSelected(false); tab.getContent().dispose(); removeTab(tab); if (hasTabs()) { Tab firstTab = getFirstTab(); firstTab.getCaption().setSelected(true); } else disposeInternalFrame(this); } private Tab findTab(TabCaption item) { for (Tab tab : getTabs()) { if (tab.getCaption().equals(item)) { return tab; } } return null; } public void addTab(final Tab tab) { TabCaption caption = tab.getCaption(); caption.addPropertyChangeListener("CloseButtonPressed", new TabCaptionCloseTabListener()); caption.addPropertyChangeListener("TabSelected", new SelectTabListener()); TabContent content = tab.getContent(); content.addPropertyChangeListener("TabClosed", new TabContentCloseTabListener()); captions.addTab(caption); tabs.add(tab); validate(); repaint(); } private boolean hasTabs() { return !tabs.isEmpty(); } private Tab getFirstTab() { return tabs.get(0); } private List getTabs() { return new ArrayList(tabs); } public void removeTab(Tab tab) { TabCaption tabCaption = tab.getCaption(); captions.removeTab(tabCaption); tabs.remove(tab); validate(); repaint(); } public void addTabButton(TabButton button) { captions.addTabButton(button); } public void selectTab(Tab tab) { TabCaption tabCaption = tab.getCaption(); TabCaption selectedTab = captions.getSelectedTab(); if (selectedTab != null && !selectedTab.equals(tabCaption)) { selectedTab.setSelected(false); } captions.setSelectedTab(tabCaption); } private class TabCaptionCloseTabListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { TabCaption caption = (TabCaption) evt.getSource(); Tab tab = findTab(caption); disposeTab(tab); } } private class SelectTabListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { TabCaption caption = (TabCaption) evt.getSource(); Tab tab = findTab(caption); if (caption.isSelected()) { selectTab(tab); } if (!caption.isSelected()) { TabContent content = tab.getContent(); contentContainer.remove(content); contentContainer.validate(); contentContainer.repaint(); } else { final TabContent content = tab.getContent(); contentContainer.add(content, BorderLayout.CENTER); contentContainer.validate(); contentContainer.repaint(); } } } private class TabContentCloseTabListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { TabContent content = (TabContent) evt.getSource(); Tab tab = findTab(content); disposeTab(tab); } private Tab findTab(TabContent content) { for (Tab tab : getTabs()) { if (tab.getContent().equals(content)) { return tab; } } return null; } } } static class TabFactory { public static Tab createFirstTab() { return createTab("https://www.teamdev.com/jxbrowser"); } public static Tab createTab() { return createTab("about:blank"); } public static Tab createTab(String url) { Browser browser = new Browser(); BrowserView browserView = new BrowserView(browser); TabContent tabContent = new TabContent(browserView); browser.setDownloadHandler(new DefaultDownloadHandler(browserView)); browser.setDialogHandler(new DefaultDialogHandler(browserView)); browser.setPopupHandler(new DefaultPopupHandler()); final TabCaption tabCaption = new TabCaption(); tabCaption.setTitle("about:blank"); tabContent.addPropertyChangeListener("PageTitleChanged", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { tabCaption.setTitle((String) evt.getNewValue()); } }); browser.loadURL(url); return new Tab(tabCaption, tabContent); } } sclass Tab { private final TabCaption caption; private final TabContent content; public Tab(TabCaption caption, TabContent content) { this.caption = caption; this.content = content; } public TabCaption getCaption() { return caption; } public TabContent getContent() { return content; } } sclass TabButton extends JButton { public TabButton(Icon icon, String toolTipText) { setIcon(icon); setToolTipText(toolTipText); setOpaque(false); setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); setContentAreaFilled(false); setFocusable(false); } } sclass TabCaption extends JPanel { private boolean selected; private TabCaptionComponent component; public TabCaption() { setLayout(new BorderLayout()); setOpaque(false); add(createComponent(), BorderLayout.CENTER); add(Box.createHorizontalStrut(1), BorderLayout.EAST); } private JComponent createComponent() { component = new TabCaptionComponent(); component.addPropertyChangeListener("CloseButtonPressed", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { firePropertyChange("CloseButtonPressed", evt.getOldValue(), evt.getNewValue()); } }); component.addPropertyChangeListener("TabClicked", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { setSelected(true); } }); return component; } @Override public Dimension getPreferredSize() { return new Dimension(155, 26); } @Override public Dimension getMinimumSize() { return new Dimension(50, 26); } @Override public Dimension getMaximumSize() { return getPreferredSize(); } public void setTitle(String title) { component.setTitle(title); } public boolean isSelected() { return selected; } public void setSelected(boolean selected) { boolean oldValue = this.selected; this.selected = selected; component.setSelected(selected); firePropertyChange("TabSelected", oldValue, selected); } private static class TabCaptionComponent extends JPanel { private final Color defaultBackground; private JLabel label; private TabCaptionComponent() { defaultBackground = getBackground(); setLayout(new BorderLayout()); setOpaque(false); add(createLabel(), BorderLayout.CENTER); add(createCloseButton(), BorderLayout.EAST); } private JComponent createLabel() { label = new JLabel(); label.setOpaque(false); label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); label.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { firePropertyChange("TabClicked", false, true); } if (e.getButton() == MouseEvent.BUTTON2) { firePropertyChange("CloseButtonPressed", false, true); } } }); return label; } private JComponent createCloseButton() { JButton closeButton = new JButton(); closeButton.setOpaque(false); closeButton.setToolTipText("Close"); closeButton.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); closeButton.setPressedIcon(Resources.getIcon("close-pressed.png")); closeButton.setIcon(Resources.getIcon("close.png")); closeButton.setContentAreaFilled(false); closeButton.setFocusable(false); closeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { firePropertyChange("CloseButtonPressed", false, true); } }); return closeButton; } public void setTitle(final String title) { SwingUtilities.invokeLater(new Runnable() { public void run() { label.setText(title); label.setToolTipText(title); } }); } public void setSelected(boolean selected) { setBackground(selected ? defaultBackground : new Color(150, 150, 150)); repaint(); } @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setPaint( new GradientPaint(0, 0, Color.LIGHT_GRAY, 0, getHeight(), getBackground())); g2d.fillRect(0, 0, getWidth(), getHeight()); g2d.dispose(); super.paint(g); } } } sclass TabCaptions extends JPanel { private TabCaption selectedTab; private JPanel tabsPane; private JPanel buttonsPane; public TabCaptions() { createUI(); } private void createUI() { setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); setBackground(Color.DARK_GRAY); add(createItemsPane()); add(createButtonsPane()); add(Box.createHorizontalGlue()); } private JComponent createItemsPane() { tabsPane = new JPanel(); tabsPane.setOpaque(false); tabsPane.setLayout(new BoxLayout(tabsPane, BoxLayout.X_AXIS)); return tabsPane; } private JComponent createButtonsPane() { buttonsPane = new JPanel(); buttonsPane.setOpaque(false); buttonsPane.setLayout(new BoxLayout(buttonsPane, BoxLayout.X_AXIS)); return buttonsPane; } public void addTab(TabCaption item) { tabsPane.add(item); } public void removeTab(TabCaption item) { tabsPane.remove(item); } public void addTabButton(TabButton button) { buttonsPane.add(button); } public TabCaption getSelectedTab() { return selectedTab; } public void setSelectedTab(TabCaption selectedTab) { this.selectedTab = selectedTab; this.selectedTab.setSelected(true); } } sclass TabContent extends JPanel { private final BrowserView browserView; private final ToolBar toolBar; private final JComponent jsConsole; private final JComponent container; private final JComponent browserContainer; public TabContent(final BrowserView browserView) { this.browserView = browserView; this.browserView.getBrowser().addLoadListener(new LoadAdapter() { @Override public void onFinishLoadingFrame(FinishLoadingEvent event) { if (event.isMainFrame()) { firePropertyChange("PageTitleChanged", null, TabContent.this.browserView.getBrowser().getTitle()); } } }); this.browserView.getBrowser().addTitleListener(new TitleListener() { @Override public void onTitleChange(TitleEvent event) { firePropertyChange("PageTitleChanged", null, event.getTitle()); } }); browserContainer = createBrowserContainer(); jsConsole = createConsole(); toolBar = createToolBar(browserView); container = new JPanel(new BorderLayout()); container.add(browserContainer, BorderLayout.CENTER); setLayout(new BorderLayout()); add(toolBar, BorderLayout.NORTH); add(container, BorderLayout.CENTER); } private ToolBar createToolBar(BrowserView browserView) { ToolBar toolBar = new ToolBar(browserView); toolBar.addPropertyChangeListener("TabClosed", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { firePropertyChange("TabClosed", false, true); } }); toolBar.addPropertyChangeListener("JSConsoleDisplayed", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { showConsole(); } }); toolBar.addPropertyChangeListener("JSConsoleClosed", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { hideConsole(); } }); return toolBar; } private void hideConsole() { showComponent(browserContainer); } private void showComponent(JComponent component) { container.removeAll(); container.add(component, BorderLayout.CENTER); validate(); } private void showConsole() { JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.add(browserContainer, JSplitPane.TOP); splitPane.add(jsConsole, JSplitPane.BOTTOM); splitPane.setResizeWeight(0.8); splitPane.setBorder(BorderFactory.createEmptyBorder()); showComponent(splitPane); } private JComponent createConsole() { JSConsole result = new JSConsole(browserView.getBrowser()); result.addPropertyChangeListener("JSConsoleClosed", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { hideConsole(); toolBar.didJSConsoleClose(); } }); return result; } private JComponent createBrowserContainer() { JPanel container = new JPanel(new BorderLayout()); container.add(browserView, BorderLayout.CENTER); return container; } public void dispose() { browserView.getBrowser().dispose(); } }