2011-12-30 53 views
2

在下面的简单代码中,我只需创建一个框架,然后在其中添加一个JPanelmenubar即可。JFrame的奇怪显示问题

public class MainFrame extends JFrame { 
    private DrawPanel drawPanel; 
    public MainFrame() 
    { 
     super("Coordinate Geometry Visualiser"); 
     drawPanel = new DrawPanel(); 
     add(drawPanel); 

     JMenu fileMenu = new JMenu("File"); 
     fileMenu.setMnemonic('F'); 

     JMenuItem newItem = new JMenuItem("New"); 
     newItem.setMnemonic('N'); 
     fileMenu.add(newItem); 

     JMenuBar menuBar = new JMenuBar(); 
     setJMenuBar(menuBar); 
     menuBar.add(fileMenu); 

     JMenu editMenu = new JMenu("Edit"); 
     editMenu.setMnemonic('E'); 
     menuBar.add(editMenu); 
    } 
} 

抽奖面板代码 -

public class DrawPanel extends JPanel { 
    public DrawPanel() 
    { 
    } 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponents(g); 
     setBackground(Color.BLACK); 
     g.setColor(Color.RED); 
     g.drawLine(100, 50, 150, 100); 
    } 
} 

,最后用main()

public class CGVApplication { 
    public static void main(String[] args) { 
     MainFrame appFrame = new MainFrame(); 
     appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     appFrame.setSize(300, 275); 
     appFrame.setVisible(true); 
    } 
} 

应用程序在运行中日食的应用程序,这是我所得到的 - enter image description hereenter image description here

为什么双菜单栏线?这非常烦人。在循环应用程序或弹出窗口时,重绘的窗口很好(右侧图像)。

也在我的DrawPanelpaintComponent我将背景设置为黑色,但没有效果?

上述两个问题的原因是什么?请帮忙!

+0

您通常在初始化组件时设置背景色,而不是在绘制方法中。尝试将该行移至构造函数。 - 对于加倍问题:这只是一个猜测,但尝试添加此行之前打开框架:'System.setProperty(“sun.java2d.noddraw”,“true”);' – Thomas 2011-12-30 07:26:57

+0

嘿谢谢,移动(或评论)这行'setBackground(Color.BLACK);'从paint到构造函数解决了双线和菜单的问题。但面板仍然不是黑色。也许你应该添加你的评论作为答案。顺便说一句'setProperty'没有帮助。 – 2011-12-30 07:39:57

回答

5

您正在调用Container.paintComponents()方法。它必须是super.paintComponent(g)

@Override 
public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); //super.paintComponents(g); 
    setBackground(Color.BLACK); 
    g.setColor(Color.RED); 
    g.drawLine(100, 50, 150, 100); 
} 
+2

+1:没有注意到超级中的s。paintComponents()! – 2011-12-30 08:20:06

+0

解决了问题!是的@JBNizet - 请取消删除您的帖子。 – 2011-12-30 08:29:29

+1

我将其删除。它更具信息性,但并不像您的解决方案那样正确。 – 2011-12-30 08:39:34

3

的Javadoc提到

  • isOpaque必须是真实的
  • ,取决于在L &女,这个属性可以被忽略
  • 是JComponent的子类必须重写paintComponent以遵守此属性。

将setBackground放在构造函数中,并在paintComponent(在绘制红色线条之前)中添加这两行代码使面板变黑。

g.setColor(getBackground()); 
g.fillRect(getX(), getY(), getWidth(), getHeight()); 

另请注意,应始终在EDT中创建和修改Swing组件。您的主要方法应该是这样的:

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      MainFrame appFrame = new MainFrame(); 
      appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      appFrame.setSize(300, 275); 
      appFrame.setVisible(true); 
     } 
    }); 
} 
+1

你是在暗示多线程?嗯,将不得不学习它。 – 2011-12-30 08:42:03

+0

我不是建议多线程。所有的摆动组件只能由单个线程使用:事件调度线程。您的代码正在主线程中使用组件。请参阅http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threading,它由每个swing组件的javadoc链接到。 – 2011-12-30 08:47:18