1

これが私の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)。何も機能しません。私が間違っていることを見つけられますか?

皆さんが提案した変更の後、コードは次のようになります。

パッケージ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;
    }
}
4

2 に答える 2

2

ここで何が起こるか:

  • 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 スレッド規則に準拠するには、メイン メソッドのコードを EDT スレッドで実行する必要があります。つまり、ラップする必要があります

SwingUtilities.invokeLater(new Runnable() {
     public void run() {
         // your code goes here
     } 
}
于 2010-02-19T19:37:46.810 に答える
2

デフォルトでは、JComponents は不透明ではないため、背景が描画されることはありません。への呼び出しsetOpaque(true)でうまくいくはずです。

コードに関する 2 つのコメント:

  1. カスタム ペイント コードを作成する場合は、overridepaintComponent()ではなくpaint()
  2. UI コンポーネントへの変更は、EventDispatchThread (EDT) で行う必要があります。これを行わないと、一貫性のない動作から完全なクラッシュまで、一般的に悪いことが起こります。したがって、メインでは、コードを invokeLater でラップする必要があります。

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // your code goes here
        }
    }
    
于 2010-02-19T19:40:46.673 に答える