Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

ComboBox scroll and selected/highlight on glasspane

843806Jul 19 2008 — edited Dec 17 2008
I'm using JInternalFrame as a modal frame( we couldn't use JDialog).
For that I used an example that i found on net, which in this way the JInternalFrame is added to GlassPane of JFrame .

On JInternalFrame there is a JComboBox.
When I drag its scrollpad and move it up and down (to see items in Combo box), content moves ok, but scrollpad stays fixed on one place (instead of going up and down too).
Also, when mouse points an item, it's not highlighted.

After browsing the web and this forum i found 2 threads about this but no answer.

Does anyone have a solution for that?

Sample code:
/*
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.beans.*;

public class ModalInternalFrame extends JInternalFrame {

  private static final JDesktopPane glass = new JDesktopPane();
  
  public ModalInternalFrame(String title, JRootPane 
      rootPane, Component desktop) {
    super(title);

    // create opaque glass pane    
    glass.setOpaque(false);
    glass.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);

    // Attach mouse listeners
    MouseInputAdapter adapter = new MouseInputAdapter(){};
    glass.addMouseListener(adapter);
    glass.addMouseMotionListener(adapter);
   
    desktop.validate(); 
    try {
      setSelected(true);
    } catch (PropertyVetoException ignored) {
    }

    // Add modal internal frame to glass pane
    glass.add(this);

    // Change glass pane to our panel
    rootPane.setGlassPane(glass);

  }
  
    @Override
  public void setVisible(boolean value) {
    super.setVisible(value);
    // Show glass pane, then modal dialog
    if(glass != null)
        glass.setVisible(value);    
    if (value) {
      startModal();
    } else {
      stopModal();
    }
  }

  private synchronized void startModal() {
        
    try {
      if (SwingUtilities.isEventDispatchThread()) {
        EventQueue theQueue = 
          getToolkit().getSystemEventQueue();
        while (isVisible()) {
          AWTEvent event = theQueue.getNextEvent();
          Object source = event.getSource();
          if (event instanceof ActiveEvent) {              
            ((ActiveEvent)event).dispatch();
          } else if (source instanceof Component) {
              ((Component)source).dispatchEvent(event);                            
          } else if (source instanceof MenuComponent) {              
            ((MenuComponent)source).dispatchEvent(
              event);
          } else {
            System.out.println(
              "Unable to dispatch: " + event);
          }
        }
      } else {
        while (isVisible()) {
          wait();
        }
      }
    } catch (InterruptedException ignored) {
    }
  }
  
  private synchronized void stopModal() {
    notifyAll();
  }

  public static void main(String args[]) {
  
      final JFrame frame = new JFrame(
      "Modal Internal Frame");
    frame.setDefaultCloseOperation(
      JFrame.EXIT_ON_CLOSE);

    final JDesktopPane desktop = new JDesktopPane();
    
    ActionListener showModal = 
        new ActionListener() {
      Integer ZERO = new Integer(0);
      Integer ONE = new Integer(1);
      public void actionPerformed(ActionEvent e) {

        // Construct a message internal frame popup
        final JInternalFrame modal = 
          new ModalInternalFrame("Really Modal", 
          frame.getRootPane(), desktop);
          
        JTextField text = new JTextField("hello");
        JButton btn = new JButton("close");
        JComboBox cbo = new JComboBox(new String[]{"-01-", "-02-", "-03-", "-04-", "-05-", "-06-", "-07-", "-08-", "-09-", "-10-", "-11-", "-12-"});
        
        btn.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        modal.setVisible(false);
                    }
                });
                
        cbo.setLightWeightPopupEnabled(false);
        Container iContent = modal.getContentPane();
        iContent.add(text, BorderLayout.NORTH);
        iContent.add(cbo, BorderLayout.CENTER);        
        iContent.add(btn, BorderLayout.SOUTH);
        //modal.setBounds(25, 25, 200, 100);
        modal.pack();
        modal.setVisible(true);     
        
      }
    };
    
    JInternalFrame jif = new JInternalFrame();
    jif.setSize(200, 200);
    desktop.add(jif);
    jif.setVisible(true);
    JButton button = new JButton("Open");
    button.addActionListener(showModal);

    Container iContent = jif.getContentPane();
    iContent.add(button, BorderLayout.CENTER);
    jif.setBounds(25, 25, 200, 100);
    jif.setVisible(true);
    
    Container content = frame.getContentPane();
    content.add(desktop, BorderLayout.CENTER);
    frame.setSize(500, 300);
    frame.setVisible(true);
  }
  
}

Comments

camickr
I'm using JInternalFrame as a modal frame( we couldn't use JDialog).
Why? How is a modal JInternalFrame different than a modal JDialog?
843806
camickr wrote:


Why? How is a modal JInternalFrame different than a modal JDialog?
JDialog does NOT bound to the desktop area so that a user can move JDialog anywhere in a screen.
JDialog appearance is not same as the other window (JInternalFrame(s)) in the application.
800774
This is a bug, and there are several open bugs on the same subject.
The only pop up that works in this situation is a heavy weight pop up.

There are 3 types of pop up windows: light weight, medium weight and heavy weight.
When you call setLightWeightPopupEnabled(false) the combo box uses the medium weight when the pop up window is inside the application frame, and heavy weight when the window exceeds the frame bounds.

There is no easy way to force the pop up to heavy weight, since most of the functions and fields in the relevant classes are private.
But you can use reflection to access them.
Here is one solution (tested and working with JDK 5) - adding the client property forceHeavyWeightPopupKey from PopupFactory to your combo box.
...
cbo.setLightWeightPopupEnabled(false);
try {					
	Class cls = Class.forName("javax.swing.PopupFactory");
	Field field = cls.getDeclaredField("forceHeavyWeightPopupKey");
	field.setAccessible(true);
	cbo.putClientProperty(field.get(null), Boolean.TRUE);
} catch (Exception e1) {e1.printStackTrace();}
...
843806
Many tanks for your answer Rodney_McKay.
It works fine.
843806
If the modalInternalFrame is resized, reshape() is invoked and it does something like stopModal().
// Add modal internal frame to glass pane
this.setResizable(true);
glass.add(this);
It is also strange that the existing menus/ frames are covered by the glass.
843806
I have this Same issue however I am stuck at 1.4.2 and it seems this property pointed out by Rodney_McKay does not exist.
Rodney_McKay wrote:
Here is one solution (tested and working with JDK 5) - adding the client property forceHeavyWeightPopupKey from PopupFactory to your combo box.
Does anyone know if there is a workaround available for 1.4.2? Also, I am using this code in a JApplet if that makes a differnce.
darrylburke
theSchaef

Please don't post in threads that are long dead. When you have a question, start your own topic. Feel free to provide a link to an old post that may be relevant to your problem.

I'm locking this thread now. It's about 5 months old.

db
1 - 7
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jan 14 2009
Added on Jul 19 2008
7 comments
781 views