JDK-4479158 : Scrollable tab buttons of JTabbedPane don't work for special size of TabbedPane
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2001-07-12
  • Updated: 2001-07-14
  • Resolved: 2001-07-14
Related Reports
Duplicate :  
Description

Name: bsC130419			Date: 07/12/2001


java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)

I tried to use the new scrollable tabs feature of the JTabbedPane.
I had a JFrame which had a JTabbedPane in BorderLAyout.CENTER with x tabs
inside the JTabbedPane and the TabLayoutPolicy is SCROLL_TAB_LAYOUT.
Initially the width of the JTabbedPane is so that all tabs are fully displayed.
Then I reduce the width so that only x-1 tabs are fully displayed and you can't
see the last tab. Then I push the right button. Now you can see the last tab
(number x). After that I push the left button but nothing happens. There is no
way to get access to the first tab, only if I reduce the width of the
JTabbedPane once more to a size that is less than a certain value. I think this
value depends on the number of tabs and the width of the single tabs.
e.g.:
let N be the number of tabs
    Y be the width of each tab (each tab has the same width)
    Z be the width of the scrollable tab buttons
    W be the width of the JTabbedPane
The above behaviour is noticed only when the size of the JTabbedPane is less
than (N x Y) but still more than ((N-1 x Y) + Z). For a size less than ((N-1 x
Y) + Z) everthing works fine.

  To Reproduce the bug :

1) Compile and run the attached Java File.
2) Check the JCheckBox for 'scroll'.
3) Press the 'add' button four times.
4) Reduce the size of the frame, so that you can fully see only three tabs
(after the scrollable tab buttons are displayed)
5) Press the right scrollable tab button to display the last tab. Now you can
see three tabs, but not the first one.
6) Press the left scrollable tab button.
=> nothing happens; you still can't see the first tab.
7) Reduce the size of the frame once more, so that the last tab is not displayed
fully.
8) Press the right button twice.
9) Press the left button. Now you can see again the first tab.

Here is the sample code:

import javax.swing.UIManager;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Application1 {
  boolean packFrame = false;

  /**Construct the application*/
  public Application1() {
    Frame1 frame = new Frame1();
    //Validate frames that have preset sizes
    //Pack frames that have useful preferred size info, e.g. from their layout
    if (packFrame) {
      frame.pack();
    }
    else {
      frame.validate();
    }
    //Center the window
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    if (frameSize.height > screenSize.height) {
      frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
      frameSize.width = screenSize.width;
    }
    frame.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
    frame.setVisible(true);
  }
  /**Main method*/
  public static void main(String[] args) {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    new Application1();
  }
}


class Frame1 extends JFrame {
  JPanel contentPane;
  BorderLayout borderLayout1 = new BorderLayout();
  JTabbedPane jTabbedPane1 = new JTabbedPane();
  JLabel jLabel1 = new JLabel();
  JPanel jPanel1 = new JPanel();
  JCheckBox jCheckBox2 = new JCheckBox();
  JButton jButton1 = new JButton();
  int tabZaehler = 0;
  JButton jButton2 = new JButton();

  /**Construct the frame*/
  public Frame1() {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  /**Component initialization*/
  private void jbInit() throws Exception  {
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(borderLayout1);
    this.setSize(new Dimension(400, 300));
    this.setTitle("Frame Title");
    jLabel1.setText("Hier unter befindet sich ein JTabbedPane ");
    jPanel1.setLayout(null);
    jCheckBox2.setText("scroll");
    jCheckBox2.setBounds(new Rectangle(11, 2, 55, 25));
    jCheckBox2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jCheckBox2_actionPerformed(e);
      }
    });
    jPanel1.setPreferredSize(new Dimension(20, 30));
    jButton1.setFont(new java.awt.Font("Dialog", 0, 8));
    jButton1.setText("add");
    jButton1.setBounds(new Rectangle(74, 4, 47, 22));
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton1_actionPerformed(e);
      }
    });
    jButton2.setFont(new java.awt.Font("Dialog", 0, 8));
    jButton2.setMaximumSize(new Dimension(61, 23));
    jButton2.setMinimumSize(new Dimension(61, 23));
    jButton2.setPreferredSize(new Dimension(61, 23));
    jButton2.setText("size");
    jButton2.setBounds(new Rectangle(124, 3, 48, 22));
    jButton2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton2_actionPerformed(e);
      }
    });
    contentPane.add(jTabbedPane1, BorderLayout.CENTER);
    contentPane.add(jLabel1, BorderLayout.SOUTH);
    contentPane.add(jPanel1, BorderLayout.NORTH);
    jPanel1.add(jCheckBox2, null);
    jPanel1.add(jButton1, null);
    jPanel1.add(jButton2, null);
  }
  /**Overridden so we can exit when window is closed*/
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      System.exit(0);
    }
  }

  void jButton1_actionPerformed(ActionEvent e) {
    // nun mal noch ein tab hinzuf?gen
    String myString = "Reg. " + String.valueOf( tabZaehler );
    jTabbedPane1.add( myString, new JButton( myString) );
    tabZaehler ++;
  }

  void jCheckBox2_actionPerformed(ActionEvent e) {
    JCheckBox myCheckBox = (JCheckBox)e.getSource();
    if ( myCheckBox.isSelected() ) {
      jTabbedPane1.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
    }
    else {
      jTabbedPane1.setTabLayoutPolicy( JTabbedPane.WRAP_TAB_LAYOUT );
    }
  }

  void jButton2_actionPerformed(ActionEvent e) {
    System.out.println("The Frames size is: " + this.getSize() );
    System.out.println("The JTabbedPane width 'W' is: " + jTabbedPane1.getWidth
() );
    System.out.println("The tab width 'Y' is : " + jTabbedPane1.getBoundsAt
(0) );

  }
}
(Review ID: 127951) 
======================================================================

Comments
WORK AROUND Name: bsC130419 Date: 07/12/2001 none ======================================================================
11-06-2004

EVALUATION This was fixed as part of 4456754, refer to it for more information. scott.violet@eng 2001-07-13
13-07-2001