Results 1 to 8 of 8
  1. #1
    Semik is offline Member
    Join Date
    Sep 2011
    Posts
    5
    Rep Power
    0

    Question TabComponentsDemo java tutorial - ContainerListener problems

    Good evening. At first i apologize for my bad English.
    I have problems with TabComponentsDemo Using Swing Components: Examples (The Java™ Tutorials > Creating a GUI with JFC/Swing > Using Swing Components).
    I want to add ContainerListener to jTabbedPane in ButtonTabComponent as:
    Java Code:
    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));
           
    	    
    	.......	    
    
            pane.addContainerListener(new ContainerAdapter()
            {
                @Override
                public void componentRemoved(ContainerEvent e)
                {                
                   
                }
            });
        }  
    
    
    	.......	 
      
    }
    And problem, when i close any Tab with cross button, listener method componentRemoved is called multiple (4x, 5x..).


    If i add a ContainerListener to jTabbedPane outside class ButtonTabComponent, directly to jTabbedPane, it works correctly, method i called once.

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    It sounds like you've got a bug in your code that is causing you to add the listener more than once to the tab. If you can't figure it out with this information, you may need to post more code here. How much? Just enough to show the problem. ;-)

  3. #3
    Semik is offline Member
    Join Date
    Sep 2011
    Posts
    5
    Rep Power
    0

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    Yes, no problem, it's just tutorial example:

    ButtonTabComponent
    Java Code:
    package TabbedPane;
    
    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()
            {
                @Override
                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));
    
            pane.addContainerListener(new ContainerAdapter()
            {
                @Override
                public void componentRemoved(ContainerEvent e)
                {
                    System.out.println("componentRemoved");
                }
            });
        }
    
        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);
            }
    
            @Override
            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
            @Override
            public void updateUI()
            {
            }
    
            //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));
                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()
        {
            @Override
            public void mouseEntered(MouseEvent e)
            {
                Component component = e.getComponent();
                if (component instanceof AbstractButton) {
                    AbstractButton button = (AbstractButton) component;
                    button.setBorderPainted(true);
                }
            }
    
            @Override
            public void mouseExited(MouseEvent e)
            {
                Component component = e.getComponent();
                if (component instanceof AbstractButton) {
                    AbstractButton button = (AbstractButton) component;
                    button.setBorderPainted(false);
                }
            }
        };
    }
    Test JFrame
    Java Code:
    package TabbedPane;
    
    /*
     * TabComponentDemo.java requires one additional file:
     *   ButtonTabComponent.java
     */
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import java.awt.event.InputEvent;
    import java.awt.event.KeyEvent;
    
    /*
     * Creating and using TabComponentsDemo example  
     */
    public class TabComponentsDemo extends JFrame
    {
        private final int tabNumber = 5;
        private final JTabbedPane pane = new JTabbedPane();
        private JMenuItem tabComponentsItem;
        private JMenuItem scrollLayoutItem;
    
        public static void main(String[] args)
        {
            //Schedule a job for the event dispatch thread:
            //creating and showing this application's GUI.
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    //Turn off metal's use of bold fonts
                    UIManager.put("swing.boldMetal", Boolean.FALSE);
                    new TabComponentsDemo("TabComponentsDemo").runTest();
                }
            });
        }
    
        public TabComponentsDemo(String title)
        {
            super(title);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            initMenu();
            add(pane);
        }
    
        public void runTest()
        {
            pane.removeAll();
            for (int i = 0; i < tabNumber; i++) {
                String title = "Tab " + i;
                pane.add(title, new JLabel(title));
                initTabComponent(i);
            }
            tabComponentsItem.setSelected(true);
            pane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
            scrollLayoutItem.setSelected(false);
            setSize(new Dimension(400, 200));
            setLocationRelativeTo(null);
            setVisible(true);
        }
    
        private void initTabComponent(int i)
        {
            pane.setTabComponentAt(i, new ButtonTabComponent(pane));
        }
    
        //Setting menu
        private void initMenu()
        {
            JMenuBar menuBar = new JMenuBar();
            //create Options menu
            tabComponentsItem = new JCheckBoxMenuItem("Use TabComponents", true);
            tabComponentsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_MASK));
            tabComponentsItem.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    for (int i = 0; i < pane.getTabCount(); i++) {
                        if (tabComponentsItem.isSelected()) {
                            initTabComponent(i);
                        } else {
                            pane.setTabComponentAt(i, null);
                        }
                    }
                }
            });
            scrollLayoutItem = new JCheckBoxMenuItem("Set ScrollLayout");
            scrollLayoutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.ALT_MASK));
            scrollLayoutItem.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    if (pane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT) {
                        pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
                    } else {
                        pane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
                    }
                }
            });
            JMenuItem resetItem = new JMenuItem("Reset JTabbedPane");
            resetItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_MASK));
            resetItem.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    runTest();
                }
            });
    
            JMenu optionsMenu = new JMenu("Options");
            optionsMenu.add(tabComponentsItem);
            optionsMenu.add(scrollLayoutItem);
            optionsMenu.add(resetItem);
            menuBar.add(optionsMenu);
            setJMenuBar(menuBar);
        }
    }

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    As I assumed, you're adding the Listener to the JTabbedPane more than once, and in fact are doing so every time you add a ButtonTabComponent object to the JTabbedPane. The obvious solution is to do as you suggested: not add the listener from inside of ButtonTabComponent. Either that or you could always add an AncestorListener to your ButtonTabComponent object in its constructor and listen for the ancestorRemoved method:

    Java Code:
          addAncestorListener(new AncestorListener() {
             @Override
             public void ancestorRemoved(AncestorEvent event) {
                System.out.println("removed");
                System.out.println(event.getSource());
             }
             
             public void ancestorMoved(AncestorEvent event) {}
             public void ancestorAdded(AncestorEvent event) {}
          });

  5. #5
    Semik is offline Member
    Join Date
    Sep 2011
    Posts
    5
    Rep Power
    0

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    Yes, it is as you say. Problem solved, thank you very much.

  6. #6
    Semik is offline Member
    Join Date
    Sep 2011
    Posts
    5
    Rep Power
    0

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    Just one little question. Can i somehow determine index of previous selected tab (component) on jTabbedPane after i selected another ???

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    You'll need to keep tabs of the tab index yourself but you can detect a change in tab by adding a ChangeListener to the JTabbedPane or its model. When that happens, the old tab will be the one you saved in your int variable, and the new one will be obtainable by calling getSelectedIndex() on the pane or its model. Then store this variable in your int variable for the next time this happens.

  8. #8
    Semik is offline Member
    Join Date
    Sep 2011
    Posts
    5
    Rep Power
    0

    Default Re: TabComponentsDemo java tutorial - ContainerListener problems

    Yes, I have implemented this solution. I just did not know if there's a more compact solution. Thank you.

Similar Threads

  1. Mark Dexter persistence tutorial Junit problems
    By sonny in forum New To Java
    Replies: 9
    Last Post: 05-24-2010, 04:09 PM
  2. Sun java tutorial in pdf?
    By makpandian in forum New To Java
    Replies: 2
    Last Post: 06-29-2009, 09:25 PM
  3. Best Tutorial for Java GUI ?
    By Ms.Ranjan in forum New To Java
    Replies: 1
    Last Post: 09-13-2008, 01:22 AM
  4. Java 5 Tutorial
    By Ganeshag777 in forum New To Java
    Replies: 1
    Last Post: 08-18-2008, 06:38 PM
  5. Demonstrating the ContainerListener
    By Java Tip in forum java.awt
    Replies: 0
    Last Post: 04-23-2008, 08:22 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •