1
import javax.swing.JFrame;
import javax.swing.JTextField;

import com.sun.awt.AWTUtilities;

@SuppressWarnings("serial")
public class TranslucentIssueTest extends JFrame
{
    public static void main(String[] args)
    {
        (new TranslucentIssueTest()).setVisible(true);
    }

    public TranslucentIssueTest()
    {
        super();
        setUndecorated(true);
        setLayout(null);
        setSize(300, 300);
        AWTUtilities.setWindowOpaque(this, false);

        JTextField box = new JTextField();
        box.setBounds(30, 150, 100, 25);
        add(box);
    }
}

上記のコードは、透明なフレームにテキスト フィールドを作成します。

しかし、入力方法を使用してボックスにいくつかの漢字を入力すると、透明効果が自動的に削除されました。私のコードに何か問題がありますか?

前もって感謝します。

4

1 に答える 1

2

同じ問題のように見えるものに遭遇し、検索中にこの質問を見つけた人のために私の解決策を投稿すると思いました. この問題は、Swing の DirectDraw パイプラインのバグが原因のようです。古いバージョンの Java 7 (update 5) を使用しているため、これは後のリリースで修正されている可能性があります。

問題は特に IME にあるようには見えませんが、IME がアクティブなときにテキスト フィールドによって行われるレンダリング呼び出しに問題があるようです。

この問題を回避する最も簡単な方法は、GUI コードを実行する前に次の呼び出しを行って DirectDraw レンダリングを無効にすることです。

System.setProperty("sun.java2d.noddraw", "true");

JTextFieldDirectDraw レンダリングを完全に無効にしたくない場合は、以下の例のようにメソッドをオーバーライドしpaintComponentてバッファに書き込むことで、特定の問題を回避できます。

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;

public class Test {

    public static class JTextField2 extends JTextField {
        private static final long serialVersionUID = 1L;
        private BufferedImage buffer = null;

        @Override public void paintComponent(Graphics g) {
            Component window = this.getTopLevelAncestor();
            if (window instanceof Window && !((Window)window).isOpaque()) {
                // This is a translucent window, so we need to draw to a buffer
                // first to work around a bug in the DirectDraw rendering in Swing.
                int w = this.getWidth();
                int h = this.getHeight();
                if (buffer == null || buffer.getWidth() != w || buffer.getHeight() != h) {
                    // Create a new buffer based on the current size.
                    GraphicsConfiguration gc = this.getGraphicsConfiguration();
                    buffer = gc.createCompatibleImage(w, h, BufferedImage.TRANSLUCENT);
                }

                // Use the super class's paintComponent implementation to draw to
                // the buffer, then write that buffer to the original Graphics object.
                Graphics bufferGraphics = buffer.createGraphics();
                try {
                    super.paintComponent(bufferGraphics);
                } finally {
                    bufferGraphics.dispose();
                }
                g.drawImage(buffer, 0, 0, w, h, 0, 0, w, h, null);
            } else {
                // This is not a translucent window, so we can call the super class
                // implementation directly.
                super.paintComponent(g);
            }        
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
                final JFrame frame = new JFrame();
                frame.setUndecorated(true);
                frame.setBackground(new Color(96, 128, 160, 192));

                JTextField textField = new JTextField2();                
                JButton exitButton = new JButton("Exit");
                exitButton.addActionListener(new ActionListener() {
                    @Override public void actionPerformed(ActionEvent e) {
                        frame.dispose();
                    }
                });

                frame.add(exitButton, BorderLayout.PAGE_START);
                frame.add(textField, BorderLayout.PAGE_END);

                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
于 2013-04-07T19:16:19.943 に答える