簡體   English   中英

Gui 圖形未出現在面板中

[英]Gui graphic does not appear in Panel

我試圖通過使用我設置為NorthEast的兩個按鈕使drawOval移動,因此球將在中心的 JButton 之間移動。

為什么不出現在面板上?

此外,我正在考慮使用一個使x=x+的函數; 當我向左或向右按​​下時, y=y+1

我不知道我能做什么。

所以這是我制作的代碼:

public class Main extends JFrame implements ActionListener {

    JButton left;
    JButton right;
    JPanel p;

    Main(){ 
    JButton left = new JButton("left"); 
    left.addActionListener(this);
    left.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {

        //The first way I think is better to make it move.  
        }
    });
    JButton right = new JButton("right");   
    right.addActionListener(this);


    Panel p = new Panel();
    p.setLayout(new BorderLayout());

    p.add("West",left);// to the left
    p.add("East",right);//to the right 

    Container c = getContentPane();     
    c.add(p);

    }           
    public static void main(String[] args) {
        Main f=new Main();
        f.setTitle("Heracles");
        f.setSize(500, 500);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);     //this is the window
    }

    public void paintComponent (Graphics g) {
           super.paintComponents(g);
           Graphics2D g1=(Graphics2D) g;
            g.drawOval(3, 5, 45, 46); // The ball
            g.fillOval(20, 30, 40, 40);     

        }
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }   
}

要了解為什么它不起作用,您需要了解油漆系統的實際工作原理

僅通過查看此代碼段,就應該很明顯有問題。

public class Main extends JFrame implements ActionListener {
    //...    
    public void paintComponent (Graphics g) {
        super.paintComponents(g);
        //...
    }
}

您已經聲明了一個名為paintComponent的方法,但正在調用super 方法paintComponents (注意末尾的s )。

此外,當你“認為”你正在重寫一個方法時,你應該使用#Override屬性,當你做錯了什么時這會導致編譯器錯誤

public class Main extends JFrame implements ActionListener {
    //... 
    @Overrride   
    public void paintComponent (Graphics g) {
        super.paintComponents(g);
        //...
    }
}

上面的代碼現在將無法編譯,因為JFrame沒有聲明paintComponent方法。

作為一般規則,您應該避免直接從JFrame (或其他頂級容器)擴展,它們是復合組件並且具有復雜的層次結構和功能。

一個更好的起點可能是使用JPanel

結構簡單

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        JButton left;
        JButton right;
        JPanel paintPane;

        public TestPane() {
            JButton left = new JButton("left");
            left.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                }
            });
            JButton right = new JButton("right");
            right.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                }
            });

            paintPane = new PaintPane();

            setLayout(new BorderLayout());
            add(left, BorderLayout.WEST);
            add(right, BorderLayout.EAST);
            add(paintPane);
        }

    }

    public class PaintPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        public void paintComponent(Graphics g) {
            super.paintComponents(g);
            Graphics2D g1 = (Graphics2D) g;
            g1.drawOval(3, 5, 45, 46); // The ball
            g1.fillOval(20, 30, 40, 40);

        }
    }

}

您應該花時間查看在 Swing繪畫執行自定義繪畫以了解更多詳細信息。

您可能想花時間學習的其他一些概念:

  • 單一職責原則——一個班級應該做一件事並且做好
  • 觀察者模式- 這通常在 Swing 中表示為偵聽器 API
  • 模型-視圖-控制器- 這包括上述內容,並為程序的不同部分定義了不同的職責層,它也將幫助您理解 Swing 的基本結構

此外,我正在考慮使用一個使x=x+的函數; 當我向左或向右按​​下時, y=y+1

好的,這就是 MVC 的“模型”部分將發揮作用的地方。

因此,讓我們首先定義我們希望模型支持的基本屬性......

public interface ShapeModel {
    public Point getPoint();
    public void addChangeListener(ChangeListener listener);
    public void removeChangeListener(ChangeListener listener);
}

這里支持一個Point作為位置,一個ChangeListener作為觀察者模式,它會通知感興趣的各方模型的狀態已經改變。

為什么要從interface開始? 作為一般概念,您應該始終更喜歡對接口而不是實現進行編碼。 在這種情況下,尚未定義的interface一個方面是, Point如何更新? 對於大多數想要使用模型的各方來說,這沒什么興趣,他們只是想知道它何時發生變化,模型的變異可以通過實現或從 this interface擴展的“可變” interface直接表達

接下來,我們定義一個默認實現...

public class DefaultShapeModel implements ShapeModel {

    private Point point = new Point(40, 40);

    private List<ChangeListener> listeners = new ArrayList<>(25);

    @Override
    public Point getPoint() {
        return point;
    }

    public void setPoint(Point point) {
        this.point = point;
        fireStateChanged();
    }

    protected void fireStateChanged() {
        ChangeEvent evt = new ChangeEvent(this);
        for (ChangeListener listener : listeners) {
            listener.stateChanged(evt);
        }
    }

    @Override
    public void addChangeListener(ChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(listener);
    }

}

這確實定義了如何更新油漆。

最后,我們更新了TestPanePaintPane以支持模型...

public class TestPane extends JPanel {

    JButton left;
    JButton right;
    JPanel paintPane;

    private DefaultShapeModel model;

    public TestPane() {
        model = new DefaultShapeModel();

        JButton left = new JButton("left");
        left.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                Point p = model.getPoint();
                p.x--;
                if (p.x > 0) {
                    p.x = 0;
                }
                model.setPoint(p);
            }
        });
        JButton right = new JButton("right");
        right.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Point p = model.getPoint();
                p.x++;
                if (p.x + 40 > paintPane.getWidth()) {
                    p.x = paintPane.getWidth() - 40;
                }
                model.setPoint(p);
            }
        });

        paintPane = new PaintPane(model);

        setLayout(new BorderLayout());
        add(left, BorderLayout.WEST);
        add(right, BorderLayout.EAST);
        add(paintPane);
    }

}

public class PaintPane extends JPanel {

    private ShapeModel model;

    public PaintPane(ShapeModel model) {
        this.model = model;
        this.model.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                repaint();
            }
        });
    }

    public ShapeModel getModel() {
        return model;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    public void paintComponent(Graphics g) {
        super.paintComponents(g);
        Graphics2D g1 = (Graphics2D) g;
        Point p = getModel().getPoint();
        g1.fillOval(p.x, p.y, 40, 40);
        g1.setColor(Color.WHITE);
        g1.drawOval(p.x, p.y, 40, 40);

    }
}

為什么不出現在面板上?

要顯示您創建的圖形,請使用以下步驟,

刪除paintComponent方法並將其替換為以下代碼..

public JComponent createOvel() {
    return new JComponent() {
        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g1 = (Graphics2D) g;
            g.drawOval(3, 5, 45, 46); // The ball
            g.fillOval(20, 30, 40, 40);
        }
    };
}

然后在Main()構造函數中調用它,

p.add("Center", createOvel());

這將顯示您創建的圖形。

暫無
暫無

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

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