简体   繁体   中英

Java Window Size Limitations on OSX Yosemite (10.10.5)

I am attempting to resize a window from a Java application to span 8 connected monitors. All monitors are the exact same Dell monitor with 2560 X 1600 resolution each. The monitors are laid out so that there are 4 across and 2 down. This means that the total resolution across all 8 monitors is 10240 X 3200. However, no Java application seems capable of expanding past about 4096 X 3200. Since I know Java applications were able to scale across all 8 monitors before I updated the system to OSX, it makes me wonder if Java doesn't play nicely with OSX.

Has anyone experienced similar issues? Anyone know how to fix it or if I can?

Previous Findings

  • I know that the new OS has an options in System Preferences to make a multi-monitor display continuous. I have already done this.
  • There are ways get the entire screen resolution dynamically in Java, which I found references to previously on StackOverflow. The original documentation is on java.awt.GraphicsConfiguration. While this seems to be able to determine what the total screen resolution should be and despite me using setBounds (or setSize) to make the application be that size, it will not work. I also tried statically inputting the desired dimensions and saw no difference than doing so dynamically. Even simple programs cannot be manually resized beyond the 4096 X 3200 size. (Sample program code is provided below.)
  • I also know that OSX doesn't seem to like to have windows span multiple displays if the upper boundary of the window is moved too close to the top of a monitor or too close to the boundary between an upper monitor or a lower monitor. When this happens, OSX automatically scales the window so that it only takes up the hight of one monitor, and the window is placed at the top of the nearest monitor. This is not just with Java applications, but with any application and is simply how OSX operates. This also means that attempting to start an application that is higher than one screen will trigger this behavior as well. For my purposes right now, that is ok (even though not preferable); I just want to be able to span all 8 monitors, even if I have to manually resize the window.
  • My belief that this issue is only with Java applications is based on the fact that three separate Java applications (including the sample one below) have the same issue. However, other applications on the machine, like Google Chrome, seem to have no problem spanning all 8 monitors.
  • Because of the Dock at the bottom of one of the monitors and the menu at the top of another, I may not be able to get the full hight of 3200 pixels. That's fine; I just want to get as close to the 10240 X 3200 window size as possible. (So, right now, the width is the real issue.)

System Details OS: OSX Yosemite (10.10.5), Processor: 2X2.26 GHz Quad-Core Intel Xeon, Memory: 16 BG, Graphics: NVIDIA GeForce GT 120 512 MB

Sample Java Program

import javax.swing.*;

class WindowTest extends JFrame {
  public WindowTest() {
    setSize(10240, 3200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

  public static void main (String[] args) {
    WindowTest w = new WindowTest();
    w.setVisible(true);
  }
}

Very interesting question, and nice SSCCE but I am unable to test the following code since my machine only has one display port, but I hope this may be of some help.

The call to setSize(10240, 3200) is often ignored, the javadoc tells us

The method changes the geometry-related data. Therefore, the native windowing system may ignore such requests, or it may modify the requested data , so that the Window object is placed and sized in a way that corresponds closely to the desktop settings.

Instead I suggest using both of the following to try and force a size, and call pack() later:

setMinimumSize(new Dimension(10240, 3200));
setPreferredSize(new Dimension(10240, 3200));

In addition to this you can and should specify the JFrame location relative to the left/top most screen, something a little like this: (Edit: Updated to reflect the comments and added pack() where needed)

import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class WindowTest extends JFrame
{
    public WindowTest()
    {
        setLocation(0, 0);

        //Set your window to a specific size, we can force this by calling pack() later
        setMinimumSize(new java.awt.Dimension(10240, 3200));
        setPreferredSize(new java.awt.Dimension(10240, 3200));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public static void main (String[] args)
    {
        try
        {
            // Set cross-platform Java L&F (also called "Metal")
        UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        }
        catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e)
        {
            //Do nothing, the progam will default to automatic system assigned L&F
            System.out.println("Failed to set L&F to \"Metal\": "+e.getMessage());
        }
        WindowTest w = new WindowTest();
        w.setVisible(true);
        //Then try pack() to force your window size, and hopefully ignore OS sizing
        w.pack();
    }
}

This should achieve the frame size you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM