Results 1 to 8 of 8
- 09-19-2011, 10:41 PM #1
Member
- Join Date
- Sep 2011
- Posts
- 5
- Rep Power
- 0
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:
And problem, when i close any Tab with cross button, listener method componentRemoved is called multiple (4x, 5x..).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) { } }); } ....... }
If i add a ContainerListener to jTabbedPane outside class ButtonTabComponent, directly to jTabbedPane, it works correctly, method i called once.
-
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. ;-)
- 09-19-2011, 10:57 PM #3
Member
- Join Date
- Sep 2011
- Posts
- 5
- Rep Power
- 0
Re: TabComponentsDemo java tutorial - ContainerListener problems
Yes, no problem, it's just tutorial example:
ButtonTabComponent
Test JFrameJava 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); } } }; }
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); } }
-
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) {} });
- 09-19-2011, 11:26 PM #5
Member
- Join Date
- Sep 2011
- Posts
- 5
- Rep Power
- 0
Re: TabComponentsDemo java tutorial - ContainerListener problems
Yes, it is as you say. Problem solved, thank you very much.
- 09-20-2011, 12:06 AM #6
Member
- Join Date
- Sep 2011
- Posts
- 5
- Rep Power
- 0
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 ???
-
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.
- 09-20-2011, 01:32 AM #8
Member
- Join Date
- Sep 2011
- Posts
- 5
- Rep Power
- 0
Similar Threads
-
Mark Dexter persistence tutorial Junit problems
By sonny in forum New To JavaReplies: 9Last Post: 05-24-2010, 04:09 PM -
Sun java tutorial in pdf?
By makpandian in forum New To JavaReplies: 2Last Post: 06-29-2009, 09:25 PM -
Best Tutorial for Java GUI ?
By Ms.Ranjan in forum New To JavaReplies: 1Last Post: 09-13-2008, 01:22 AM -
Java 5 Tutorial
By Ganeshag777 in forum New To JavaReplies: 1Last Post: 08-18-2008, 06:38 PM -
Demonstrating the ContainerListener
By Java Tip in forum java.awtReplies: 0Last Post: 04-23-2008, 08:22 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks