Skip to Main Content

Oracle Database Discussions

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.

IBM HACMP Support on Database 10G

491815Feb 18 2006
Hello,

Is IBM HACMP v5.3 certified for Oracle Database 10g.

Comments

843805
You could have a non-opaque JPanel above your panel in an Overlay Layout and draw on it with an AlphComposite for a "dimming" affect. Also check out the JProgressBar and ProgressMonitor classes. The Swing tutorial has a page in which these are discussed: How to Use Progress Bars.
843805
Another option is using a glass pane above the app and do the same thing that crwood mentioned (alpha composite painting, JProgressBars, etc).
843805
Personally, I like crwood's suggestion. Extend JPanel, override the paintComponent method, and paint a partially transparent rectangle over the entire thing.

However, beware of this problem: Most Component subclasses have asynchronous repaint methods (such as JPanel and JLabel). That means that the work of actually painting each pixel runs in another thread, which usually doesn't finish until other operations are complete. In other words, your screen dimming and loading data message may not occur until after the data has already been loaded.

To solve this problem, call the Components's paintImmediately method right after you display the it. That forces the paint operation to be executed in the same thread, so the desired action will occur BEFORE the data starts loading (which is the behavior you are trying to create). Note, that JProgressBar is immune from this problem.

I fought this issue for hours, so I'm just giving you the heads up.

Hope it helps,
Bill

PS: A lot more info is available here: http://java.sun.com/products/jfc/tsc/articles/painting/ . Pay attention to the stuff about synchronization and threads.
camickr
Personally, I like crwood's suggestion. Extend JPanel, override the paintComponent method....
That is what a GlassPane is for. You create the panel as described. Then you use:

frame.setGlassPane(...);
To solve this problem, call the Components's paintImmediately method...
The real problem is that you are trying to execute a long running task in the GUI Event Thread. The long running task should execute in its own Thread so the GUI is free to repaint itself.
How to display "Loading data..." to the user
If you really want to display some text, then you should probably be using an indeterminate progress bar since is displays an actual window with borders. If you just try to write text on the JPanel or GlassPane, you never know what you will be painting over unless you customize the painting to fill in the background before you write the text.
843805
That is what a GlassPane is for. You create the panel
as described. Then you use:
frame.setGlassPane(...);
The glass pane will work fine too. I'd choose the overlay approach simply because it allows me to create a JPanel subclass DimmableJPanel that doesn't rely on a JFrame to help. For the benefit of the OP, heres a link that explains the glass pane: http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html
The real problem is that you are trying to execute a
long running task in the GUI Event Thread. The long
running task should execute in its own Thread so the
GUI is free to repaint itself.
Yep. Thats why repaint starts a new thread. But in this case, the text has to be painted before starting a new task, hence the call to paintImmediately. JProgressBar does the same thing, because progress bars have to be updated in real time.
If you really want to display some text, then you
should probably be using an indeterminate progress
bar since is displays an actual window with borders.
If you just try to write text on the JPanel or
GlassPane, you never know what you will be painting
over unless you customize the painting to fill in the
background before you write the text.
Right. But if you don't want to use an indeterminate progress bar, you can recreate that same behavior with a JLabel and paintImmediately. (Yes, you do have to accept responsibility for the background if you don't repaint the entire JPanel.)

- Bill
camickr
I'd choose the overlay approach simply because it allows me to
create a JPanel subclass DimmableJPanel that doesn't rely on a JFrame to help
Don't understand this statement. How do you show a DimmableJPanel overtop of an existing panel?
But in this case, the text has to be painted before starting a new task, hence the call to paintImmediately.
There is no need to use paintImmediately. You update the GUI component. Then you start a separate Thread for the long running task. The GUI is free to repaint the label or whatever. Yes, technically you may have to wait milliseconds (over using paintImmediately), but the user will see no difference. paintImmediately is not recommended to be used. The RepaintManager manages paint requests and consolidates multiple paint requests into one for efficiency reasons. Using paintImmediately overrides the default behaviour and is not needed in this situation.
Right. But if you don't want to use an indeterminate progress bar, you
can recreate that same behavior with a JLabel and paintImmediately.
The point is not to recreate code, but to use the code that is available.

I was also suggesting that a progress bar is a dialog that only covers a certain amount of space. A disable panel would cover the entire frame. So it depends on the look that the user is going for.

Here is an example of a disable GlassPane:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

public class DisabledGlassPane extends JComponent
	implements KeyListener
{
	private final static Color DEFAULT_BACKGROUND = new Color(128, 128, 128, 128);
	private final static Border MESSAGE_BORDER = new EmptyBorder(10, 10, 10, 10);

	private JLabel message = new JLabel();

	public DisabledGlassPane()
	{
		setOpaque( false );
		setBackground( DEFAULT_BACKGROUND );
		setLayout( new GridBagLayout() );
		add(message, new GridBagConstraints());

		message.setOpaque(true);
		message.setBorder(MESSAGE_BORDER);

		//  Disable Mouse, Key and Focus events for the glass pane

		addMouseListener( new MouseAdapter() {} );
		addMouseMotionListener( new MouseMotionAdapter() {} );

		addKeyListener( this );

        setFocusTraversalKeys(
            KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET );
        setFocusTraversalKeys(
            KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET );
	}

	protected void paintComponent(Graphics g)
	{
		g.setColor( getBackground() );
		g.fillRect(0, 0, getSize().width, getSize().height);
	}

	public void setBackground(Color background)
	{
		super.setBackground( background );

		Color messageBackground =
			new Color(background.getRed(), background.getGreen(), background.getBlue());
		message.setBackground( messageBackground );
	}

	public void keyPressed(KeyEvent e)
	{
		e.consume();
	}

	public void keyTyped(KeyEvent e)
	{
		e.consume();
	}
	public void keyReleased(KeyEvent e)
	{
		e.consume();
	}

	public void activate(String text)
	{
		if  (text != null && text.length() > 0)
		{
			message.setVisible( true );
			message.setText( text );
			message.setForeground( getForeground() );
		}
		else
			message.setVisible( false );

		setVisible( true );
		setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
		requestFocusInWindow();
	}

	public void deactivate()
	{
		setCursor(null);
		setVisible( false );
	}

	public static void main(String[] args)
	{
		final DisabledGlassPane glassPane = new DisabledGlassPane();
		glassPane.setBackground( new Color(255, 128, 128, 128) );
		glassPane.setForeground( Color.WHITE );

		final JButton button = new JButton( "Click Me" );
		button.setMnemonic('c');
		button.addActionListener( new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				glassPane.activate("Please Wait...");

				Thread thread = new Thread()
				{
					public void run()
					{
						try { this.sleep(5000); }
						catch (InterruptedException ie) {}

						glassPane.deactivate();
					}
				};
				thread.start();
			}
		});

		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setGlassPane( glassPane );
		frame.getContentPane().add(new JLabel("NORTH"), BorderLayout.NORTH );
		frame.getContentPane().add( button );
		frame.getContentPane().add(new JTextField(), BorderLayout.SOUTH);
		frame.setSize(300, 300);
		frame.setLocationRelativeTo( null );
		frame.setVisible(true);
	}
}
843805
hi codebook, using a glasspane is not a viable option for me, because i want to display the Loading data on only one of the panels in the frame.

vani
843805
Hi All,
i went through all of your reply and unfortunately only a part of the screen is being updated and only that panel need to show the "Loading Data..." message not the whole screen. So i can not use the glass pane nad block the whole screen.

If some one knows how to update only a part of the screen, that would be very helpful.

vani
843805
Is there a way to set the Z order of the Panels in the Overlay layout?
How can i choose the Panel whoich should be showing on top?

thanks
843805
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class DimOverlay {
    DimmerPanel dimmerPanel;
 
    private JPanel getContent() {
        dimmerPanel = new DimmerPanel();
        JPanel content = new JPanel(new BorderLayout());
        JLabel label = new JLabel("graphical data", JLabel.CENTER);
        content.add(label);
        JPanel panel = new JPanel();
        OverlayLayout overlay = new OverlayLayout(panel);
        panel.setLayout(overlay);
        panel.add(dimmerPanel);
        panel.add(content);
        return panel;
    }
 
    private void reload() {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                int count = 0;
                boolean workAway = true;
                while(workAway && count <= 10) {
                    try {
                        Thread.sleep(1000);
                    } catch(InterruptedException e) {
                        workAway = false;
                    }
                    System.out.println("count = " + count++);
                }
                dimmerPanel.clearView();
            }
        });
        thread.setPriority(Thread.NORM_PRIORITY);
        thread.start();
        dimmerPanel.dimView();
    }
 
    private JPanel getControl() {
        JButton reload = new JButton("reload");
        reload.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reload();
            }
        });
        JPanel panel = new JPanel();
        panel.add(reload);
        return panel;
    }
 
    public static void main(String[] args) {
        DimOverlay test = new DimOverlay();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(test.getContent());
        f.getContentPane().add(test.getControl(), "Last");
        f.setSize(400,400);
        f.setLocation(200,200);
        f.setVisible(true);
    }
}
 
class DimmerPanel extends JPanel {
    float alpha = 0.0f;
 
    public DimmerPanel() {
        setOpaque(false);
    }
 
    public void dimView() {
        alpha = 0.25f;
        repaint();
    }
 
    public void clearView() {
        alpha = 0.0f;
        repaint();
    }
 
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        AlphaComposite ac =
            AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
        g2.setComposite(ac);
        g2.setPaint(Color.gray);
        g2.fillRect(0, 0, getWidth(), getHeight());
    }
}
843805
Thanks Crwood, this solution is perfect,
I ran it as a seperate program and worked great.
Unfortunately when i did the same thing in my application the dimmerpanel does not show up for some reason.

The Panel i am trying these, which is overlay laid out is inside a Tab Panel. I dont know if that is the reaon, why i dont see the DimmerOPanel at all when i call dimview()

Thanks a lot though, i am transferring Duke dollars

vani
843805
laid out ... inside a Tab Panel
Having the panel which has the Overlay layout manager and containing the graphic component below the non&#8211;opaque component added to the tabbedPane as a (tab) component. This should be okay. As long as you have a reference to the overlay component and can properly access it, it should work. The order in which you add the two components in the OverlayLayout is crucial. I can never remember the order and have to play with them to get it right. You can set the alpha value to 1.0f to see if it is showing over the graphic, lower component. It should cover it in the color you have set for fillRect. Also, you can put a System.out.println statement in the while loop in the reload method to print count to check if the loop is running/working.
1 - 12
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Mar 18 2006
Added on Feb 18 2006
0 comments
183 views