为什么我的JFrame内容有时没有被绘制?

时间:2010-02-17 16:15:00

标签: java swing awt jframe

我正在尝试构建一个基本控件,当单击一个按钮时,它将在其下方显示未修饰的JFrame。我试图模仿下拉类型功能,但使用我自己的Frame而不是面板。我的组件包含我希望它显示的JFrame派生控件的类成员。在某些情况下,调用setVisible时,不会绘制此JFrame的内容。当我试图在最左边的显示器上显示JFrame时,这似乎正在发生,它使用负x坐标(我的主监视器是中间监视器)。奇怪的是这个问题只出现在我的Windows 7机器上,而不是出现在XP机器上。

这是一个演示问题的非常基本的示例。如您所见,这是一个非常基本的示例,应该只是隐藏和显示DropFrame。我已经省略了initComponents中的代码,在这种情况下,只需要为每个框架添加一个按钮,并为每个按钮添加必要的ActionListener。

代码:

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,而不是重用和设置相同Frame的可见性,则问题不存在,但这不是必需的。 关于为什么我的DropFrame有时没有画过的任何想法?

1 个答案:

答案 0 :(得分:1)

以下是一些要注意的事项:

<强>#1 你在运行什么版本的JVM? Sun在1.6版的不同版本中对图形管道进行了大量更改。预更新10版本的行为与以后的版本完全不同。 (注意:Firefox 3.6+需要更新10或更高版本才能使applet正常工作。)

<强>#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管道。如果这样会导致问题消失,请更新显示驱动程序。