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!
Related
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));
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;
}
so I would like to know if it's possible to put things like buttons, text boxes, words, progress bars, ect, ect, on top of an already existing, in this example, JLabel.
Here is the image of the undercoated frame I made, followed by the snippet of code that is associated with this undercoated frame.
(I dont have 10 reputation, so here is a link to a photo)
http://prntscr.com/15516f
Map.setTitle("Map");
Map.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Map.setUndecorated(true);
Map.setBackground(new Color(0,0,0,0));
Map.setLayout(new FlowLayout());
JLabel Background = new JLabel(new ImageIcon(getClass().getResource("Map.png")));
Background.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
initialClick = e.getPoint();
getComponentAt(initialClick);
}
});
Background.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
// get location of Window
int thisX = Map.getLocation().x;
int thisY = Map.getLocation().y;
// Determine how much the mouse moved since the initial click
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
// Move window to this position
int X = thisX + xMoved;
int Y = thisY + yMoved;
Map.setLocation(X, Y);
}
});
Map.add(Background);
Map.setSize(507,512);
Map.setLocation(0, 100);
Map.setResizable(false);
Map.setVisible(false);
on a side note, and I KNOW this is FlowLayout(), but when I try to add something else, it'll just put itself above, or below my map.
I'd just like to know if I could put things on top of this Map.
Maybe I should put the image in in another way besides the JLabel?
Look into JLayeredPane and similar strategies. See How to Use Layered Panes for more details.
I have a simple extended JSplitPane that I set different panels to at different times when they are needed. Specifically, I split it into an upper and lower section, and I swap out the bottom section frequently. Each time I do, I reset the slider position to how I want it, but sometimes it jumps off at and re-positions itself to the top of the screen (not always).
Here's my code:
public class MainPanel extends JSplitPane{
public Screen screen;
public int height;
public ControlPanel curPanel;
public MainPanel(Screen screen, int height){
super(JSplitPane.VERTICAL_SPLIT);
this.screen = screen;
this.height = height;
setDividerSize(2);
setEnabled(false);
setTopComponent(screen);
setToInitControls();
}
public void setToInitControls(){
InitControls initCtrls = new InitControls(this);
setBottomComponent(initCtrls);
curPanel = initCtrls;
setDividerLocation(height / 4 * 3);
}
public void setToConfigControls(){
ConfigControls configCtrls = new ConfigControls(this);
setBottomComponent(configCtrls);
curPanel = configCtrls;
setDividerLocation(height / 4 * 3);
}
public void setToWaitControls(){
WaitControls waitCtrls = new WaitControls(this);
setBottomComponent(null);
setBottomComponent(waitCtrls);
curPanel = waitCtrls;
setDividerLocation(height / 4 * 3);
}
//and so on (I have more methods like these further down)
//OVERRIDES: I figured overriding these might help. It didn't.
#Override
public int getMinimumDividerLocation(){
return (height / 4 * 3);
}
#Override
public int getMaximumDividerLocation(){
return (height / 4 * 3);
}
}
Basically, I use the "setTo...Controls()" methods to swap bottom panels. Is there a way to tell the slider to stay put where I placed it regardless of the panel's preferred sizes, or if not, how do I make the panels know what to shape themselves to fit in? Thanks for any/all suggestions!
EDIT: I should note that these panels do not use layouts. They are custom panels that I use mouse/keyboard listeners on and use my own graphics to paint over them.
I found the solution, thanks to the links above. It's actually quite simple. Instead of using
setDividerLocation(height / 4 * 3);
for every time I added a component, I just replaced it with:
setResizeWeight(0.66);
Did that once inside the constructor, and it never bothered me again. 0.66 is the equivalent decimal position to h/4*3 (I just trial-and-errored it).
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);