I'm currently programming a plugin for IntelliJ, but have lost the basic of how to center a new JDialog in front of IntelliJ window. That is that I create and open a new JDialog and it should initially center in the IDE, even if I change the monitor. Atm I run "setLocationRelativeTo(null);" and it's just opening on my primary screen all the time and not in the IDE. Anyone got any idea what I'm missing?
Edit
I tried to get the parents position and use the coordinate to place where the JDialog should be. But it always displays on the upper left corner of my primary screen and not where I have my IDE.
Point parentPoint = getParent().getLocation();
Dimension parentDimension = getParent().getSize();
Dimension dialogDimension = getSize();
int x = (int) (parentPoint.getX() + (parentDimension.getWidth() - dialogDimension.getWidth()) / 2);
int y = (int) (parentPoint.getY() + (parentDimension.getHeight() - dialogDimension.getHeight()) / 2);
setLocation(x, y);
Solved it!
The problem was that I never assigned the parent window for the JDialog. Since I created the dialog through AnAction impl, I could get the project from AnActionEvent.
I used that project variable to create this code in my JDialog implementation.
private Window getParentWindow(Project project) {
WindowManagerEx windowManager = (WindowManagerEx) WindowManager.getInstance();
Window window = windowManager.suggestParentWindow(project);
if (window == null) {
Window focusedWindow = windowManager.getMostRecentFocusedWindow();
if (focusedWindow instanceof IdeFrameImpl) {
window = focusedWindow;
}
}
return window;
}
Then just calling this method to
setLocationRelativeTo(getParentWindow(project));
Related
Don't mind the use of the Window Insets, but pay more attention to the use of the ScreenInsets, which is saved locally as Insets insets; I print the insets.bottom, and for every monitor the taskbar height shows up, even though the taskbar is only located on the first monitor.
The monitor insets on my second monitor should all be zero, but yet it acts as if the taskbar is located on both monitors. Setting the window to full size in the monitor the window is currently located on works, except it leaves room for the taskbar regardless which monitor are use it in.
From my understanding of the Toolkit.getScreenInsets(GraphicsConfiguration), it should return the correct insets for the specific GraphicsConfiguration you pass in, yet I'm passing in each GraphicsDevice's GraphicsConfiguration and getting the same results back.
JFrame window;
public void setSizeToFullScreen()
{
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screenDevices=ge.getScreenDevices();
Point p=window.getLocationOnScreen();
for(int i=0;i<screenDevices.length;i++)
{
Rectangle2D b=screenDevices[i].getDefaultConfiguration().getBounds();
if(SMath.getMath().doesRectangleContainPoint(b.getX(), b.getY(), b.getWidth(), b.getHeight(), p.getX(),p.getY()))
{
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(screenDevices[i].getDefaultConfiguration());
System.out.println("Monitor: "+i+": task bar height: "+insets.bottom);
this.setSize(b.getWidth()+1 -(insets.right+insets.left)-(this.window.getInsets().left+this.window.getInsets().right), b.getHeight()+1-(insets.top+insets.bottom)-(this.window.getInsets().top+this.window.getInsets().bottom));
this.setLocation(b.getX()+insets.left+window.getInsets().left, b.getY()+insets.top+window.getInsets().top);
return;
}
}
}
My question is, in Java, how can we figure out which monitor actually has the taskbar, or the better question, how can we get the correct monitor insets for each monitor in Java.
Re: "..., yet it acts as if the taskbar is located on both monitors".
I found the following:
Referring to Windows->Control Panel->Appearance and Personalization->
Display->Screen Resolution:
When gs[0] (= the display shown with a "1" inside a circle in the Control Panel window above) has the Toolbar, the reported Insets are correct.
I.e., they are reported to be = 0 for the no-Toolbar screen and = 49 for the screen that has the Toolbar.
When any other gs[x] has the Toolbar, the reported Insets are wrong :-(. I.e., they are reported to be = 49 for all screens.
In my application, I want "JDialog dialog0" to always appear 500 to the right of the lower-left corner of my "big" display, and "JFrame frameBalloonHerderGui" to always appear in the upper-left corner of my "small" display.
I want the JDialog to have a fixed size in the lower-left corner of my "big" display, and the JFrame should pretty much fill the "small" display it's in.
I did give the graphicsConfiguration for the display I wanted each JDialog/JFrame to appear in to their constructors. Alas, that is not enough to allow the Insets to be correct.
To accomplish the positioning above, I wrote a function that I call for my JDialog and JFrame as follows:
// I'll omit the creation of the grapicsConfiguration for now.
JDialog dialog0 = new JDialog( gc);
ScreenAndTaskBarHeights h = getThisComponentsScreensTaskBarHeight( dialog0);
final int myWidth = 1170;
final int myHeight = 800;
final int myScreenXInset = 500;
final int myScreenYInset = 10;
dialog0.setBounds(
h.screenOriginX + myScreenXInset,
h.screenOriginY + h.screenHeight - myHeight - h.taskBarHeight - myScreenYInset,
myWidth, myHeight);
dialog0.setVisible( true);
// I'll omit the creation of the grapicsConfiguration for now.
JFrame frameBalloonHerderGui = new JFrame( gc);
ScreenAndTaskBarHeights h =
getThisComponentsScreensTaskBarHeight( frameBalloonHerderGui);
final int myWidth = 1695;
final int myScreenInset = 10;
frameBalloonHerderGui.setBounds(
h.screenOriginX + myScreenInset,
h.screenOriginY + myScreenInset,
myWidth, h.screenHeight - (myScreenInset * 2) - h.taskBarHeight);
frameBalloonHerderGui.setVisible( true);
The workaround I found is that the screenSize.x & .y = (0,0) for the display that has the TaskBar, and some big positive or negative numbers for the other displays.
The function below successfully implements this workaround. I also made a simple class so I could pass multiple values back to the caller as shown above.
// Add additional data members here to your liking.
static class ScreenAndTaskBarHeights
{
int screenOriginX = -1;
int screenOriginY = -1;
int screenHeight = -1;
int taskBarHeight = -1;
ScreenAndTaskBarHeights()
{
}
void setValues(
int newScreenOriginX, int newScreenOriginY,
int newScreenHeight, int newTaskBarHeight)
{
screenOriginX = newScreenOriginX;
screenOriginY = newScreenOriginY;
screenHeight = newScreenHeight;
taskBarHeight = newTaskBarHeight;
}
}
static ScreenAndTaskBarHeights
getThisComponentsScreensTaskBarHeight( Component c)
{
ScreenAndTaskBarHeights screenAndTaskBarHeights =
new ScreenAndTaskBarHeights();
GraphicsConfiguration gc = c.getGraphicsConfiguration();
Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets( gc);
// This should be the TaskBar height specific to the gc that we
// passed in, but it's not :-(.
//
// int taskBarHeight = scnMax.bottom;
//
// However, this seems to be a successful workaround:
//
Rectangle screenSize = gc.getBounds();
boolean thisScreenHasTheToolbar =
(screenSize.x == 0 && screenSize.y == 0);
// Change scnMax.bottom to catch wherever you're worried that the
// TaskBar may be lurking.
//
screenAndTaskBarHeights.setValues(
screenSize.x, screenSize.y, screenSize.height,
(thisScreenHasTheToolbar) ? scnMax.bottom : 0);
return screenAndTaskBarHeights;
}
I want my app to detect mouse clicks anywhere on the screen without having to have the app focused. I want it to detect mouse events universally even if its minimized. So far I've only been able to detect mouse events within a swing gui.
Autohotkey can detect mouse clicks and get the mouse's position at any time, how can I do this with java?
It is possible with a little trick. Should be 100% cross-platform (tested on Linux & Windows). Basically, you create a small JWindow, make it "alwaysOnTop" and move it around with the mouse using a timer.
Then, you can record the click, dismiss the window and forward the click to the actual receiver using the Robot class.
Short left and right clicks work completely fine in my tests.
You could also simulate dragging and click-and-hold, just forwarding that seems harder.
I have code for this, but it is in my Java extension (JavaX). JavaX does translate into Java source code, so you can check out the example here.
The code in JavaX:
static int windowSize = 11; // odd should look nice. Set to 1 for an invisible window
static int clickDelay = 0; // Delay in ms between closing window and forwarding click. 0 seems to work fine.
static int trackingSpeed = 10; // How often to move the window (ms)
p {
final new JWindow window;
window.setSize(windowSize, windowSize);
window.setVisible(true);
window.setAlwaysOnTop(true);
JPanel panel = singleColorPanel(Color.red);
window.setContentPane(panel);
revalidate(window);
final new Robot robot;
panel.addMouseListener(new MouseAdapter {
// public void mousePressed(final MouseEvent e) {}
public void mouseReleased(final MouseEvent e) {
print("release! " + e);
window.setVisible(false);
int b = e.getButton();
final int mod =
b == 1 ? InputEvent.BUTTON1_DOWN_MASK
: b == 2 ? InputEvent.BUTTON2_DOWN_MASK
: InputEvent.BUTTON3_DOWN_MASK;
swingLater(clickDelay, r {
print("clicking " + mod);
robot.mousePress(mod);
robot.mouseRelease(mod);
});
}
});
swingEvery(window, trackingSpeed, r {
Point p = getMouseLocation();
window.setLocation(p.x-windowSize/2, p.y-windowSize/2);
//print("moving");
});
}
I have a JDesktopPane where I add and show a JInternalFrame called ListarEmpleado.java. From that ListarEmpleado.java I open another JInternalFrame called InformacionEmpleado.java doing click in a button. I have a equation to locate InformacionEmpleado.java in the middle of the JDesktopPane when it is opened.
This is the button event (I code in Netbeans):
private void masInformacionActionPerformed(java.awt.event.ActionEvent evt) {
InformacionEmpleado verDetalle = new InformacionEmpleado(this.cedulaSeleccionada);
escritorio = getDesktopPane();
escritorio.add(verDetalle);
int width = verDetalle.getParent().getWidth();
int width1 = verDetalle.getWidth();
int height = verDetalle.getParent().getHeight();
int height1 = verDetalle.getHeight();
verDetalle.setLocation(width / 2 - width1 / 2, height / 2 - height1/ 2 - 10);
verDetalle.setVisible(true);
}
The problem is when the line verDetalle.setVisible(true); is executed, InformacionEmpleado.java is located in the middle perfectly and I don't have problems with it, but if I have ListarEmpleado.java maximized, it returns to its initial size (does not stay maximized). Why does this happen and how can I fix it?
Thanks a lot!
i am developing a GWT mobile application with GWT 2.4. i want my DialogBox to be seen always on the center of the user's viewport on zoom or on normal view. On normal view, center() can handle it but when the page is zoom, the DialogBox pops on center of the whole browser window which includes the scroll part of the page not on the center of the user's viewport. how to do this? please help. thanks in advance.
You need to attach a handler to your window that catches the zoom event. In this handler, you call
myDialogBox.setPopupPosition((Window.getClientWidth() - myDialogBox.getOffsetWidth())/2, (Window.getClientHeight() - myDialogBox.getOffsetHeight())/2);
}
You may need to add a check for situations when your dialog is bigger than the browser window, if you want to treat them differently.
i have to implements ResizeHandler on my window and on its constructor, i have added ResizeEvent handler > Window.addResizeHandler(this);. since i'm implementing the ResizeHandler interface, i need to override the following:
#Override
public void onResize(ResizeEvent event) {
if (isShowing() ) { //check if popup is showing
int left = (Window.getClientWidth() * 0.5 - (widthOfMyWindow * 0.5) );
int top = (Window.getClientHeight() * 0.5 - (heightOfMyWindow * 0.5) );
setPopupPosition( left < 10 ? 10 : left, top < 0 ? 0 : top );
}
}
I have never been able to figure this one out; the usual suspects don't work.
Given:
FileDialog dlg=null;
dlg=new FileDialog(owner,"Select File to Load",FileDialog.LOAD);
dlg.setFile(null);
dlg.setVisible(true);
is there any way to get that dialog centered?
A key point is that at setVisible(), the calling thread is blocked until the dialog is dismissed; and any positioning prior to that seems to be ignored.
The below solution works for SWT, probably it can do the trick for AWT as well...
As it shows the dialog in left top corner of the current shell, a quick-and-dirty solution is to create a new, well-positioned and invisible shell and to open FileDialog from it. I got an acceptable result with the following code:
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
public class CenteredFileDialog extends Dialog {
protected Shell shell;
public FileDialog dialog;
private int width = 560; // WinXP default
private int height = 420;
public CenteredFileDialog(Shell parent, int style) {
super(parent, style);
shell = new Shell(getParent(), SWT.APPLICATION_MODAL);
dialog = new FileDialog(shell, style);
}
public Object open() {
shell.setSize(width, height);
Rectangle parentBounds = getParent().getBounds();
shell.setLocation(
parentBounds.x + (parentBounds.width - width) / 2,
parentBounds.y + (parentBounds.height - height) / 2);
Object result = dialog.open();
shell.dispose();
return result;
}
}
The class can be used this way:
CenteredFileDialog saveDialog = new CenteredFileDialog(getShell(), SWT.SAVE);
saveDialog.dialog.setFilterExtensions(new String[] { "*.txt" });
saveDialog.dialog.setFilterNames(new String[] { "Text (*.txt)" });
...
String f = (String)saveDialog.open();
if ( f != null ) {
name = f;
recentPath = saveDialog.dialog.getFilterPath();
}
The class only partially solves the problem for Windows platform (On MacOS the dialog is screen-centered anyway; on Linux I did not test) - first time the dialog appears centered relatively to the parent shell (which is what we need), and "remembers" its absolute position on the screen. By subsequent calls it always pops up in the same place, even if the main application window moved.
Despite the oddity, from my perspective the new behaviour is definitely better than the default unprofessionally looking top-left docking of the dialog.
Appears that this may still be a bug.... see last line of this (though its dated 2003)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4333836
I threw this together
FileDialog fd = new FileDialog(f, title, FileDialog.LOAD);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = fd.getSize().width;
int h = fd.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
System.out.println("Dialog location: " + fd.getLocation().toString());
fd.setLocation(x, y);
System.out.println("Dialog location: " + fd.getLocation().toString());
fd.setVisible(true);
And my output was:
Dialog location: java.awt.Point[x=0,y=0]
Dialog location: java.awt.Point[x=840,y=525]
But the screen was still in the top left corner
Try this code: dlg.setLocationRelativeTo(null);
Using Java 7, Eclipse 4.4.1 and Ubuntu 14.04 I was able to find a solution for centering AWT FileDialog.
I was determined to find a solution because Apple recommends using awt.FileDialog over Swing's JFileChooser for a more native look and feel.
The trick is to give your FileDialog instance a size before setting its location.
Use the bounds of the contentPane of your main application frame to calculate the distance of the left corner Point (minX, minY) of FileDialog from the contentPane's center Point.
Then set the location of your FileDialog to this calculated Point, et voilá ... centered.
final FileDialog fileDialog = new FileDialog(applicationFrame,
"Choose a file", FileDialog.LOAD);
/* Lots of code to be able to center an awt.FileDialog on screen... */
Rectangle rect = applicationFrame.getContentPane().getBounds();
/*
* Making sure FileDialog has a size before setVisible, otherwise
* left corner's distance from contentPane center cannot be found.
*/
fileDialog.pack();
fileDialog.setSize(800, 600);
fileDialog.validate();
double width = fileDialog.getBounds().getWidth();
double height = fileDialog.getBounds().getHeight();
double x = rect.getCenterX() - (width / 2);
double y = rect.getCenterY() - (height/ 2);
/* Could be new Point(x, y) */
Point leftCorner = new Point();
leftCorner.setLocation(x, y);
fileDialog.setLocation(leftCorner);
fileDialog.setVisible(true);