Окрашенный контент невидим при изменении размера в Java - PullRequest
5 голосов
/ 21 августа 2010

Обратите внимание, что я не проверял это на Windows-машине, только на Mac-машине.Я не уверен, происходит ли это и на Windows-машине ...

Когда я изменяю размер моего Java-приложения, содержимое становится невидимым.Я уже нашел способ исправить это после изменения его размера, но не , пока пользователь изменяет размер окна.

Я не использую Swing или что-то еще, потому что этоделает мой двоичный файл таким медленным (по моему мнению).

Структура выглядит следующим образом:

  • Frame Мое главное окно
    • Containe r Просмотр содержимого main-window
      • Container основанных подпредставлений, включая paint(Graphics g) -метод

Я добавил всех слушателейMy main-window и теперь я могу перерисовать Content-view после изменения размера окна.

public void componentResized(ComponentEvent e) {
    this.contentView.paint(this.contentView.getGraphics());
}

ЯОстерегайтесь того факта, что использование paint(getGraphics()) -метода не очень хороший способ сделать это, но так как repaint() -метод вообще ничего не делает, это единственная рабочая возможность.

При изменении размера весь нарисованный контент становится невидимым.Однако, когда я добавляю Button -экземпляр к моему Content-view и изменяю размеры моего Main-window, кнопка не становится невидимой.

I am в состоянии отследить событие «живого» изменения размера:

public void componentMoved(ComponentEvent e) {
    System.out.println("Live-resize");
}
  1. Когда я начинаю изменение размера, этот метод не вызывается.
  2. При изменении его размерагенерирует «Live-resize» в моем журнале каждый пиксель, который я изменяю размер окна.
  3. Когда я прекращаю изменение размера, этот метод не вызывается, метод componentResized делает.

КогдаЯ добавляю свой repaint-метод (или официальный repaint-метод) к событию «live» -izeize, как это, я все еще получаю вывод, однако, это не перерисовка или что-то еще

public void componentMoved(ComponentEvent e) {
    System.out.println("Live-resize");
    this.contentView.paint(this.contentView.getGraphics());
}

или

public void componentMoved(ComponentEvent e) {
    System.out.println("Live-resize");
    this.contentView.repaint();
}

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

Я не использую Graphics2D или что-то, просто Graphics.

Не могли бы вы объяснить, как я могу перекрасить взгляды?

Заранее спасибо, Тим

Ответы [ 3 ]

6 голосов
/ 21 августа 2010

Для справки, здесь та же программа, использующая Swing.Поскольку JPanel имеет двойную буферизацию, она не мерцает при отпускании мыши после изменения размера.

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class SwingPaint {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new CirclePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    private static class CirclePanel extends JPanel {

        private static final Random r = new Random();

        public CirclePanel() {
            this.setPreferredSize(new Dimension(320, 240));
            this.setForeground(new Color(r.nextInt()));
            this.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    CirclePanel.this.update();
                }
            });
        }

        public void update() {
            this.setForeground(new Color(r.nextInt()));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Dimension size = this.getSize();
            int d = Math.min(size.width, size.height) - 10;
            int x = (size.width - d) / 2;
            int y = (size.height - d) / 2;
            g.fillOval(x, y, d, d);
            g.setColor(Color.blue);
            g.drawOval(x, y, d, d);
        }
    }
}
5 голосов
/ 21 августа 2010

Я больше знаком с Swing, но статья Рисование в AWT и Swing различает рисование, запускаемое системой и приложением. В приведенном ниже примере показано, как система вызывает paint() при изменении размера окна, а приложение вызывает repaint(), что вызывает update() в ответ на событие мыши. Поведение кроссплатформенное.

import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class AWTPaint {

    public static void main(String[] args) {
        Frame frame = new Frame();
        frame.add(new CirclePanel());
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.pack();
        frame.setVisible(true);
    }

    private static class CirclePanel extends Panel {

        private static final Random r = new Random();

        public CirclePanel() {
            this.setPreferredSize(new Dimension(320, 240));
            this.setForeground(new Color(r.nextInt()));
            this.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    CirclePanel.this.repaint();
                }
            });
        }

        @Override
        public void update(Graphics g) {
            this.setForeground(new Color(r.nextInt()));
        }

        @Override
        public void paint(Graphics g) {
            Dimension size = this.getSize();
            int d = Math.min(size.width, size.height) - 10;
            int x = (size.width - d) / 2;
            int y = (size.height - d) / 2;
            g.fillOval(x, y, d, d);
            g.setColor(Color.blue);
            g.drawOval(x, y, d, d);
        }
    }
}
0 голосов
/ 22 августа 2010

Хорошо, я наконец исправил это.

Вместо того, чтобы перерисовывать его каждый раз в paint(Graphics g) -методе, вам нужно буферизовать вывод и перерисовывать только это изображение (я надеялся, что Java уже будет это делать, точно так же, как Obj-C).

public BufferedImage buffer;

public void redraw() {
    buffer = new BufferedImage(
            200, // height
            300, // width
            BufferedImage.TYPE_4BYTE_ABGR); // ABGR = RGBA, 4-byte (r, g, b, a) per pixel
    Graphics g = buffer.getGraphics();
    // do your drawing here
    if (this.getGraphics()) {
        // 'this' is already shown, so it needs a redraw
        this.paint(this.getGraphics()); // little hack
    }
}

public void update(Graphics g) {
    this.paint(g);
}

public void paint(Graphics g) {
    g.drawImage(buffer, 0, 0, this);
}

Теперь, когда вы свернете окно и снова развернете его, картины останутся. Только окно сейчас мигает в течение 0,1 секунды или около того, но мне это безразлично.

...