0

ボタンがクリックされたときに、装飾されていないJFrameをそのすぐ下に表示する基本的なコントロールを構築しようとしています。ドロップダウンタイプの機能を模倣しようとしていますが、パネルの代わりに独自のフレームを使用しています。私のコンポーネントには、表示したいJFrame派生コントロールのクラスメンバーが含まれています。特定の状況では、setVisibleが呼び出されたときに、このJFrameのコンテンツはペイントされません。これは、負のx座標を使用する左端のモニターにJFrameを表示しようとしているときに発生しているようです(私のプライマリモニターは中央のモニターです)。奇妙なことに、この問題は私のWindows 7マシンでのみ発生し、XPマシンでは発生しません。

これは、問題を示す非常に基本的なサンプルです。ご覧のとおり、DropFrameを非表示および表示するだけの非常に基本的なサンプルです。initComponentsからコードを省略しました。この場合、各フレームにボタンを追加し、各ボタンに必要なActionListenersを追加します。

コード:

public class NewJFrame extends javax.swing.JFrame {
private javax.swing.JButton jButton2;
private DropFrame f = new DropFrame();

/** Creates new form NewJFrame */
public NewJFrame() {
    initComponents();
}

private void initComponents() {
    //Create button and add it to the frame...
    pack();
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)        {                                         
    SwingUtilities.invokeLater(new Runnable() 
    {
        public void run() {
            Point p = jButton2.getLocationOnScreen();
            f.setLocation(p.x, p.y + 25);
            f.setVisible(true);
        }
    });

}                                        

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
} }

public class DropFrame extends javax.swing.JFrame {
private javax.swing.JButton jButton1;  

/** Creates new form NewJFrame1 */
public DropFrame() {
    initComponents();
}

private void initComponents() {
    //Create button and add to frame...
    pack();
}                   

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)    {                                         
    this.setVisible(false);
} }                                                  

同じフレームの可視性を再利用して設定するのではなく、ボタンをクリックするたびに新しいDropFrameを作成しても問題は発生しませんが、これは望ましくありません。私のDropFrameが時々ペイントされない理由について何かアイデアはありますか?

4

1 に答える 1

1

注目すべき点がいくつかあります。

#1 どのバージョンのJVMを実行していますか?Sunは、1.6のさまざまなリリースでグラフィックスパイプラインに多くの変更を加えています。プレアップデート10リリースは、それ以降のリリースとはまったく異なる動作をします。(注:Firefox 3.6以降では、アプレットが機能するためにアップデート10以降が必要です。)

#2 initコンポーネントに、次の行を追加します。

    Point location = getLocation();
    setLocation(new Point(0, 0));
    setLocation(location);
    pack();

setLocation()最終的にへの呼び出しComponent.notifyNewBounds(boolean resized, boolean moved)。これは、各コンポーネントの境界を設定するコンポーネント階層をトラバースします。

デフォルトでは、これは「怠惰に」行われるため、コンポーネントがどこにあるか(またはどこにあるべきか)を計算するときにJavaにいくつかの問題が発生するようです。上記のコードは、境界を前もって計算するように強制します。

#3 u10以降を実行している場合は、引数を指定してアプリケーションを起動します

-Dsun.java2d.d3d=false

これにより、DirectXパイプラインが無効になります。それで問題が解決する場合は、ディスプレイドライバを更新してください。

于 2010-02-18T16:53:23.980 に答える