com.intellij.ui.popup.MovablePopup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of platform-impl Show documentation
Show all versions of platform-impl Show documentation
A packaging of the IntelliJ Community Edition platform-impl library.
This is release number 1 of trunk branch 142.
The newest version!
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ui.popup;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
/**
* @author Sergey Malenkov
*/
public class MovablePopup {
private final Component myOwner;
private final Component myContent;
private Rectangle myViewBounds;
private Container myView;
private boolean myAlwaysOnTop;
private boolean myHeavyWeight;
private boolean myWindowFocusable;
private boolean myWindowShadow;
/**
* @param owner a component to which this popup belongs
* @param content a component to show within this popup
*/
public MovablePopup(@NotNull Component owner, @NotNull Component content) {
myOwner = owner;
myContent = content;
myViewBounds = new Rectangle(content.getPreferredSize());
myHeavyWeight = true;
}
public void dispose() {
disposeAndUpdate(false);
}
/**
* Sets whether this popup should be always on top.
* This property is used by heavy weight popups only.
*/
public void setAlwaysOnTop(boolean value) {
if (myAlwaysOnTop != value) {
myAlwaysOnTop = value;
disposeAndUpdate(true);
}
}
/**
* Sets whether this popup should be a separate window.
* A light weight popups are painted on the layered pane.
*/
public void setHeavyWeight(boolean value) {
if (myHeavyWeight != value) {
myHeavyWeight = value;
disposeAndUpdate(true);
}
}
/**
* Sets whether this popup should grab a focus.
* This property is used by heavy weight popups only.
*/
public void setWindowFocusable(boolean value) {
if (myWindowFocusable != value) {
myWindowFocusable = value;
disposeAndUpdate(true);
}
}
/**
* Sets whether this popup should have a shadow.
* This property is used by heavy weight popups only.
*/
public void setWindowShadow(boolean value) {
if (myWindowShadow != value) {
myWindowShadow = value;
disposeAndUpdate(true);
}
}
public void setBounds(@NotNull Rectangle bounds) {
setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
}
public void setBounds(int x, int y, int width, int height) {
if (myViewBounds != null) {
myViewBounds.setBounds(x, y, width, height);
}
else {
setBounds(new Point(x, y), new Dimension(width, height));
}
}
public void setLocation(@NotNull Point location) {
setLocation(location.x, location.y);
}
public void setLocation(int x, int y) {
if (myViewBounds != null) {
myViewBounds.setLocation(x, y);
}
else {
setBounds(new Point(x, y), null);
}
}
public void setSize(@NotNull Dimension size) {
setSize(size.width, size.height);
}
public void setSize(int width, int height) {
if (myViewBounds != null) {
myViewBounds.setSize(width, height);
}
else {
setBounds(null, new Dimension(width, height));
}
}
public void setVisible(boolean visible) {
if (myView != null) {
myView.setVisible(visible);
}
else if (visible) {
Window owner = UIUtil.getWindow(myOwner);
if (owner != null) {
if (myHeavyWeight) {
JWindow view = new JWindow(owner);
// TODO 1.7+: temporary fix for the i3 window manager because of Java 1.6
try {
@SuppressWarnings("unchecked")
Class extends Enum> type = (Class extends Enum>)Class.forName("java.awt.Window$Type");
Object value = Enum.valueOf(type, "POPUP");
view.getClass().getMethod("setType", type).invoke(view, value);
}
catch (Exception ignored) {
}
// TODO 1.7+: setType(Window.Type.POPUP); // or UTILITY
if (myAlwaysOnTop) {
try {
view.setAlwaysOnTop(true);
}
catch (SecurityException ignored) {
myAlwaysOnTop = false;
}
}
view.setFocusableWindowState(myWindowFocusable);
if (!myWindowShadow) {
view.getRootPane().putClientProperty("Window.shadow", Boolean.FALSE);
}
myView = view;
}
else if (owner instanceof RootPaneContainer) {
JLayeredPane parent = ((RootPaneContainer)owner).getLayeredPane();
if (parent != null) {
JPanel view = new JPanel(new BorderLayout());
view.setVisible(false);
parent.add(view, JLayeredPane.POPUP_LAYER, 0);
myView = view;
}
}
}
if (myView != null) {
myView.add(myContent);
Component parent = myView instanceof Window ? null : myView.getParent();
if (parent != null) {
Point location = myViewBounds.getLocation();
SwingUtilities.convertPointFromScreen(location, parent);
myViewBounds.setLocation(location);
}
myView.setBounds(myViewBounds);
myView.setVisible(true);
myViewBounds = null;
}
}
}
/**
* Determines whether this popup should be visible.
*/
public boolean isVisible() {
return myView != null && myView.isVisible();
}
private void disposeAndUpdate(boolean update) {
if (myView != null) {
boolean visible = myView.isVisible();
if (myView instanceof Window) {
myViewBounds = myView.getBounds();
Window window = (Window)myView;
window.dispose();
}
else {
Container parent = myView.getParent();
if (parent == null) {
myViewBounds = new Rectangle(myContent.getPreferredSize());
}
else {
myViewBounds = new Rectangle(myView.getBounds());
parent.remove(myView);
Point point = new Point(myViewBounds.x, myViewBounds.y);
SwingUtilities.convertPointToScreen(point, parent);
myViewBounds.x = point.x;
myViewBounds.y = point.y;
}
}
myView = null;
if (update && visible) {
setVisible(true);
}
}
}
private void setBounds(Point location, Dimension size) {
if (myView != null) {
if (size == null) {
size = myView.getSize();
}
if (location == null) {
location = myView.getLocation();
}
else {
Component parent = myView instanceof Window ? null : myView.getParent();
if (parent != null) {
SwingUtilities.convertPointFromScreen(location, parent);
}
}
myView.setBounds(location.x, location.y, size.width, size.height);
if (myView.isVisible()) {
myView.invalidate();
myView.validate();
myView.repaint();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy