簡體   English   中英

JComponent不可見,有誰知道為什么?

[英]JComponent is not visible, anyone knows why?

這是我的JFrame代碼:

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) ,以確保它是可見的。 什么都行不通。 你能發現我做錯了什么嗎?

經過你們建議的修改后,代碼現在是:

package 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;
    }
}

這是這里發生的事情:

  • JFrame內容窗格的默認布局是BorderLayout。 這意味着您的組件將調整為內容窗格的整個大小。 要在添加組件之前在任何地方修復此問題
  jf.getContentPane().setLayout(null); 
  • 在JComponent的直接后代中不會自動繪制背景。 您可以使組件不透明(setOpaque(true)),從JPanel擴展或覆蓋paintComponent方法,如下所示
  public void paintComponent (Graphics g) { super.paintComponent (g); g.setColor(getBackground()); g.drawRect(0, 0, getWidth(), getHeight()); } 

編輯:

為了符合Swing線程規則,main方法中的代碼應該在EDT線程上運行。 這意味着必須將其包裹起來

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

默認情況下,JComponents不是不透明的,因此您的背景永遠不會被繪制。 調用setOpaque(true)應該可以解決問題。

對您的代碼有2條評論:

  1. 如果要編寫自定義繪制代碼,則覆蓋paintComponent() ,而不是paint()
  2. 必須在EventDispatchThread(EDT)上對UI組件進行任何更改,如果不這樣做,將導致從不一致的行為到完全崩潰等一般不好的事情。 因此,在您的主要內容中,您需要將代碼包裝在invokeLater中:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM