I know Window.sizeToScene() will resize the window to the size that its scene needs, but the position of the window does not adjust accordingly (i.e. the stationary point is top-left corner of the window). Is there any way to make the window resize itself, and keep the window's center at the same place (i.e. make the stationary point at the center of the window)?
Do something like:
public void resize(Window win) {
double x = win.getX();
double y = win.getY();
double width = win.getWidth();
double height = win.getHeight();
win.sizeToScene();
win.setX(x + ((width - win.getWidth()) / 2));
win.setY(y + ((height - win.getHeight()) / 2));
}
The code above caches the position before the window is resized to the scene, then it moves the window the appropriate amount to keep the window centered in the same area. This code does not take into account where the window will be once it is moved/resized. You might want to add checks to make sure the window doesn't end up going off the screen.
Related
I have a JPanel with a JLabel in it, added to a JScrollPane. I have an actionListener that calls JLabel.setIcon("file.jpg");. The image is displayed in the JScrollPane correctly and is full size. The scrollbars appear perfectly. I am trying to position the vertical and horizontal scrollbars in the center by default so you are looking at the center of the image by default.
Is there a JScrollPane method that will position the viewport on the center of the image? Or could I manually set the position of each scrollbar to max size divided by 2?
I have tried
JScrollPane.getVerticalScrollBar().setValue(JScrollPane.getVerticalScrollBar().getMaximum() / 2);
While it compiles it does not center the scrollbar. I have also tried setting the layout manager of my JPanel to GridBagLayout but that doesn't work either.
Basically, you need to know the size of the viewport's viewable area.
Rectangle bounds = scrollPane.getViewport().getViewRect();
Then you need the size of the component, but once it's added to the scroll pane, you can get this from the view port...
Dimension size = scrollPane.getViewport().getViewSize();
Now you need to calculate the centre position...
int x = (size.width - bounds.width) / 2;
int y = (size.height - bounds.height) / 2;
Then you need to simply adjust the view port position...
scrollPane.getViewport().setViewPosition(new Point(x, y));
Now, remember, this is only going to work once the scroll pane has being realised on the screen (or at least it has being laid out within it's parent container)
I'm guessing that the image has not been read at the time you try to execute your code so try something like the following:
label.setIcon( new ImageIcon("...") );
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Rectangle bounds = scrollPane.getViewport().getViewRect();
JScrollBar horizontal = scrollPane.getHorizontalScrollBar();
horizontal.setValue( (horizontal.getMaximum() - bounds.width) / 2 );
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( (vertical.getMaximum() - bounds.height) / 2 );
}
});
This will add code to the end of the Event Dispatch Thread so hopefully it executes after the image has been read in completely and the scrollbar values have all been updated.
Add an AdjustmentListener and see if that helps. It will let you know if the value of the component changes. That way, when the image is added, the scroll bar's properties will change and you will be notified. You can then try to set the caret position to the mid.
Tutorial: http://examples.javacodegeeks.com/desktop-java/awt/event/adjustmentlistener-example/
I'm going the coordinates of my cursor from Java.AWT.MouseInfo and I need to convert it to the coordinate relative to a ScrollPane's viewport. I'm trying to have the scrollpane's scrollbar positions center on where the mouse was when zooming in/out.
viewScroll is a ScrollPane. zoomGroup is a Group containing an imageView that is scaled (zooming). When scaled the method repositions the scrollbars where it was before the scale. I want to reposition the scrollbars where the mouse was at the time of zooming.
protected void zoom(double scaleValue) {
p = MouseInfo.getPointerInfo().getLocation();
double Y = p.getX();
double X = p.getY();
double scrollH = viewScroll.getHvalue();
double scrollV = viewScroll.getVvalue();
zoomGroup.setScaleX(scaleValue);
zoomGroup.setScaleY(scaleValue);
viewScroll.setHvalue(Y);
viewScroll.setVvalue(X);
}
I have a JPanel with a JLabel in it, added to a JScrollPane. I have an actionListener that calls JLabel.setIcon("file.jpg");. The image is displayed in the JScrollPane correctly and is full size. The scrollbars appear perfectly. I am trying to position the vertical and horizontal scrollbars in the center by default so you are looking at the center of the image by default.
Is there a JScrollPane method that will position the viewport on the center of the image? Or could I manually set the position of each scrollbar to max size divided by 2?
I have tried
JScrollPane.getVerticalScrollBar().setValue(JScrollPane.getVerticalScrollBar().getMaximum() / 2);
While it compiles it does not center the scrollbar. I have also tried setting the layout manager of my JPanel to GridBagLayout but that doesn't work either.
Basically, you need to know the size of the viewport's viewable area.
Rectangle bounds = scrollPane.getViewport().getViewRect();
Then you need the size of the component, but once it's added to the scroll pane, you can get this from the view port...
Dimension size = scrollPane.getViewport().getViewSize();
Now you need to calculate the centre position...
int x = (size.width - bounds.width) / 2;
int y = (size.height - bounds.height) / 2;
Then you need to simply adjust the view port position...
scrollPane.getViewport().setViewPosition(new Point(x, y));
Now, remember, this is only going to work once the scroll pane has being realised on the screen (or at least it has being laid out within it's parent container)
I'm guessing that the image has not been read at the time you try to execute your code so try something like the following:
label.setIcon( new ImageIcon("...") );
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Rectangle bounds = scrollPane.getViewport().getViewRect();
JScrollBar horizontal = scrollPane.getHorizontalScrollBar();
horizontal.setValue( (horizontal.getMaximum() - bounds.width) / 2 );
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( (vertical.getMaximum() - bounds.height) / 2 );
}
});
This will add code to the end of the Event Dispatch Thread so hopefully it executes after the image has been read in completely and the scrollbar values have all been updated.
Add an AdjustmentListener and see if that helps. It will let you know if the value of the component changes. That way, when the image is added, the scroll bar's properties will change and you will be notified. You can then try to set the caret position to the mid.
Tutorial: http://examples.javacodegeeks.com/desktop-java/awt/event/adjustmentlistener-example/
I'm writing a simple game in Java and are trying to get the coordinates of the mouse. What I want is 0,0 at the upper left corner of the content, however, I get coordinates relative to the Window.
The code is as follows:
public void mouseMoved(MouseEvent event)
{
x = event.getY();
y = event.getX();
}
and this is hooked up via JFrame.addWindowListener()
Any suggestions?
I would make sure you bind your event to the content pane inside the window frame. Then your events should trigger relatively from 0,0 coordinates. Assuming, you don't need events outside on the main, which for all purposes you could bind a different event handler there.
Another method is to determine the title bar height and window frame width and just subtract them from the given coordinates (since you are positioned adjacent to them inside the game window - if you move adjust appropriately) for the position relative inside the content frame.
That is relative to the window. The window includes the border around the edge of the contentPane, which is why you're getting 3, 25 instead of 0,0. You can either add your MouseListener to the contentPane directly, or use the frame's Insets to account for the border.
double screenW = Toolkit.getDefaultToolkit().getScreenSize().width;
double screenH = Toolkit.getDefaultToolkit().getScreenSize().height;
double posX = screenW/2 - WIDTH/2;
double posY = screenH/2 - HEIGHT/2;
x = event.getX() - posX;
y = event.getY() - posY;
I have a JLayeredPane, and inside the JLayeredPane is a JInternalFrame. What I need are the bounds (x position, y position, width, height) of the content pane in the JInternalFrame. The bounds need to be in relation to the JLayeredPane. My problem is the borders, title bar, and I'm not sure what else of the JInternalFrame are messing with my calculation. It's a few pixels off.
Here is how I try to calculate it. This code is in the JInternalFrame:
Rectangle area = new Rectangle(
getX() + 2, //The x coordinate of the JInternalFrame + 2 for the border
getY() + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getHeight(), //The Y position of the JinternalFrame + theheight of the title bar of the JInternalFrame
getContentPane().getWidth() - 2, //The width of the Jinternals content pane - the border of the frame
getContentPane().getHeight() //the height of the JinternalFrames content pane
);
I need to get the location of the content pane of the internal frame.
Coordinates with respect to what? The screen? The window?
Calling getLocation() will give you the coordinates relative to the component's parent in the window hierarchy.
SwingUtilities has several methods for transforming coordinates from one frame of reference to another. So, to compensate for the title bar and frame, you can do this:
JInternalFrame iframe = ...
Container c = iframe.getContentPane();
Rectangle r = c.getBounds();
r = SwingUtilities.convertRectangle(c.getParent(), r, iframe.getParent());
The getBounds() method of JInternalFrame returns a Rectangle with the coordinates you need. Why not just do the following:
{
...
JInternalFrame iframe = ...;
Rectangle r = new Rectangle(iframe.getBounds());
}
This way you don't need to manually calculate the bounds.