2010-02-19 121 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 
        } 
    } 
    
相關問題