3

I have a JTabbedPane with a custom tab component. That component contains a JLabel (To display the tab title) and a JButton (A close button). When I change the text in the JLabel the JLabel stops receiving mouse events and I can no longer select that tab when I click directly on the label instead if I click around the label then I can select the tab. Any ideas?

A snippet of the code:

class ShellPanelTabComponent extends JPanel implements ActionListener{

    private ShellPanel panel;
    private JLabel label;

    public ShellPanelTabComponent(final ShellPanel panel){
      super(new FlowLayout(FlowLayout.LEFT, 0, 0));
      this.panel = panel;
      setOpaque(false);

      label = new JLabel(panel.getTitle());
      label.setFocusable(false);
      add(label);
      label.setBorder(BorderFactory.createEmptyBorder(2,0,0,5));

      //now the button
      CloseButton closeButton = new CloseButton(panel);
      add(closeButton);
      closeButton.addActionListener(this);
    }

    public void actionPerformed(ActionEvent ae) {
      panel.getShell().removeShellPanel(panel);
    }

    /**
     * @return the label
     */
    public JLabel getLabel() {
      return label;
    }
  }
Sandro
  • 2,219
  • 4
  • 27
  • 41

3 Answers3

2

I don't recall seeing such a problem in the TabComponentsDemo, discussed in How to Use Tabbed Panes. You might compare your code with that example as a reference.

Addendum: Re-factoring ButtonTabComponent to include getLabel(), this version of runTest() in TabComponentsDemo adds a button that evinces the desired behavior. In particular, each time the button is pressed, the tabs are redrawn to display the enlarged title.

Update: Modify correct tab component after pane.remove().

public void runTest() {
    pane.removeAll();
    for (int i = 0; i < tabNumber; i++) {
        final int titleIndex = i;
        String title = "Tab " + titleIndex;
        final JButton button = new JButton("Relabel tab");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int index = pane.indexOfComponent(button);
                ButtonTabComponent btc = (ButtonTabComponent)
                    pane.getTabComponentAt(index);
                JLabel label = btc.getLabel();
                pane.setTitleAt(index, label.getText() + titleIndex);
                label.invalidate();
                pane.repaint();
            }
        });
        pane.add(title, button);
        initTabComponent(i);
    }
    tabComponentsItem.setSelected(true);
    pane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT);
    scrollLayoutItem.setSelected(false);
    this.setPreferredSize(new Dimension(500, 200));
    this.pack();
    this.setLocationRelativeTo(null);
    this.setVisible(true);
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • That was the example that my code was originally based on. The problem is that the JLabel that they used displayed the text by overriding the getText() method in the JLabel class. While this doesn't have the mouseclick issue,it has the problem of not resizing the tab when the text is changed. This ends up giving me tabs with cutoff titles. Is there a solution for that? – Sandro Jul 01 '10 at 14:47
  • @Sandro: Looking closer at `TabComponentsDemo`, an implicit `validate()` occurs as a result of the call to `setVisible()` in `runTest()`. – trashgod Jul 01 '10 at 19:30
  • I'm still getting the same behavior even with the validate. – Sandro Jul 02 '10 at 14:41
  • @Sandro: Any chance you're inadvertently replacing the label, rather than modifying it? – trashgod Jul 02 '10 at 15:41
  • I ended up figuring out that the problem is related to the issue that I posted here: http://stackoverflow.com/questions/3198037/workaround-for-settooltiptext-consuming-mouse-events – Sandro Jul 08 '10 at 12:35
  • @Sandro: I've updated the example for anyone else who might need it. It seems to handle tool tips correctly. – trashgod Jul 09 '10 at 01:03
2

I seem to remember a question like this recently although I can't find the posting. I believe the problem is that the "custom component" receives the mouse event so it is not passed on to the tabbed pane. The solution suggested was to use the dispatchEvent(...) method to redispatch the mouse event to the proper tab.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Oh ok this sounds close. Who can I dispatch it to so that it goes to the right place? – Sandro Jul 01 '10 at 15:04
  • This is what I actually did. To clarify: My problem: Had a tabbedpane with a custom heading. Heading contained a label and a button. Added a listener to the heading to make the tab get funky when double clicked. This made it so s.t. you could not switch tabs anymore. My solution: Make each method of said mouse listener dispatch the event to the JTabbedPane if the event was not used with the following line: container.dispatchEvent(SwingUtilities.convertMouseEvent(ModelTab.this, e, container)); ModelTab was my "heading" component, container the JTabbedPane. HTH. – bobismijnnaam Sep 19 '16 at 17:27
0

The problem is related to the one that I posted here after I did more digging: Workaround for setToolTipText consuming mouse events?

Community
  • 1
  • 1
Sandro
  • 2,219
  • 4
  • 27
  • 41