Author: kmorin Date: 2014-05-08 12:07:12 +0200 (Thu, 08 May 2014) New Revision: 2824 Url: http://forge.nuiton.org/projects/jaxx/repository/revisions/2824 Log: fixes #3189 [CustomTab] Add a button to close the custom tab Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java 2014-05-08 10:07:12 UTC (rev 2824) @@ -29,11 +29,14 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.util.beans.BeanUtil; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.UIManager; -import java.awt.Color; -import java.awt.Font; +import javax.swing.*; +import javax.swing.plaf.basic.BasicButtonUI; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -54,14 +57,20 @@ protected TabContentModel model; + protected TabContainerHandler handler; + protected JLabel title = new JLabel(); public TabContentModel getModel() { return model; } - public CustomTab(TabContentModel model) { + public CustomTab(TabContentModel model, TabContainerHandler handler) { + super(new FlowLayout(FlowLayout.LEFT, 0, 0)); + this.model = model; + this.handler = handler; + try { BeanUtil.addPropertyChangeListener( new PropertyChangeListener() { @@ -83,7 +92,15 @@ if (actionIcon != null) { title.setIcon(SwingUtil.createActionIcon(actionIcon)); } + title.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); add(title); + + if (model.isCloseable()) { + JButton button = new TabButton(); + add(button); + } + + setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); } @Override @@ -123,4 +140,79 @@ title.setFont(f.deriveFont(style)); } + protected class TabButton extends JButton implements ActionListener { + + public TabButton() { + int size = 17; + setPreferredSize(new Dimension(size, size)); + setToolTipText(t("jaxx.application.tab.customtab.close.label")); + //Make it transparent + setContentAreaFilled(false); + //No need to be focusable + setFocusable(false); + setBorder(BorderFactory.createEtchedBorder()); + setBorderPainted(false); + //Making nice rollover effect + //we use the same listener for all buttons + addMouseListener(buttonMouseListener); + setRolloverEnabled(true); + //Close the proper tab by clicking the button + addActionListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { +// if (tabbedPane != null) { +// if (i != -1) { +// tabbedPane.remove(i); +// } +// } + if (handler != null) { + JTabbedPane tabPanel = handler.getTabPanel(); + int i = tabPanel.indexOfTabComponent(CustomTab.this); + handler.removeTab(i); + } + } + + //paint the cross + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + + Graphics2D g2 = (Graphics2D) g.create(); + //shift the image for pressed buttons + if (getModel().isPressed()) { + g2.translate(1, 1); + } + g2.setStroke(new BasicStroke(2)); + if (getModel().isRollover()) { +// g2.setBackground(Color.MAGENTA); + g2.setColor(Color.MAGENTA); + } else { + g2.setColor(Color.BLACK); + } + int delta = 5; + g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1); + g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1); + g2.dispose(); + } + } + + private MouseListener buttonMouseListener = new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + Component component = e.getComponent(); + if (component instanceof AbstractButton) { + AbstractButton button = (AbstractButton) component; + button.setBorderPainted(true); + } + } + + public void mouseExited(MouseEvent e) { + Component component = e.getComponent(); + if (component instanceof AbstractButton) { + AbstractButton button = (AbstractButton) component; + button.setBorderPainted(false); + } + } + }; } Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java 2014-05-08 10:07:12 UTC (rev 2824) @@ -40,9 +40,11 @@ public class DelegateTabContainerHandler implements TabContainerHandler { final JTabbedPane tabbedPane; + final TabContainerHandler mainHandler; - public DelegateTabContainerHandler(JTabbedPane tabbedPane) { + public DelegateTabContainerHandler(JTabbedPane tabbedPane, TabContainerHandler mainHandler) { this.tabbedPane = tabbedPane; + this.mainHandler = mainHandler; } @Override @@ -70,7 +72,6 @@ }); } - @Override public boolean onTabChanged(int currentIndex, int newIndex) { boolean result = true; @@ -107,6 +108,17 @@ @Override public void setCustomTab(int index, TabContentModel model) { - getTabPanel().setTabComponentAt(index, new CustomTab(model)); + JTabbedPane tabPanel = getTabPanel(); + tabPanel.setTabComponentAt(index, new CustomTab(model, mainHandler)); } + + @Override + public boolean removeTab(int i) { + TabHandler tabHandler = getTabHandler(i); + boolean remove = tabHandler.onRemoveTab(); + if (remove) { + getTabPanel().removeTabAt(i); + } + return remove; + } } Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java 2014-05-08 10:07:12 UTC (rev 2824) @@ -65,4 +65,13 @@ * @param model */ void setCustomTab(int index, TabContentModel model); + + /** + * Removes the tab i + * @param i the index of the tab to remove + * @return <code>false</code> if you want to prevent the tab close, + * <code>true</code> otherwise + */ + boolean removeTab(int i); + } Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java 2014-05-08 10:07:12 UTC (rev 2824) @@ -41,4 +41,6 @@ String getTitle(); String getIcon(); + + boolean isCloseable(); } Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java 2014-05-08 10:07:12 UTC (rev 2824) @@ -49,4 +49,12 @@ * @param newIndex */ void onShowTab(int currentIndex, int newIndex); + + /** + * Method called when the tab is removed + * + * @return <code>false</code> to prevent the tab to be closed, + * <code>true</code> otherwise. + */ + boolean onRemoveTab(); } Modified: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java 2014-05-08 10:07:12 UTC (rev 2824) @@ -101,6 +101,24 @@ return desktop; } + public static Desktop getDesktopForOpen() { + + if (!Desktop.isDesktopSupported()) { + throw new ApplicationTechnicalException( + t("jaxx.application.error.desktop.not.supported")); + } + + Desktop desktop = Desktop.getDesktop(); + + if (!desktop.isSupported(Desktop.Action.OPEN)) { + + throw new ApplicationTechnicalException( + t("jaxx.application.error.desktop.open.not.supported")); + } + + return desktop; + } + public static void openLink(URI uri) { Desktop desktop = getDesktopForBrowse(); Modified: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties =================================================================== --- trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties 2014-05-08 10:07:12 UTC (rev 2824) @@ -18,4 +18,5 @@ jaxx.application.error.ui.business.warning= jaxx.application.error.ui.other.error= jaxx.application.message.action.running= +jaxx.application.tab.customtab.close.label= jaxx.application.title.actionUI= Modified: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties =================================================================== --- trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties 2014-05-08 10:07:12 UTC (rev 2824) @@ -18,4 +18,5 @@ jaxx.application.error.ui.business.warning= jaxx.application.error.ui.other.error= jaxx.application.message.action.running= +jaxx.application.tab.customtab.close.label= jaxx.application.title.actionUI= Modified: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties =================================================================== --- trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties 2014-03-25 12:23:43 UTC (rev 2823) +++ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties 2014-05-08 10:07:12 UTC (rev 2824) @@ -18,4 +18,5 @@ jaxx.application.error.ui.business.warning=Avertissement jaxx.application.error.ui.other.error=Erreur jaxx.application.message.action.running=<html>Action <strong>%s</strong> en cours d'exécution...</html> +jaxx.application.tab.customtab.close.label=Fermer l'onglet jaxx.application.title.actionUI=%s - v %s [%s]