Rumah > Java > javaTutorial > Mengapakah menambah dan memfokus pada JTextField pada JPanel animasi berganda buffer dalam Swing menyebabkan masalah kelipan pada Mac OS X 10.5 dengan Java 1.6?

Mengapakah menambah dan memfokus pada JTextField pada JPanel animasi berganda buffer dalam Swing menyebabkan masalah kelipan pada Mac OS X 10.5 dengan Java 1.6?

Mary-Kate Olsen
Lepaskan: 2024-12-28 05:52:10
asal
210 orang telah melayarinya

Why does adding and focusing on a JTextField over a double-buffered animated JPanel in Swing cause flickering issues on Mac OS X 10.5 with Java 1.6?

JTextFields di atas lukisan aktif pada JPanel, masalah threading

Swing boleh digunakan untuk mencipta persekitaran pemaparan berbilang buffer yang betul di atas yang mana elemen antara muka pengguna Swing boleh ditambah. Dalam kes ini, kami mempunyai segi empat tepat merah animasi yang dilukis pada latar belakang. Latar belakang tidak perlu dikemas kini setiap bingkai, jadi kami memaparkannya pada BufferedImage dan lukis semula hanya bahagian yang diperlukan untuk mengosongkan lokasi sebelumnya segi empat tepat.

Setakat ini; animasi lancar, penggunaan cpu rendah, tidak berkelip. Kemudian kami menambah JTextField pada Jpanel (dengan mengklik mana-mana kedudukan pada skrin), dan fokus padanya dengan mengklik di dalam kotak teks. Mengosongkan lokasi segi empat tepat sebelumnya kini gagal pada setiap kelipan kursor, lihat imej di bawah.

Kami ingin tahu jika sesiapa mempunyai idea mengapa ini mungkin berlaku (Swing tidak selamat untuk benang? Imej sedang dicat secara tidak segerak?) dan ke arah mana untuk mencari penyelesaian yang mungkin.

Ini pada Mac OS 10.5, Java 1.6.

NewTest memanjangkan JPanel; tetapi kerana anda tidak melukis setiap piksel pada setiap panggilan ke paintComponent(), anda perlu menggunakan kaedah kelas super dan memadam lukisan lama:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    int width = this.getWidth();
    int height = this.getHeight();
    g.setColor(Color.black);
    g.fillRect(0, 0, width, height);
    ...
}
Salin selepas log masuk

Tambahan: Seperti yang anda perhatikan, menetapkan latar belakang warna dalam pembina menghalang keperluan untuk mengisi panel dalam paintComponent(), manakala super.paintComponent() membenarkan medan teks berfungsi dengan betul. Seperti yang anda perhatikan, penyelesaian yang dicadangkan adalah rapuh. Sebaliknya, permudahkan kod dan optimumkan seperti yang dibenarkan. Sebagai contoh, anda mungkin tidak memerlukan komplikasi inset, penimbal tambahan dan pendengar komponen.

Tambahan 2: Ambil perhatian bahawa super.paintComponent() memanggil kaedah kemas kini() perwakilan UI, "yang mengisi komponen yang ditentukan dengan warna latar belakangnya (jika sifat legapnya adalah benar)." Anda boleh menggunakan setOpaque(false) untuk menghalang perkara ini.

Versi kod yang dipertingkatkan lagi, dengan beberapa ciri dan pengoptimuman tambahan:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

/** @see http://stackoverflow.com/questions/3256941 */
public class AnimationTest extends JPanel implements ActionListener {

    private static final int WIDE = 640;
    private static final int HIGH = 480;
    private static final int RADIUS = 25;
    private static final int FRAMES = 24;
    private final Timer timer = new Timer(20, this);
    private final Rectangle rect = new Rectangle();
    private BufferedImage background;
    private int index;
    private long totalTime;
    private long averageTime;
    private int frameCount;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new AnimationTest().create();
            }
        });
    }

    private void create() {
        JFrame f = new JFrame("AnimationTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        timer.start();
    }

    public AnimationTest() {
        super(true);
        this.setOpaque(false);
        this.setPreferredSize(new Dimension(WIDE, HIGH));
        this.addMouseListener(new MouseHandler());
        this.addComponentListener(new ComponentHandler());
    }

    @Override
    protected void paintComponent(Graphics g) {
        long start = System.nanoTime();
        super.paintComponent(g);
        int w = this.getWidth();
        int h = this.getHeight();
        g.drawImage(background, 0, 0, this);
        double theta = 2 * Math.PI * index++ / 64;
        g.setColor(Color.blue);
        rect.setRect(
            (int) (Math.sin(theta) * w / 3 + w / 2 - RADIUS),
            (int) (Math.cos(theta) * h / 3 + h / 2 - RADIUS),
            2 * RADIUS, 2 * RADIUS);
        g.fillOval(rect.x, rect.y, rect.width, rect.height);
        g.setColor(Color.white);
        if (frameCount == FRAMES) {
            averageTime = totalTime / FRAMES;
            totalTime = 0; frameCount = 0;
        } else {
            totalTime += System.nanoTime() - start;
            frameCount++;
        }
        String s = String.format("%1.3f", averageTime / 1000000d);
        g.drawString(s, 5, 16);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        this.repaint();
    }

    private class MouseHandler extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            super.mousePressed(e);
            JTextField field = new JTextField("test");
            Dimension d = field.getPreferredSize();
            field.setBounds(e.getX(), e.getY(), d.width, d.height);
            add(field);
        }
    }

    private class ComponentHandler extends ComponentAdapter {

        private final GraphicsEnvironment ge =
            GraphicsEnvironment.getLocalGraphicsEnvironment();
        private final GraphicsConfiguration gc =
            ge.getDefaultScreenDevice().getDefaultConfiguration();
        private final Random r = new Random();

        @Override
        public void componentResized(ComponentEvent e) {
            super.componentResized(e);
            int w = getWidth();
            int h = getHeight();
            background = gc.createCompatibleImage(w, h, Transparency.OPAQUE);
            Graphics2D g = background.createGraphics();
            g.clearRect(0, 0, w, h);
            g.setColor(Color.green.darker());
            for (int i = 0; i < 128; i++) {
                g.drawLine(w / 2, h / 2, r.nextInt(w), r.nextInt(h));
            }
            g.dispose();
            System.out.println("Resized to " + w + " x " + h);
        }
    }
}
Salin selepas log masuk

Atas ialah kandungan terperinci Mengapakah menambah dan memfokus pada JTextField pada JPanel animasi berganda buffer dalam Swing menyebabkan masalah kelipan pada Mac OS X 10.5 dengan Java 1.6?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan