簡體   English   中英

框沒有出現或在JPanel上移動。

[英]box isn't appearing or moving on JPanel.. Java

我正在嘗試在Java面板1上創建此框,但屏幕上沒有任何顯示:/問題是什么? 抱歉,我是Java動畫的新手,它太難了! 另外,我希望該框僅出現在第一個面板上而不在第二個面板上移動。這是我的代碼。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class frog extends JPanel implements ActionListener{
    JFrame frame= new JFrame();
    JPanel panel=new JPanel();
    JButton button = new JButton("Hungry");
    JPanel panel2=new JPanel();
    JTextField t;
    Timer tm= new Timer(5, this);
    int x=0, velX=2;
    public void paintComponent(Graphics g){
        super.paintComponents(g);
        g.setColor(Color.RED);
        g.drawRect(100,10,30,40);
        g.fillRect(x,10,20,10);
        tm.start();
    }
    JLabel l= new JLabel("Good");
    frog(){
        panel.setBackground(Color.CYAN);
        panel2.setBackground(Color.GREEN);
        t= new JTextField("Frog is hungry",10);
        panel2.add(t);
        panel2.add(button);
        frame.add(panel,BorderLayout.CENTER);
        frame.add(panel2,BorderLayout.PAGE_END);
        button.addActionListener(this);
        frame.setSize(500,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        frog f= new frog();

    }


    @Override
    public void actionPerformed(ActionEvent e) {
        t.setText("Now he is full");
        x=x+velX;
        repaint();
    }

}

讓我們停一分鍾,看看您做了什么。

您已經創建了一個從JPanel擴展的類

public class Frog extends JPanel implements ActionListener {

好的。 您已經覆蓋了paintComponent來進行一些自定義繪制

@Override
public void paintComponent(Graphics g) {
    super.paintComponents(g);
    g.setColor(Color.RED);
    g.drawRect(100, 10, 30, 40);
    g.fillRect(x, 10, 20, 10);
    tm.start();
}

好的,這里有一些問題,但讓我們繼續。 在面板的構造函數中,您已經創建了兩個新面板,並將這兩個面板添加到JFrame並使其可見

Frog() {
    panel.setBackground(Color.CYAN);
    panel2.setBackground(Color.GREEN);
    t = new JTextField("Frog is hungry", 10);
    panel2.add(t);
    panel2.add(button);
    frame.add(panel, BorderLayout.CENTER);
    frame.add(panel2, BorderLayout.PAGE_END);
    button.addActionListener(this);
    frame.setSize(500, 400);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

但是,等等,永遠不會添加到任何內容的Frog面板如何處理,那么該如何顯示呢?

而且,構造函數有一些非常討厭的副作用,將非關聯的面板放在一邊,在調用它時會創建一個框架,這確實是一個壞主意。

基本OO

使用OO,您希望將任何對象的功能限制在一個責任之內, Frog面板不負責創建其他面板(它們不向Frog面板添加任何功能)或制作框架,它的職責是為青蛙,沒別的。

public class FrogPane extends JPanel {

    private Timer timer;
    int x = 0, velX = 2;

    public FrogPane() {
        timer = new Timer(40, new ActionListener() {
                                        @Override
                                        public void actionPerformed(ActionEvent e) {
                                            x = x + velX;
                                            repaint();
                                        }
                                    });
        setBackground(Color.CYAN);
    }

    public void start() {
        timer.start();
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.RED);
        g2d.drawRect(100, 10, 30, 40);
        g2d.fillRect(x, 10, 20, 10);
        g2d.dispose();
    }

}

好的, FrogPane非常基礎,它繪制了青蛙的表示並通過使用Timer更新位置。 請注意, Timer在未啟動paintComponentpaintComponent可以要求任何數量的原因,其中有許多你不控制,所以不要做內就任何可能更改組件或你的狀態依靠執行一些次要任務

我們需要做的下一件事是顯示它並有一些啟動它的方法

public class Test {

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

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

                FrogPane frogPane = new FrogPane();

                JTextField t = new JTextField("Frog is hungry", 10);
                JButton button = new JButton("Hungry");

                JPanel actionPane = new JPanel();
                actionPane.setBackground(Color.GREEN);
                actionPane.add(t);
                actionPane.add(button);
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        t.setText("Run frog run");
                        frogPane.start();
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(frogPane);
                frame.add(actionPane, BorderLayout.PAGE_END);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

因此,您的下一個問題將是如何管理不同類之間的狀態,這向我建議您需要離開並且對Model-View-Controller進行更多研究,並更好地理解職責分離的概念。 基本答案是,您使用模型。

您正在為frog類定義動畫,但沒有在JFrame添加frog面板。 您的第一個面板是純Jpanel ,它沒有關聯的paintComponent覆蓋。

你應該:

  1. 刪除線

     JPanel panel=new JPanel(); 
  2. 代替

     panel.setBackground(Color.CYAN); 

    采用

     this.setBackground(Color.CYAN); 
  3. 代替

     frame.add(panel,BorderLayout.CENTER); 

    采用

     frame.add(this,BorderLayout.CENTER); 

現在,第一個面板將是當前創建的frog ,您應該能夠看到動畫。

筆記:

  • 請注意Java語言約定。 班級名稱應以大寫字母開頭( Frog而不是frog )。
  • 請注意,計時器和按鈕都在使用您的actionPerformed 您確定這就是您想要的嗎? 另外,我認為每次重新粉刷面板時都不太可能要啟動計時器。

暫無
暫無

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

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