Почему jframe скрывает панель задач, когда развернута? - PullRequest
0 голосов
/ 21 июня 2011

Я использую setUndecorated(true); и getRootPane().setWindowDecorationStyle(JRootPane.FRAME); в моем jFrame. Это прекрасно работает, но теперь, когда я развернул свой фрейм, он распространился по всему окну, даже панель задач не видна. Что я могу сделать, чтобы рамка не скрывала панель задач?

Также, когда я максимизирую минимизацию моего фрейма несколько раз, курсор меняется на этот <->, который обычно используется для изменения размера фрейма, когда курсор находится на границе фрейма. Что я могу для этого сделать?


Небольшой код затем может воспроизвести вещь:

import javax.swing.JFrame;
import javax.swing.JRootPane;
public class Demo extends JFrame {
    public Demo() {
        setSize(250,125);
        setUndecorated(true);
        getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
        setVisible(true);
    }
    public static void main(String[] args) {
        new Demo();
    }
}

Ответы [ 3 ]

6 голосов
/ 21 июня 2011

Это известная ошибка: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4737788

Цитата из этой ссылки:

Обходной путь - это создать подкласс JFrame и переопределить метод setExtendedState, перехватывая любые события максимизации до того, как онипроизойдет и установит максимальные границы кадра перед вызовом метода setExtendedState суперкласса.

import java.awt.*;
import javax.swing.*;

public class PFrame extends JFrame
{
private Rectangle maxBounds;

public PFrame()
{
    super();        
    maxBounds = null;
}

//Full implementation has other JFrame constructors

public Rectangle getMaximizedBounds()
{
    return(maxBounds);
}

public synchronized void setMaximizedBounds(Rectangle maxBounds)
{
    this.maxBounds = maxBounds;
    super.setMaximizedBounds(maxBounds);
}

public synchronized void setExtendedState(int state)
{       
    if (maxBounds == null &&
        (state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH)
    {
        Insets screenInsets = getToolkit().getScreenInsets(getGraphicsConfiguration());         
        Rectangle screenSize = getGraphicsConfiguration().getBounds();
        Rectangle maxBounds = new Rectangle(screenInsets.left + screenSize.x, 
                                    screenInsets.top + screenSize.y, 
                                    screenSize.x + screenSize.width - screenInsets.right - screenInsets.left,
                                    screenSize.y + screenSize.height - screenInsets.bottom - screenInsets.top);
        super.setMaximizedBounds(maxBounds);
    }

    super.setExtendedState(state);
}
}
0 голосов
/ 28 мая 2019

Ответ Fortega работал, однако, некоторая часть не нужна (или больше не нужна в Java 8):

  • Rectangle не нужно сохранять.
  • Код не учитывает конфигурацию двойного экрана.В частности, GraphicsConfiguration изменится, если окно изменения окна.
  • Насколько я тестировал, единственное требуемое переопределение - setExtendedState.

При учете конфигурации с двумя экранами, по крайней мере в Windows , приведенный ниже код не работает должным образом:

Rectangle maxBounds = new Rectangle(screenInsets.left + screenSize.x, 
                                    screenInsets.top + screenSize.y, 
                                    screenSize.x + screenSize.width - screenInsets.right - screenInsets.left,
                                    screenSize.y + screenSize.height - screenInsets.bottom - screenInsets.top);

На следующих настройках двойного экрана:

  • Левый экран 1920x1080(не основной), позиция: -1920, 0
  • Правый экран 1920x1080 (основной), позиция: 0, 0

maxBounds будет содержать отрицательный x (-1920)но setMaximizedBounds каким-то образом ожидает координату в пространстве экрана (где (x,y) начинается с (0,0)), а не на виртуальном экране:

  • Будет установлено значение setMaximizedBounds(x=-1920,y=0,width=1920,height=1050)
  • Windows увидит окно на левом экране (потому что у меня есть одна панель задач на экран, показывающая только окно на этом экране), однако окно не будет отображаться на экране, потому что оно находится за пределами.
  • Если разрешение экрана, или хуже, его масштабный коэффициент (с ноутбуком, Windows10 применяет масштабный коэффициент, например: 25%, делая экран «не очень» (1920x1080), тогда приведенный выше код не адаптируется.Например, если в моей конфигурации 3 экрана, причем самый правый из них является основным, окно будет плохо отображаться на левом и среднем экранах.Не думаю, что я исправил это в приведенном ниже коде.

Следующий код работает в Windows с двойным экраном:

  @Override
  public synchronized void setExtendedState(final int state) {
    if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
      final GraphicsConfiguration cfg = getGraphicsConfiguration();
      final Insets screenInsets = getToolkit().getScreenInsets(cfg);
      final Rectangle screenBounds = cfg.getBounds();
      final int x = screenInsets.left + screenBounds.x * 0;
      final int y = screenInsets.top + screenBounds.y * 0;
      final int w = screenBounds.width - screenInsets.right - screenInsets.left;
      final int h = screenBounds.height - screenInsets.bottom - screenInsets.top;
      final Rectangle maximizedBounds = new Rectangle(x, y, w, h);

      System.out.println("cfg (" + cfg + ") screen.{bounds: " + screenBounds + ", insets: " + screenInsets + ", maxBounds: " + maximizedBounds);

      super.setMaximizedBounds(maximizedBounds);
    }
    super.setExtendedState(state);
  }

На простом JFrame:

  • При максимизации на левом экране («screen = 0») будет напечатано cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=0],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=-1920,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]
  • При максимизации на правом экране («screen = 1») будет напечатано cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=1],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]
0 голосов
/ 21 июня 2011

Возможно, вы можете установить максимальный размер jFrame и ограничить его в соответствии с размером экрана.

РЕДАКТИРОВАТЬ

Также проверьте setExtendedState

...