Попробуйте написать крошечное тестовое приложение, которое не содержит ничего, кроме того, что вам нужно для воспроизведения этой проблемы. Это облегчит профилирование. Затем опубликуйте это приложение здесь, чтобы мы могли взглянуть на возможные решения.
Я нашел ваш вопрос интересным, поэтому сам написал тестовое приложение. Это рисует кривую Безье, которая постоянно изменяется при перетаскивании. Я создал градиентный фон, чтобы он хорошо работал с неприятным фоном. Я получаю хорошую производительность и низкий уровень мерцания, хотя я использую первоклассный аппарат.
Стоит почитать «Грязных богатых клиентов», чтобы изучить все приемы написания пользовательских компонентов 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 справиться с этим хорошо.