我正在尝试在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
不是在paintComponent
中启动的,由于多种原因可以调用paintComponent
,其中许多原因是您无法控制的,因此请勿在其中进行任何可能改变其状态的操作。该组件或您要执行某些次要任务所依赖的组件我们需要做的下一件事是显示它并有一些启动它的方法
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进行更多研究,并更好地理解职责分离的概念。基本的答案是,您使用模型。