Изменение базового цвета фона окна Swing

Как обсуждалось здесь, при изменении размера приложения Swing в Vista (и Windows 7, которое я использую) вы получаете черный фон в правом/нижнем углу, а Swing repaint догоняет изменения.

Играя с другими приложениями (проводник Windows (родной), Firefox (С++?) и Eclipse (Java)), я замечаю, что все они имеют эту же проблему - вопреки тому, что говорят люди в ссылке выше, - но они сводят к минимуму проблема заключается в том, что имеет серый цвет заливки, который намного менее визуально резче, чем черный, который появляется в Swing.

Мне интересно, есть ли способ изменить это, чтобы Swing вел себя как эти другие приложения? Я попытался установить фоновый цвет JFrame, но безрезультатно.

Дополнительная информация Джонас обнаружил (см. Их информативный ответ ниже), что это проблема с JFrames, но не AWT Frames - возможно, это поможет кому-то понять это.

Ответы

Ответ 1

Я заметил ту же проблему. Этот цвет серый в IE, в Opera - черный, а в Eclipse - серый. Этот шов будет более заметным в Swing, потому что его шов будет немного медленнее при перекраске, а цвет - как вы сказали, черный. Эта проблема более заметна, если вы используете верхний левый угол для изменения размера.

Я закодировал пример и попытался понять, где этот черный цвет определен. A JFrame имеет много слоев, поэтому я устанавливаю другой фон на каждом уровне.

import java.awt.Color;
import javax.swing.JFrame;

public class BFrame {

    public static void main(String[] args) {
        new JFrame() {{
            super.setBackground(Color.CYAN);
            this.getRootPane().setBackground(Color.BLUE);
            this.getLayeredPane().setBackground(Color.RED);
            this.getContentPane().setBackground(Color.YELLOW);
            this.setSize(400,340); 
            this.setVisible(true);
        }};
    }
}

Но этот пример не помог. И, возможно, цвет устанавливается суперклассом на Frame.

java.lang.Object
  java.awt.Component
      java.awt.Container
          java.awt.Window
              java.awt.Frame

Моя теория заключается в том, что, поскольку Swing рисует сама, но использует собственное окно, то это родной фон, написанный до изменения размера, а фон Swing окрашен после изменения размера. Но для собственных приложений фон окрашивается до изменения размера.

ОБНОВЛЕНИЕ: Теперь я попытался с Frame, и он не имел того же проблема. Фоновый шов должен быть окрашен до изменения размера.

import java.awt.Color;
import java.awt.Frame;

public class B2Frame extends Frame {

    public static void main(String[] args) {
        new Frame() {{
            setBackground(Color.YELLOW);
            setSize(400,340);
            setVisible(true);
        }};
    }

}

Ответ 2

Кадр отвечает за рисование фона, поэтому вам нужно убедиться, что вы позволили ему выполнять свою работу.

Вы демонстрируете это, установив:

System.setProperty("sun.awt.noerasebackground", "true");

Это приведет к тому, что фон будет постоянно черным при расширении размера. (Так что не делайте этого.)

Следующие работали для меня:

  • (только для AWT) Настройте двойную буферизацию с помощью createBufferStrategy(2) - завернутый в addNotify(), иначе вы столкнетесь с исключениями во время создания фрейма

    (Шаг 1 необходим только в AWT, поскольку по умолчанию Swing дважды буферизуется.)

  • Всегда (важный) вызов super() в вашей реализации Frame.paint()

  • Установите цвет фона с помощью setBackground(), тогда фон всегда должен быть одного цвета при расширении рамки

Пример кода:

    class InnerFrame extends Frame {
        public void addNotify() {
            super.addNotify();
            // Buffer
            createBufferStrategy(2);           
            strategy = getBufferStrategy();
        }

        public void paint(Graphics g) {
            super(g);
            //...
        }
        //...
     }

Ответ 3

Я также заметил это. Для меня эта проблема была решена с помощью изменения менеджера макетов (раньше я использовал Free Form Layout), и он работал очень хорошо (цветная система).

Но в итоге я вернулся к FFL. Также некоторые известные приложения сталкиваются с этой проблемой (например, SKYPE), но я на самом деле не против...