Suzan Cioc
Suzan Cioc

Reputation: 30097

How to open one frame on the same monitor as another in swing?

I have one frame, which can cause another frame to open, say, by button press. I want to make second frame to appear on the same screen (in dual monitor config) as the first one.

How to do that?

UPDDATE

Passing getGraphicsConfiguration() from the parent JFrame does not help, although it contains correct screen field inside.

Upvotes: 0

Views: 1962

Answers (4)

SJN
SJN

Reputation: 11

If you want to open the new window (JPanel) on the same monitor as the predecessor, you can do it simply by:

newPanel.setLocationRelativeTo(parentPanel);

Upvotes: 1

morpheus05
morpheus05

Reputation: 4872

I did it this way:

public static void showOnScreen(Window frame) {
  GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
  GraphicsDevice[] gd = ge.getScreenDevices();

  final GraphicsDevice frameDevice = frame.getParent().getGraphicsConfiguration().getDevice();
  for (GraphicsDevice graphicsDevice : gd) {
    if (frameDevice.equals(graphicsDevice) || frameDevice.getIDstring().equals(graphicsDevice.getIDstring())) {
      final Rectangle monitorBounds = graphicsDevice.getDefaultConfiguration().getBounds();
      final int x = monitorBounds.x + (monitorBounds.width - frame.getWidth()) /2;
      final int y = monitorBounds.y + (monitorBounds.height - frame.getHeight()) / 2;
      frame.setLocation(x, y);
    }
  }
}

The code searches for the device the parent of the given frame uses. It then centers the frame on that specific monitor.

I only tested this code in a dual monitor configuration.

Upvotes: 1

Jecht Tyre
Jecht Tyre

Reputation: 297

There are many ways to do this but I'll stick with the one I did. Here is what I did using the MVC model:

Since you have multiple views(frames) you probably need to make your view class attributes non-static and add a field for the inner frame (innerView). This way you can make a view and modify its components and then set it as an inner view of another. This also means adding components to your view will be done most likely in the main program class rather than the view class itself. This might get a bit hectic but its still doable.

  • I added a List<JComponent> field to the view class where I can store the components I want to add. Then I would add them to the panel in a separate method and update it.
  • Since I used the same controller for all views, I also added a List<View> to store all the views I make and later set which one I am currently operating.

  • Next, I would construct two view classes (First and Second) with a fixed size and their components. I would set the inner view of First as Second. Note that first has a button that once click will display Second.

  • Last, I made an Action Listener for the button. This listener will make Second visible once the button is clicked. It will also set Second as the current view in the controller class in case you want to make buttons there too. The button itself is created in the main program class.

Let me know if you need more clarifications or examples.

Upvotes: 1

trashgod
trashgod

Reputation: 205785

Store the user's choice for the frame's location in java.util.Preferences or javax.jnlp.BasicService, as suggested here. Default to setLocationByPlatform(), and restore the location on startup. See also The Use of Multiple JFrames, Good/Bad Practice?

Addendum: Sorry, what are you talking about?

Let the user decide where to put the window. In outline,

  1. Constrain the design to use a single frame; use dialogs for subsidiary windows.

  2. If no preference exists, use setLocationByPlatform() for the frame's default, preferred location.

  3. If the user moves the window, record the new location as a preference.

  4. On restart, retrieve the preferred value, and use it to restore the frame's location.

Upvotes: 1

Related Questions