2010-02-19 87 views
1

这里是我的JFrame代码:JComponent不可见,任何人都知道为什么?

public static void main(String[] args) { 
    JFrame jf = new JFrame(); 
    jf.setSize(600,600); 
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    MyCustomWidget widget = MyCustomWidget.createWidget(400, 400); 
    widget.setVisible(true); 
    // just to set x and y 
    widget.setLocation(40, 40); 

    jf.getContentPane().add(widget); 
    jf.setVisible(true); 
} 

和这里的代码MyCustomWidget

public class MyCustomWidget extends JComponent { 

    public void paint(Graphics g) 
    { 
     super.paint(g); 
    } 

    public static MyCustomWidget createWidget(int width,int height) 
    { 
     MyCustomWidget tw = new MyCustomWidget(); 
     tw.setBounds(0,0,width,height); 
     tw.setBackground(Color.RED); 
     return tw; 
    } 
} 

的事情是,在窗口中没有显示的JComponent,我不明白为什么。我甚至添加了一个widget.setVisible(true)只是为了确保它是可见的。什么都没有你能发现我做错了什么吗?

你们提出的修改之后,现在该代码:

包javaapplication2;

public class Main { 

    public static void main(String[] args) throws IOException { 

     SwingUtilities.invokeLater(new Runnable() { 

      public void run() { 
       JFrame jf = new JFrame(); 
       jf.setSize(600,600); 
       jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       jf.setLayout(null); 

       JComponent container = (JComponent) jf.getContentPane(); 
       container.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION); 
       DebugGraphics.setFlashColor(Color.RED); 
       DebugGraphics.setFlashCount(2); 
       DebugGraphics.setFlashTime(100); 

       MyCustomWidget widget = MyCustomWidget.createTimeline(400, 400); 

       container.add(widget); 
       jf.setVisible(true); 
      } 

     }); 


    } 

} 

和:

public class MyCustomWidget extends JComponent { 

    public void paintComponent(Graphics g) 
    { 
     setForeground(Color.BLACK); 
     drawLines(g); 
    } 

    // a little something to see that something is drawed 
    private void drawLines(Graphics g) 
    { 
     int distanceBetween = getHeight()/numberOfLines; 
     int start = 0; 
     int colourIndex = 0; 
     Color colours[] = {Color.BLUE,Color.WHITE,Color.YELLOW}; 

     for(int i = 0;i < distanceBetween;start+=distanceBetween,i++) 
     { 
      g.setColor(colours[colourIndex]); 
      g.drawLine(0,start,40,40); 
      colourIndex %= colours.length; 
     } 
    } 

    private int numberOfLines = 4; 

    public MyCustomWidget() 
    { 
     setOpaque(true); 
    } 

    public static MyCustomWidget createTimeline(int width,int height) 
    { 
     MyCustomWidget tw = new TimelineWidget(); 
     tw.setBounds(0,0,width,height); 
     return tw; 
    } 
} 

回答

2

这里是发生在这里:

  • 你的JFrame的内容窗格中的默认布局是BorderLayout。这意味着您的组件被调整为内容窗格的整个大小。要加入你的组件之前解决这个问题的任何地方做
jf.getContentPane().setLayout(null); 
  • 背景不是在JComponent的直接后代的自动绘制。你可以让你的组件不透明(setOpaque(真)),从JPanel的扩展或重写paintComponent方法是这样
public void paintComponent (Graphics g) { 
    super.paintComponent (g); 
    g.setColor(getBackground()); 
    g.drawRect(0, 0, getWidth(), getHeight()); 
} 

编辑:

为了符合Swing线程规则的代码主要方法应该在EDT线程上运行。这意味着它必须包装成

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     // your code goes here 
    } 
} 
+0

这种似乎是工作的...但是,有时当我运行JFrame中没有显示,而其他时候,小部件的显示正确。我正在开发Kubuntu 9.04,并使用: Java版本“1.6。0_0“/ OpenJDK运行环境(IcedTea6 1.6.1)(6b16-1.6.1-3ubuntu1)/ OpenJDK客户端虚拟机(构建14.0-b16,混合模式,共享) – Geo 2010-02-19 19:57:35

+0

您的主要方法中的代码应该包装到 SwingUtilities.invokeLater遵守Swing线程规则 – 2010-02-19 20:02:06

+0

它在'invokeLater'中,但有时它仍然不会显示。 – Geo 2010-02-19 20:13:11

2

默认情况下JComponents不是不透明的,所以你的背景永远不会被绘制。拨打setOpaque(true)应该可以做到。失败

  1. ,如果你要编写自定义绘制代码,重写paintComponent(),不paint()
  2. 到UI组件的任何变动,必须在EventDispatchThread(EDT)提出:在你的代码

    2条评论要做到这一点通常会导致从不一致的行为到完全崩溃的不良后果。所以,在你的主你需要用你的代码的的invokeLater:

    SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         // your code goes here 
        } 
    } 
    
相关问题