【问题标题】:Java: Accounting for taskbars/menubars/etc when placing a window on the desktop?Java:在桌面上放置窗口时考虑任务栏/菜单栏/等?
【发布时间】:2010-10-06 05:48:21
【问题描述】:

当我的程序启动时,主窗口会将自己置于上次关闭时的位置。我想修改一些这种行为,所以如果窗口在屏幕外(或部分在屏幕外),它会自行移动到完全在屏幕上。

我已经完美地完成了这项工作。这是代码:

    int x = gameConfig.windowX;
    int y = gameConfig.windowY;
    int width = gameConfig.windowWidth;
    int height = gameConfig.windowHeight;

    if( x < 0 ) x = 0;
    if( y < 0 ) y = 0;

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

    if( x + width > screenSize.width ) x = screenSize.width - width;
    if( y + height > screenSize.height ) y = screenSize.height - height;

    if( width > screenSize.width ) width = screenSize.width;
    if( height > screenSize.height ) height = screenSize.height;

    this.setLocation(x, y);
    this.setSize(width, height );

    if( gameConfig.screenMaximized ) {
        this.setExtendedState(getExtendedState() | MAXIMIZED_BOTH );
    }



这按预期工作,但有一个很大的例外;它不考虑任务栏。在 Windows 上,如果窗口超出屏幕底部,此代码将更正它,但仍会留下一块窗口被任务栏挡住。

我不知道该怎么做。有没有办法向java询问系统中的任何任务栏,以及它们的宽度/高度是多少?


谢谢,效果很好。

您知道如何获取它,以便在我调用 getScreenSize() 时 Java 将反映我的两个显示器的总屏幕大小吗?现在它返回 1600x1200,而实际上它是 3200x1200,跨越两台显示器。

Java API 建议 GraphicsConfiguration.getBounds() 可以解决问题,但仍会返回矩形 {0, 0, 1600, 1200}。

【问题讨论】:

    标签: java swing


    【解决方案1】:

    使用 getScreenInsets (Java 4+):

    static public Insets getScreenInsets(Window wnd) {
        Insets                              si;
    
        try {
            if(wnd==null) { si=Toolkit.getDefaultToolkit().getScreenInsets(new Frame().getGraphicsConfiguration()); }
            else          { si=wnd.getToolkit()           .getScreenInsets(wnd.getGraphicsConfiguration());         }
            } catch(NoSuchMethodError thr) { si=new Insets(0,0,0,0); }
        return si;
        }
    

    (此方法允许多个屏幕,以及不支持 API 的旧 JVM)。

    而且,请始终记住,任务栏可以位于屏幕的任何边缘,而不仅仅是底部。

    【讨论】:

    • “任务栏可能位于屏幕的任何边缘”——这就是您所说的我的任务栏(在屏幕右侧)。太多的应用程序强迫我把它移到左边(啊!),但仍然有一些不能正常工作。
    • 是的 - Sun 并没有帮助我们,直到 Java 4 才包含确定该死的东西在哪里的能力。
    【解决方案2】:

    以下代码对我有用,甚至通过将工具栏移动到右侧进行了测试。但没有尝试多屏。

    public class Scene extends JFrame {
    private static final long serialVersionUID = 42L;
    
    public Scene() {
        Canvas canvas = new Canvas();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setContentPane(canvas);
        this.pack();
        this.putFrameInRightCorner();
        this.setVisible(true);
    }
    
    protected void putFrameInRightCorner(){
        Rectangle winSize = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
        Dimension frameSize = this.getSize();
        int taskBarWidth = screenSize.width - winSize.width;
        int taskBarHeight = screenSize.height - winSize.height;
        this.setLocation((screenSize.width - frameSize.width - taskBarWidth), 
                          (screenSize.height - frameSize.height - taskBarHeight));
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Scene();
            }
        });
    }
    }
    

    【讨论】:

    • 必须覆盖画布的 (JPanel) getPreferredSize 以返回所需的大小。 @Override public Dimension getPreferredSize() { 返回维度; }
    【解决方案3】:

    通过关注 Pavan Kumar Kundagol Sundara 的帖子,在 1 月 9 日 14:03 回答,我得到了这个好看且工作完美的代码:

    import java.awt.GraphicsEnvironment;
    import java.awt.Rectangle;
    
    Rectangle janelSOdisponivel = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
    int janelaSOaltura = janelSOdisponivel.height;
    int janelaSOlargura = janelSOdisponivel.width;
    

    然后使用我需要的两个变量(janelaSOalturajanelaSOlargura)。

    【讨论】:

      【解决方案4】:

      关于多屏问题,我实际上并没有这样做,但我相信每个屏幕都有自己的图形配置。据我了解,您可以枚举配置以找到您想要的配置 - 然后您使用我们已经讨论过的相同 API。

      看起来 GraphicConfiguration 的文档包含您需要的详细信息:

      GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
      GraphicsDevice[]    gs=ge.getScreenDevices();
      for(int j = 0; j<gs.length; j++) { 
          GraphicsDevice gd=gs[j];
          GraphicsConfiguration[] gc=gd.getConfigurations();
          for (int i=0; i<gc.length; i++) {
              ...
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多