001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.node.screensaver;
020
021import java.awt.*;
022
023import javax.swing.JFrame;
024
025/**
026 * This extension of JFrale ensures that the frame is brought to the fore,
027 * on top of any other window, when {@code toFront()} is called.
028 * @author Laurent Cohen
029 */
030public class FocusedJFrame extends JFrame {
031  /**
032   * Explicit serialVersionUID.
033   */
034  private static final long serialVersionUID = 1L;
035  /**
036   * Use to avoid inifinite recursion in {@code toFront()}.
037   */
038  private boolean alreadyCalled = false;
039  /**
040   * Default initialization for this frame.
041   * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} returns {@code true}.
042   */
043  public FocusedJFrame() throws HeadlessException {
044    super();
045  }
046
047  /**
048   * Initialize this frame with the specified title.
049   * @param title the title displayed in the frmae caption.
050   * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()} returns {@code true}.
051   */
052  public FocusedJFrame(final String title) throws HeadlessException {
053    super(title);
054  }
055
056  @Override
057  public void setVisible(final boolean visible) {
058    // make sure that frame is marked as not disposed if it is asked to be visible
059    if (visible) {
060      //setDisposed(false);
061    }
062    // let's handle visibility...
063    if (!visible || !isVisible()) { // have to check this condition simply because super.setVisible(true) invokes toFront if frame was already visible
064      super.setVisible(visible);
065    }
066    // ...and bring frame to the front.. in a strange and weird way
067    if (visible) {
068      int state = super.getExtendedState();
069      state &= ~Frame.ICONIFIED;
070      super.setExtendedState(state);
071      super.setAlwaysOnTop(true);
072      super.toFront();
073      super.requestFocus();
074      super.setAlwaysOnTop(false);
075    }
076  }
077
078  @Override
079  public void toFront() {
080    if (alreadyCalled) return;
081    try {
082      alreadyCalled = true;
083      super.setVisible(true);
084      int state = super.getExtendedState();
085      state &= ~Frame.ICONIFIED;
086      super.setExtendedState(state);
087      super.setAlwaysOnTop(true);
088      super.toFront();
089      super.requestFocus();
090      super.setAlwaysOnTop(false);
091    } finally {
092      alreadyCalled = false;
093    }
094  }
095}