Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4199382
Votes 0
Synopsis Swing Menus - text/icon/checkmark alignment schemes severely broken
Category java:classes_swing
Reported Against 1.4.2 , 1.2fcs , tiger-beta , swing1.0fcs
Release Fixed
State 11-Closed, duplicate of 4729669, bug
Priority: 3-Medium
Related Bugs 4113639 , 4907679 , 4992232 , 4991598 , 4729669
Submit Date 22-DEC-1998
Description




When a menu pops up - from a right-click, JMenuBar, or whatever, the individual items in the list should follow some basic alignment rules so that the
whole menu appears consistent.
  - WinLF - Extra space is allocated along the left edge of the menu for the check/radio mark for any potentially present JCheckBoxMenuItem or
JRadioButtonMenuItem components even if there are none. By convention on Win32, the checkmark in a menu is actually a depressed button
representation of the menuitem's icon (if any), and it appears in the same 'column' as the icons for other non-check items.
  If no icon is supplied by the JCheckBoxMenuItem, a default checkmark icon should be used.  The text should be left aligned for the whole menu.
The accelerators (called 'shortcuts' in Win32) should also be left-aligned along the right side of the menu (bug #4113639) for the entire menu.  This
should look and feel like a native Win32 application.
  - JLF - Similar problems with WinLF: Wasted space, and text should line up.
  - MotifLF - Slightly better than JLF/WinLF - less wasted space, but text is still not lined up between check (bug #4133790), radio, and regular items.
(Review ID: 48242)
======================================================================
Work Around
N/A
Evaluation
This is partially fixed (by weddie) for Kestrel RC.  The part that is fixed
is the Accelerator text allighnment into a second column.  Still left is any
fix to the checkbox/Icon alignment scheme.  Code used to test included:


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


public class AccTest extends JFrame implements ActionListener{

  private String title;


  public AccTest(String title) {
    this.title = title;
    
    buildGUI();
  }


  private void buildGUI() {
    this.setSize(400, 400);
    this.setTitle(this.title);
    this.getContentPane().setLayout(new java.awt.FlowLayout() );

    //Create menus
    JMenuBar menubar = new JMenuBar();

    JMenu menu1 = new JMenu("File");
    JMenu menu2 = new JMenu("Options and other Stuff");
    JMenu submenu = new JMenu("SubWay!");
    submenu.setIcon(new ImageIcon("paste.gif"));

    //Menu 1
    JMenuItem openItem = new JMenuItem("Open");
    openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, ActionEvent.ALT_MASK+ ActionEvent.CTRL_MASK ));

    JMenuItem newItem = new JMenuItem("New Stuff and other stuff too", new ImageIcon("new.gif") );
    //newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, ActionEvent.ALT_MASK + ActionEvent.CTRL_MASK));

    JMenuItem quitItem = new JMenuItem("Quit");
    quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK));
    quitItem.setActionCommand("exit");
    quitItem.addActionListener(this);

    menu1.add(openItem);
    menu1.add(newItem);
    menu1.add(new JSeparator());
    menu1.add(quitItem);


    //Menu2
    JCheckBoxMenuItem checkItem = new JCheckBoxMenuItem("Check this out!");
    checkItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.ALT_MASK + ActionEvent.SHIFT_MASK + ActionEvent.CTRL_MASK));
    checkItem.setEnabled(false);
    JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem("Video killed the radio star!");

    JMenuItem normItem = new JMenuItem("Normal");

    JMenuItem iconItem = new JMenuItem("Iconize it!", new ImageIcon("cut.gif"));
    iconItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, ActionEvent.CTRL_MASK));

    menu2.add(checkItem);
    menu2.add(radioItem);
    menu2.add(normItem);
    menu2.add(new JSeparator());
    menu2.add(iconItem); 

    
    
    //SubMenu
    JMenuItem item1 = new JMenuItem("First SubMenuItem");
    
    submenu.add(item1);
    submenu.add(new JSeparator());

    menu2.add(submenu);

    menubar.add(menu1);
    menubar.add(menu2);
    
    this.setJMenuBar(menubar);


    //Create buttons for change of LNF
    JButton winButton = new JButton("Windows");
    JButton motifButton = new JButton("Motif");
    JButton metalButton = new JButton("Metal");
    JButton macButton = new JButton("Mac"); 

    winButton.addActionListener(this);
    motifButton.addActionListener(this);
    metalButton.addActionListener(this);
    macButton.addActionListener(this);

    winButton.setActionCommand("windows");
    motifButton.setActionCommand("motif");
    metalButton.setActionCommand("metal");
    macButton.setActionCommand("mac");

    this.getContentPane().add(winButton);
    this.getContentPane().add(motifButton);
    this.getContentPane().add(metalButton);
    this.getContentPane().add(macButton);
  }
    
  
  public void actionPerformed(ActionEvent e) {
    String lnfName = null;
    
    if(e.getActionCommand().equals("exit")) {
      this.dispose();
      System.exit(0);
    }
    else { 
      if(e.getActionCommand().equals("windows")) {
	lnfName = 
	  "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
      }
      else if(e.getActionCommand().equals("motif")) {
	lnfName = 
	  "com.sun.java.swing.plaf.motif.MotifLookAndFeel";	
      }
      else if(e.getActionCommand().equals("metal")) {
	lnfName = "javax.swing.plaf.metal.MetalLookAndFeel";
	  }
      else if(e.getActionCommand().equals("mac")) {
	lnfName = "com.sun.java.swing.plaf.mac.MacLookAndFeel";
	  }
      try {
	UIManager.setLookAndFeel(lnfName);
	SwingUtilities.updateComponentTreeUI(this);
      } 
      catch (Exception exc) {
	System.err.println("Could not load LookAndFeel: " + lnfName);
      }
    }
  }       



  public static void main(String[] args) {

    (new AccTest("TestFrame") ).show();

  }

}

 xxxxx@xxxxx  1999-10-18




We now left-align accelerator keys, but text is still not aligned.
To align text, we need to know if there is an item in the menu which
has check icon. If such item exists, we have to indent text in all
the other menu items.

We can calculate maximum check icon width across all menu items and
then indent text accordingly.

 xxxxx@xxxxx  2002-02-20

======================================================================

Currently all the development for this issue is concentrated in the bug 4729669. I'm closing this one as a duplicate of 4729669.
 xxxxx@xxxxx  2004-09-29
Comments
  
  Include a link with my name & email   

Submitted On 01-FEB-2001
kuhse
Come on, "weddie", fix the rest too!


Submitted On 05-FEB-2001
grishav
Please test also this stuff in right-to-left menus
(after use of setComponentOrientation()).
The alignment is absolutely terrible!


Submitted On 05-JAN-2003
snebeling
Still left to be fixed:
If (in the same menu) one menu item has an icon set
while another hasn't, the text of the two menu items
isn't aligned.


Submitted On 18-MAY-2004
Oleg.S.Estehin
Fix it!



PLEASE NOTE: JDK6 is formerly known as Project Mustang