Метод рисования Java мигает и исчезает - PullRequest
1 голос
/ 06 февраля 2011

Привет, я пытался возиться с Java GUI, изменяя созданную мной программу, которая рисовала набор mandelbrot, но когда я помещал выражения if в метод рисования, это заставляло изображение мигать на экране, а затем стиралось вчерный экран.

Это мой метод рисования:

public void paintComponent(Graphics g)
{
    if (clicked == false && count == 0)
    {

        drawMandelbrot(g); //sends graphics object to the method that draws the Mandelbrot set
        clicked = !clicked;
    }

    zoom(g);
    repaint();

}

public void zoom(Graphics g)
{

    if (count > 0 && clicked == false)
    {
        g.setColor(Color.white);
        g.fillRect(0,0, 400, 400);

        clicked = !clicked;
    }
}

Я знаю, что функция drawMandelbrot () замечена неправильно, потому что она работала раньше, и я знаю, что это не должно бытьфункция zoom (), потому что счет увеличивается только при нажатии мыши.

Есть идеи ?!Я пытался комментировать так много частей, и иногда это остается на экране, но я запускаю его снова, и это не так.Является ли Swing / AWT таким шатким?

ОБНОВЛЕНИЕ:

Я понял, что проблема связана с настройкой цвета фона.Я установил цвет фона рамки в основной функции, но по какой-то причине (все еще неизвестной мне) после рисования изображения, он снова установил цвет фона поверх него.

public Mandelbrot (int w, int h) //constructor method that is only utilized to bring in the size of the screen
{
    this.setBackground(Color.BLACK);
    addMouseListener(this);
    clicked = false;
    count = 0;
}

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (clicked == false && count == 0)
    {

        drawMandelbrot(g); //sends graphics object to the method that draws the Mandelbrot set
        clicked = !clicked;
    }

    zoom(g);

}

public void zoom(Graphics g)
{

    if (count > 0 && clicked == false)
    {
    }
}
public void mouseReleased(MouseEvent e) 
{
        zoomX = e.getX();
        count ++;
        clicked = !clicked;
        repaint();
        System.out.print(clicked);
}

ОБНОВЛЕНИЕ 2: Этовсе еще не работает, он работал в первый раз, но я попытался запустить его снова и повторить то же самое, что и раньше, и он закончился черной рамкой.

Ответы [ 2 ]

1 голос
/ 06 февраля 2011

Вызовите super.paintComponent() в начале вашего вызова метода, чтобы дескриптор Swing рисовал остальную часть компонента.См. Эту статью для получения дополнительной информации о компонентах рисования в Swing .Но в основном метод paintComponent() выполняет реальную работу, рисуя компоненты, которые вы пытаетесь отобразить, и все они отключаются при переопределении.Позвонив по номеру super.paintComponent(), вы заставляете Swing делать то, что нужно, чтобы все правильно нарисовать, , а затем он также рисует то, что вы хотите нарисовать.

Обновление Мне интересно, не связано ли это с вашей логикой в ​​отношении "нажал".Когда вы звоните repaint(), он перерисовывает всю панель с нуля.Это означает, что если вы хотите, чтобы что-то сохранялось с течением времени, вам нужно либо a) не вызывать repaint, ни позволять Swing вызывать repaint, например, изменяя размер окна;или б) убедитесь, что ваш метод перекраски всегда рисует то, что вы хотите.Вообще говоря, б) - лучший подход, так как он более устойчивый.

Поэтому я хотел бы, чтобы вы попытались реструктурировать свой код так, чтобы он не имел никаких условий в методе paintComponent(), так что независимо от того, сколькораз он вызывается, объект все равно рисуется.

Проблема, с которой вы можете столкнуться (вероятно, именно поэтому вы структурировали свой код так, как вы это сделали), - это время, необходимое для создания объекта, который вы хотите нарисоватьможет быть слишком долго, чтобы оправдать перерисовку все время.Если это проблема, вам нужно переделать логику вашей программы так, чтобы вы вычислили то, что хотите нарисовать в другом потоке (см. SwingUtilities.invokeLater()), а затем, когда вы вызываете paintComponent(), просто рисуете ранее вычисленное значение.

0 голосов
/ 16 февраля 2011

Поместите System.out.println( список релевантных переменных ); в начале каждого метода, чтобы получить четкую картину порядка, в котором он происходит.

Было бы полезно узнать, что происходит в zoom(g), поскольку вы не включили это.

Также было бы полезно, чтобы вы исправили сообщение, чтобы метод mouseReleased был правильно отформатирован. Я пропустил это в первый раз! :)

Некоторая логика кажется немного ... сомнительной.

Оба оператора if проверяют clicked==false, но это будет верно только для первого элемента paintComponent после каждого отпускания мыши. Я не эксперт по Swing, я могу основывать свои знания только на AWT, но разве функция paintComponent вызывается довольно часто? Вероятно, это однажды картина, потом ее вспоминают, и снова картина - только на этот раз (clicked==false) верно. Отсюда и «вспышка».

Я бы порекомендовал нарисовать поворотный круг на изображении, затем скопировать изображение в компонент, используя getGraphics().drawImage(img, 0, 0 null);, а затем вы просто копируете готовое изображение в каждой краске.

Следующий код полностью не проверен. Я не несу ответственности за это. ; -)

BufferedImage mbrot = null;
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (mbrot==null || mbrot.getWidth()!=getWidth() || mbrot.getHeight()!=getHeight())
    {
        mbrot = new BufferedImage(getWidth(), getHeight(), null);
    }
    if (clicked == false)
    {
        Graphics mg = mbrot.getGraphics();
        if (count==0)
        {
            drawMandelbrot(mg); //sends graphics object to the method that draws the Mandelbrot set
            clicked = !clicked;
        }
        else
        {
            zoom(mg);
        }
        mg.dispose();
    }
    g.drawImage(mbrot, 0, 0, null);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...