Browse Source

closeable Tab example

Jessey Widhalm 7 years ago
parent
commit
7b791399f3
3 changed files with 152 additions and 1 deletions
  1. 2 1
      .gitignore
  2. 148 0
      src/ui/view/ButtonTabComponent.java
  3. 2 0
      src/ui/view/GUI.java

+ 2 - 1
.gitignore

@@ -1 +1,2 @@
-
+bin/
+build/

+ 148 - 0
src/ui/view/ButtonTabComponent.java

@@ -0,0 +1,148 @@
+package ui.view;
+
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle or the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+import javax.swing.*;
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicButtonUI;
+import java.awt.*;
+import java.awt.event.*;
+ 
+/**
+ * Component to be used as tabComponent;
+ * Contains a JLabel to show the text and 
+ * a JButton to close the tab it belongs to 
+ */
+public class ButtonTabComponent extends JPanel {
+    private final JTabbedPane pane;
+ 
+    public ButtonTabComponent(final JTabbedPane pane) {
+        //unset default FlowLayout' gaps
+        super(new FlowLayout(FlowLayout.LEFT, 0, 0));
+        if (pane == null) {
+            throw new NullPointerException("TabbedPane is null");
+        }
+        this.pane = pane;
+        setOpaque(false);
+         
+        //make JLabel read titles from JTabbedPane
+        JLabel label = new JLabel() {
+            public String getText() {
+                int i = pane.indexOfTabComponent(ButtonTabComponent.this);
+                if (i != -1) {
+                    return pane.getTitleAt(i);
+                }
+                return null;
+            }
+        };
+         
+        add(label);
+        //add more space between the label and the button
+        label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
+        //tab button
+        JButton button = new TabButton();
+        add(button);
+        //add more space to the top of the component
+        setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
+    }
+ 
+    private class TabButton extends JButton implements ActionListener {
+        public TabButton() {
+            int size = 17;
+            setPreferredSize(new Dimension(size, size));
+            setToolTipText("close this tab");
+            //Make the button looks the same for all Laf's
+            setUI(new BasicButtonUI());
+            //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);
+        }
+ 
+        public void actionPerformed(ActionEvent e) {
+            int i = pane.indexOfTabComponent(ButtonTabComponent.this);
+            if (i != -1) {
+                pane.remove(i);
+            }
+        }
+ 
+        //we don't want to update UI for this button
+        public void updateUI() {
+        }
+ 
+        //paint the cross
+        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));
+            g2.setColor(Color.BLACK);
+            if (getModel().isRollover()) {
+                g2.setColor(Color.MAGENTA);
+            }
+            int delta = 6;
+            g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
+            g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
+            g2.dispose();
+        }
+    }
+ 
+    private final static 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);
+            }
+        }
+    };
+}
+

+ 2 - 0
src/ui/view/GUI.java

@@ -1584,7 +1584,9 @@ public class GUI<E> implements CategoryListener {
 		splitPane.setLeftComponent(scrollPane1);
 		splitPaneCanvasConsole.setLeftComponent(panelTapped_SimMenu);
 		tabbedPane.addTab("View", canvasSP);
+		tabbedPane.setTabComponentAt(0, new ButtonTabComponent(tabbedPane));
 		tabbedPane.addTab("Statistics", statScrollPane);
+		tabbedPane.setTabComponentAt(1, new ButtonTabComponent(tabbedPane));
 		
 		
 		splitPaneCanvasConsole.setRightComponent(console);