Как я могу перекрасить эффективно при использовании большого пользовательского компонента в Swing?

Вы можете использовать цикл, чтобы уменьшить количество строк. Вот оптимизированное решение, даже если у вас есть более 10 полей для проверки:

Объявите массив полей и проведите через него цикл

$fields = array("cname" => 100, "cowner" => 100, "cemail" => 200, "cpassword" => 100); // key as field name and value as maximum limit - new values can be added here.

foreach($fields as $field => $length) {
   if(strlen(${$field}) > $length) {
       die("$field field can only contain $length characters"); 
   }
}

Редактировать: Вы также можете сохранить все ошибки в массиве, а затем распечатать все ошибки на своей странице.

$errors = array();
foreach($fields as $field => $length) {
   if(strlen(${$field}) > $length) {
        $errors[] = "$field field can only contain $length characters"; 
   }
}
print_r($errors);
5
задан GEOCHET 18 May 2009 в 15:40
поделиться

7 ответов

Выполнять всю вашу математику Безье в потоке рисования каждый раз при обновлении компонента - (как вы уже поняли) - плохая идея. Ваша кривая часто меняется? Если нет, то почему бы не нарисовать его в BufferedImage по мере его изменения и не изменить код paint (), чтобы вместо этого просто рисовать буферизованное изображение в компоненте.

class CurveComponent extends JComponent {
    private BufferedImage image;

    @Override
    public void paintComponent( Graphics g ) {
        if ( image == null ) {
            return;
        }
        g.drawImage( image, 0, 0, this );
    }

    private void updateCurve() {
        image = new BufferedImage( getWidth(), getHeight(), BufferedImage.ARGB );
        Graphics g = image.getGraphics();
        // draw the curve onto image using g.
        g.dispose();
    }
}

Вызывайте updateCurve () только тогда, когда вам нужно, и все это дорого математика не будет напрасно повторяться. Рисование должно быть достаточно отзывчивым даже для полноэкранного окна. drawImage () будет выполнять прямое копирование в память и должно быть молниеносно.

3
ответ дан 18 December 2019 в 13:18
поделиться

Какой метод вы используете для рисования кривой? краска или компонент краски?

1
ответ дан 18 December 2019 в 13:18
поделиться

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

  • Двойная буферизация. Для этого требуется огромный объем памяти, но копирование памяти выполняется очень быстро (обычно это происходит, когда «электронный луч» возвращается из нижнего правого в верхний левый ... если в вашем ЖК-дисплее все еще был луч).

  • Не вызывайте super.paint () (который рисует или «стирает» фон ) и не рисуйте кривую второй раз с цветом фона, чтобы стереть ее.

Подробнее см. этот документ .

[EDIT] Если fillRect () не является абстрактным, вы можете установить точку останова :) Установите точку останова в paint (), проверьте, кто ее вызывает и очистился ли фон в это время. Так и должно быть, поскольку рендеринг будет совершенно неправильным. Затем установите точки останова выше в цепочке вызовов.

2
ответ дан 18 December 2019 в 13:18
поделиться

Посмотрите Filthy Rich Clients Чет Хаасе и Ромен Гай. Они обращаются к этим самым оптимизациям среди других по пути создания отзывчивого и графически впечатляющего пользовательского интерфейса.

4
ответ дан 18 December 2019 в 13:18
поделиться

Попробуйте написать небольшое тестовое приложение, состоящее из ничего, кроме того, что нужно для воспроизведения этой проблемы. Это упростит профилирование. Затем разместите это приложение здесь, чтобы мы могли рассмотреть возможные решения.

Мне показался интересным ваш вопрос, поэтому я сам написал тестовое приложение. Это рисует кривую Безье, размер которой постоянно изменяется при перетаскивании. Я создал градиентный фон, чтобы убедиться, что он хорошо сочетается с неприятным фоном. У меня хорошая производительность и низкий уровень мерцания, хотя я использую первоклассную машину.

Стоит прочитать «Filthy Rich Clients», чтобы изучить все приемы написания собственных компонентов Swing, которые действительно хорошо работают.

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Point2D;

public class CustomComponent extends JComponent {

    private Point2D start = new Point2D.Double(0, 0);
    private Point2D end = new Point2D.Double(300, 200);

    private CustomComponent() {
        this.setOpaque(true);
        final MouseAdapter mouseAdapter = new MouseAdapter() {

            @Override
            public void mouseDragged(MouseEvent e) {
                    setEnd(e.getPoint());
            }

        };
        this.addMouseListener(mouseAdapter);
        this.addMouseMotionListener(mouseAdapter);
    }

    public void setStart(Point2D start) {
        this.start = start;
        repaint();
    }

    public void setEnd(Point2D end) {
        this.end = end;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {

        final Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // draw gradient background
        final int width = getWidth();
        final int height = getHeight();
        g2.setPaint(new GradientPaint(0, 0, Color.WHITE, width, height, Color.YELLOW));
        g2.fillRect(0, 0, width, height);

        // draw Bezier curve
        final Shape shape = new CubicCurve2D.Double(start.getX(), start.getY(), start.getX(), end.getY(), end.getX(), start.getY(), end.getX(), end.getY());
        g2.setColor(Color.BLACK);
        g2.draw(shape);

        g2.drawString("Click and drag to test for flickering", 100, 20);
    }

    public static void main(String[] args) {
        final CustomComponent component = new CustomComponent();
        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        final Dimension size = new Dimension(screenSize.width - 20, screenSize.height - 100);
        component.setPreferredSize(size);

        final JFrame frame = new JFrame();
        frame.add(component);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

Несколько замечаний:

  • перезаписывает только paintComponent (Graphics g), а не другие методы paintXXX ()
  • устанавливают непрозрачный пользовательский компонент, если это возможно
  • используйте repaint () только для запроса перерисовки. Никогда не заказывайте перерисовку прямо в коде. Это позволяет Swing справиться с этим хорошо.
3
ответ дан 18 December 2019 в 13:18
поделиться

Вы можете перерисовать меньшую часть экрана, используя repaint (Rectangle r)

http://java.sun.com/j2se/1.4.2/docs/api /javax/swing/JComponent.html#repaint(java.awt.Rectangle)

Затем вы упоминаете мерцание. Поскольку вы используете Swing, который использует двойную буферизацию, ваше мерцание должно исходить от чего-то другого. Вы очищаете экран в paintComponent (...) ? Т.е. вызов fillRect (...) ? Не делайте этого, это не нужно (IIRC).

1
ответ дан 18 December 2019 в 13:18
поделиться

Мое решение заключалось в частичном перепроектировании :

Теперь я не представляю каждый "кабельный" -элемент компонентом.
Теперь кабели - это просто фиктивные объекты (без задействованного JComponent).
Перерисовка происходит «глобально» на панели содержимого родительского JFrame .

Теперь это эффективно и меньше мерцает.

0
ответ дан 18 December 2019 в 13:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: