Applet
(и JApplet
) официально устарели, они больше не поддерживаются Java, Oracle, браузерами (или сообществом в целом)
Компоненты Swing по умолчанию имеют двойную буферизацию. Если вы работаете с системой окраски правильно, вы не должны испытывать мерцания, если вы это делаете, это явный признак того, что вы делаете что-то не так.
Я бы порекомендовал взглянуть на Выполнение пользовательского рисования и Рисование в AWT и Swing для получения более подробной информации о том, как работает система рисования Swing.
Качели однопоточные И не безопасны для нитей. Это означает, что вы не должны выполнять никаких длительных операций в контексте потока диспетчеризации событий и не должны обновлять пользовательский интерфейс вне контекста EDT.
Посмотрите Параллельность в Swing для получения более подробной информации.
Простым решением этих проблем является использование Swing Timer
, который можно использовать для планирования регулярных обновлений, которые выполняются в контексте EDT.
См. Как использовать Swing Timers для получения более подробной информации ...
В качестве основного работоспособного примера ...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
public static final int WIDTH = 700, HEIGHT = 500;
public TestPane() {
setLayout(new GridBagLayout());
add(new JButton("Big fat button"));
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(WIDTH, HEIGHT);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, WIDTH, HEIGHT);
g2d.setColor(Color.WHITE);
g2d.fillRect(50, 50, 100, 100);
g2d.setFont(new Font("Century", Font.BOLD, 30));
g2d.drawString("I feel good sometimes I don't", 200, 200);
g2d.dispose();
}
}
}
Ладно, «Но я абсолютно, должен, без вопросов, использовать Applet
... ?, тогда мне вас жаль, но это не меняет того факта, что Swing уже имеет двойную буферизацию. Приведенный выше пример можно легко применить к J/Applet
, просто создав экземпляр JPanel
и добавив в Applet
контейнер
Swing использует алгоритм «пассивного рендеринга», если вам абсолютно необходим полный контроль, вы можете взглянуть на BufferStrategy
, который передает вам полный контроль над системой рисования, но вы не сможете использовать компоненты Swing, так как они обновляются подсистемой Swing