尝试从 GUI 绘制烟花时出现问题
Issue when attempting to draw fireworks from GUI
我有两个 classes,一个叫用户界面,另一个叫 Canvas 我需要用户能够输入速度、角度和时间的值才能渲染烟花上了Canvas。但是,当我使用按钮触发获取 JTextFields 值的内容时,Canvas 不会重新绘制 ()。无论我输入什么值都不会发生 我在另一个 class 中定义了 x 和 y,但是 getter 和 setter 不会产生任何值。
为什么我调用repaint()
时我的形状没有画在Canvase上?
public class Userinterface extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private static String str= "0";
private static String str2= "0";
private static String str3= "0";
private JTextField angle= new JTextField(5);
private JLabel alabel= new JLabel("Angle");
private JTextField velocity= new JTextField(5);
private JLabel vlabel= new JLabel("Velocity");
private JButton Actionbutton= new JButton("launch");
private JTextField time= new JTextField(5);
private JLabel tlabel= new JLabel ("Time of fuse (s)");
static int a;
static int b;
static int c;
static int x;
static int y;
Userinterface(){
setLayout(new FlowLayout(FlowLayout.CENTER));
add(time);
add(tlabel);
add (angle);
add(alabel);
add (velocity);
add(vlabel);
add(Actionbutton);
Actionbutton.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==Actionbutton) {
str=angle.getText();
str2=velocity.getText();
str3=time.getText();
a=Integer.parseInt(str);
b=Integer.parseInt(str2);
c=Integer.parseInt(str3);
repaint(); // ISSUE: Canvas does not repaint here
}
}
public static int findx() {
x=Fire_WorkMath.calculatex(b, c, a);
return x;
}
public static int findy() {
y=Fire_WorkMath.calculatey(b, c, a);
return y;
}
public class Canvas extends JPanel {
Userinterface one= new Userinterface();
int ang;
int time;
int y;
int x;
private static final long serialVersionUID = 1L;
public Canvas() {
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
x=Userinterface.findx();
y=Userinterface.findy();
g.drawLine(0, 0, x, y);
}
}
对象之间的共享状态有时会很复杂。在最基本的层面上,您要做的是将它们所依赖的对象的同一个实例传递给它们。
在此,您需要设置一个 "model" 可以在两个 classes 之间共享...
public class FireworkModel {
private int angle;
private int velocity;
private int time;
private List<ChangeListener> changeListeners;
public FireworkModel() {
changeListeners = new ArrayList<>();
}
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
public void setAngle(int angle) {
this.angle = angle;
fireStateChanged();
}
public void setVelocity(int velocity) {
this.velocity = velocity;
fireStateChanged();
}
public void setTime(int time) {
this.time = time;
fireStateChanged();
}
public int getAngle() {
return angle;
}
public int getVelocity() {
return velocity;
}
public int getTime() {
return time;
}
public int findx() {
return Fire_WorkMath.calculatex(getVelocity(), getTime(), getAngle());
}
public int findy() {
return Fire_WorkMath.calculatey(getVelocity(), getTime(), getAngle());
}
}
现在,因为在您的示例中,UserInterface
或 Canvas
class 实际上都没有直接相互交谈,模型设置了一个 "observer pattern",它用于通知相关方模型的状态已经改变。
您还会注意到 findx/y
方法也已移至此处,这样需要它们的各方就可以轻松访问它们。
接下来,我们更改 Canvas
(我已将其重命名为 FireworksPane
,因为 SDK 中有 Canvas
class)以利用此型号...
public class FireworksPane extends JPanel {
private FireworkModel model;
private static final long serialVersionUID = 1L;
public FireworksPane(FireworkModel model) {
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
repaint();
}
});
}
public FireworkModel getModel() {
return model;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = getModel().findx();
int y = getModel().findy();
g.drawLine(0, 0, x, y);
}
}
最后,我们更新 UserInterface
以也使用模型...
public class Userinterface extends JPanel implements ActionListener {
private final long serialVersionUID = 1L;
private JTextField angle = new JTextField(5);
private JLabel alabel = new JLabel("Angle");
private JTextField velocity = new JTextField(5);
private JLabel vlabel = new JLabel("Velocity");
private JButton Actionbutton = new JButton("launch");
private JTextField time = new JTextField(5);
private JLabel tlabel = new JLabel("Time of fuse (s)");
private FireworkModel model;
Userinterface(FireworkModel model) {
setLayout(new FlowLayout(FlowLayout.CENTER));
add(time);
add(tlabel);
add(angle);
add(alabel);
add(velocity);
add(vlabel);
add(Actionbutton);
Actionbutton.addActionListener(this);
this.model = model;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == Actionbutton) {
String str = angle.getText();
String str2 = velocity.getText();
String str3 = time.getText();
int angle = Integer.parseInt(str);
int velocity = Integer.parseInt(str2);
int time = Integer.parseInt(str3);
model.setAngle(angle);
model.setVelocity(velocity);
model.setTime(time);
}
}
}
两个 classes 都需要传递给它们的模型的相同实例,如果您希望它起作用...
FireworkModel model = new FireworkModel();
Userinterface userinterface = new Userinterface(model);
FireworksPane fireworksPane = new FireworksPane(model);
// Setup the remaining UI
我有两个 classes,一个叫用户界面,另一个叫 Canvas 我需要用户能够输入速度、角度和时间的值才能渲染烟花上了Canvas。但是,当我使用按钮触发获取 JTextFields 值的内容时,Canvas 不会重新绘制 ()。无论我输入什么值都不会发生 我在另一个 class 中定义了 x 和 y,但是 getter 和 setter 不会产生任何值。
为什么我调用repaint()
时我的形状没有画在Canvase上?
public class Userinterface extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private static String str= "0";
private static String str2= "0";
private static String str3= "0";
private JTextField angle= new JTextField(5);
private JLabel alabel= new JLabel("Angle");
private JTextField velocity= new JTextField(5);
private JLabel vlabel= new JLabel("Velocity");
private JButton Actionbutton= new JButton("launch");
private JTextField time= new JTextField(5);
private JLabel tlabel= new JLabel ("Time of fuse (s)");
static int a;
static int b;
static int c;
static int x;
static int y;
Userinterface(){
setLayout(new FlowLayout(FlowLayout.CENTER));
add(time);
add(tlabel);
add (angle);
add(alabel);
add (velocity);
add(vlabel);
add(Actionbutton);
Actionbutton.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==Actionbutton) {
str=angle.getText();
str2=velocity.getText();
str3=time.getText();
a=Integer.parseInt(str);
b=Integer.parseInt(str2);
c=Integer.parseInt(str3);
repaint(); // ISSUE: Canvas does not repaint here
}
}
public static int findx() {
x=Fire_WorkMath.calculatex(b, c, a);
return x;
}
public static int findy() {
y=Fire_WorkMath.calculatey(b, c, a);
return y;
}
public class Canvas extends JPanel {
Userinterface one= new Userinterface();
int ang;
int time;
int y;
int x;
private static final long serialVersionUID = 1L;
public Canvas() {
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
x=Userinterface.findx();
y=Userinterface.findy();
g.drawLine(0, 0, x, y);
}
}
对象之间的共享状态有时会很复杂。在最基本的层面上,您要做的是将它们所依赖的对象的同一个实例传递给它们。
在此,您需要设置一个 "model" 可以在两个 classes 之间共享...
public class FireworkModel {
private int angle;
private int velocity;
private int time;
private List<ChangeListener> changeListeners;
public FireworkModel() {
changeListeners = new ArrayList<>();
}
public void addChangeListener(ChangeListener listener) {
changeListeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
changeListeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : changeListeners) {
listener.stateChanged(evt);
}
}
public void setAngle(int angle) {
this.angle = angle;
fireStateChanged();
}
public void setVelocity(int velocity) {
this.velocity = velocity;
fireStateChanged();
}
public void setTime(int time) {
this.time = time;
fireStateChanged();
}
public int getAngle() {
return angle;
}
public int getVelocity() {
return velocity;
}
public int getTime() {
return time;
}
public int findx() {
return Fire_WorkMath.calculatex(getVelocity(), getTime(), getAngle());
}
public int findy() {
return Fire_WorkMath.calculatey(getVelocity(), getTime(), getAngle());
}
}
现在,因为在您的示例中,UserInterface
或 Canvas
class 实际上都没有直接相互交谈,模型设置了一个 "observer pattern",它用于通知相关方模型的状态已经改变。
您还会注意到 findx/y
方法也已移至此处,这样需要它们的各方就可以轻松访问它们。
接下来,我们更改 Canvas
(我已将其重命名为 FireworksPane
,因为 SDK 中有 Canvas
class)以利用此型号...
public class FireworksPane extends JPanel {
private FireworkModel model;
private static final long serialVersionUID = 1L;
public FireworksPane(FireworkModel model) {
this.model = model;
model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
repaint();
}
});
}
public FireworkModel getModel() {
return model;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = getModel().findx();
int y = getModel().findy();
g.drawLine(0, 0, x, y);
}
}
最后,我们更新 UserInterface
以也使用模型...
public class Userinterface extends JPanel implements ActionListener {
private final long serialVersionUID = 1L;
private JTextField angle = new JTextField(5);
private JLabel alabel = new JLabel("Angle");
private JTextField velocity = new JTextField(5);
private JLabel vlabel = new JLabel("Velocity");
private JButton Actionbutton = new JButton("launch");
private JTextField time = new JTextField(5);
private JLabel tlabel = new JLabel("Time of fuse (s)");
private FireworkModel model;
Userinterface(FireworkModel model) {
setLayout(new FlowLayout(FlowLayout.CENTER));
add(time);
add(tlabel);
add(angle);
add(alabel);
add(velocity);
add(vlabel);
add(Actionbutton);
Actionbutton.addActionListener(this);
this.model = model;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == Actionbutton) {
String str = angle.getText();
String str2 = velocity.getText();
String str3 = time.getText();
int angle = Integer.parseInt(str);
int velocity = Integer.parseInt(str2);
int time = Integer.parseInt(str3);
model.setAngle(angle);
model.setVelocity(velocity);
model.setTime(time);
}
}
}
两个 classes 都需要传递给它们的模型的相同实例,如果您希望它起作用...
FireworkModel model = new FireworkModel();
Userinterface userinterface = new Userinterface(model);
FireworksPane fireworksPane = new FireworksPane(model);
// Setup the remaining UI