这两天在做一个模拟电梯的程序
通常的办法在Elevator class上直接Paint出电梯来,通过设定Upper left corner 的位置来实现电梯的移动.
但是因为想到如果要给电梯加两个门~~也就是电梯上下人的时候,门开启后关闭。
设想1:改写结构,分离出一个ElevatorRec class,将这个JPanel add在Elevator上,然后再add两个JPanel做门在ElevatorRec上,在尝试了一段时间后.....失败的原因在于Java没有一个manually 设定 JPanel位置的机制,只有一些Layout manager不足以模拟电梯的移动。
设想2: 不改写结构,依然在原基础上,多画两个门,但问题出现了:画静态的门容易,画动态的门就难了,什么机制来控制门开和关呢?最初导致着手设想1的原因就是为了让ElevatorRec本身Implements ActionListener这样就能很容易的控制门的开关。如今看来只好使用Flag来实现,也就是在Elevator的PaintComponent()里面写入一个If 判断句,是否开启、关闭门。
但是问题依然存在,一个if判断句无法Control门的开关速度!也就是说,如果门开的慢了,电梯都开始移动了,门还没开启!或者门没有完全关闭,电梯就移动了!
如何解决,仍然在思考中....
好吧,解决的方法异常简单....代码如下:
通常的办法在Elevator class上直接Paint出电梯来,通过设定Upper left corner 的位置来实现电梯的移动.
但是因为想到如果要给电梯加两个门~~也就是电梯上下人的时候,门开启后关闭。
设想1:改写结构,分离出一个ElevatorRec class,将这个JPanel add在Elevator上,然后再add两个JPanel做门在ElevatorRec上,在尝试了一段时间后.....失败的原因在于Java没有一个manually 设定 JPanel位置的机制,只有一些Layout manager不足以模拟电梯的移动。
设想2: 不改写结构,依然在原基础上,多画两个门,但问题出现了:画静态的门容易,画动态的门就难了,什么机制来控制门开和关呢?最初导致着手设想1的原因就是为了让ElevatorRec本身Implements ActionListener这样就能很容易的控制门的开关。如今看来只好使用Flag来实现,也就是在Elevator的PaintComponent()里面写入一个If 判断句,是否开启、关闭门。
但是问题依然存在,一个if判断句无法Control门的开关速度!也就是说,如果门开的慢了,电梯都开始移动了,门还没开启!或者门没有完全关闭,电梯就移动了!
如何解决,仍然在思考中....
好吧,解决的方法异常简单....代码如下:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Lab1;
/**
*
* @author tony
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
//The main class
//The ButtonPanel class receives and handles button pressing events
public class Elevator_Simulation extends JFrame {
public JLabel state = new JLabel("");
; // display the state of the elevator
private JLabel id; //your name and group
public ButtonPanel control = new ButtonPanel(); //the button control panel
private Elevator elevator = new Elevator(this); // the elevator area
public JSlider slider;
public int cSpeed = 10;
public Elevator_Simulation() {
// Create GUI
id = new JLabel("Name: Zhang Shuhao Group:SE1 ");
slider = new JSlider(1, 2, 20, 10);
slider.setMajorTickSpacing(2);
slider.setMinorTickSpacing(1);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent evt) {
cSpeed = slider.getValue();
}
});
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(id, BorderLayout.NORTH);
container.add(control, BorderLayout.WEST);
container.add(elevator, BorderLayout.CENTER);
container.add(state, BorderLayout.SOUTH);
container.add(slider, BorderLayout.EAST);
}
// Main method
public static void main(String[] args) {
// Create a frame and display it
Elevator_Simulation frame = new Elevator_Simulation();
frame.setTitle("Elevator_Simulation");
frame.setSize(600, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} //the end of Elevator_Simulation class
class ButtonPanel extends JPanel {
public JButton b[] = new JButton[8]; // 8 Buttons
public boolean bp[] = new boolean[8]; // the state of each button, pressed or not
public ButtonPanel() { //create GUI
this.setLayout(new GridLayout(8, 1));
ButtonListener btListener = new ButtonListener();
for (int i = 8; i >= 1; i--) {
b[i - 1] = new JButton("F" + i);
bp[i - 1] = false;
this.add(b[i - 1]);
b[i - 1].setBackground(Color.cyan);
b[i - 1].addActionListener(btListener);
}
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) { //handle the button pressing events
int index = Integer.parseInt(e.getActionCommand().substring(1)) - 1;
bp[index] = true;
b[index].setBackground(Color.red);
}
}
} //the end of ButtonPanel class
// The elevator class draws the elevator area and simulates elevator movement
class Elevator extends JPanel implements ActionListener {
//Declaration of variables
private Elevator_Simulation app; //the Elevator Simulation frame
private boolean up; // the elevator is moving up or down
private int width; // Elevator width
private int height; // Elevator height
private int xco; // The x coordinate of the elevator's upper left corner
private int yco; // The y coordinate of the elevator's upper left corner
private int dy0; // Moving interval
private int topy; //the y coordinate of the top level
private int bottomy; // the y coordinate of the bottom level
private Timer timer; //the timer to drive the elevator movement
private int speed;
private int count;
private boolean stop;
private int level;
public Elevator(Elevator_Simulation app) {
//necessary initialization
this.app = app;
app.state.setText("The elevator is moving up.");
width = app.control.getWidth();
height = app.control.getHeight() / 8;
xco = 160;
yco = 460;
topy = 0;
bottomy = app.control.getHeight();
up = true;
speed = 10;
count = 0;
stop = false;
timer = new Timer(200, this);
timer.start();
}
//Handle the timer events
public void actionPerformed(ActionEvent e) {
speed = app.cSpeed;
if (stop == false) {
if (up == true) { //when th elevator is moving up
app.state.setText("The elevator is moving up.");
yco -= speed;
for (int i = 0; i < 8; i++) {
if ((i * height + topy - yco) < speed && (i * height + topy - yco) > -speed) {
if (app.control.bp[7 - i] == true) {
yco = i * height + topy;
count = 0;
stop = true;
level = 7 - i + 1;
}
}
}
if (yco <= topy) {
yco = topy;
up = false;
app.state.setText("The elevator is moving down.");
}
repaint();
} else { //when th elevator is moving down
app.state.setText("The elevator is moving down.");
yco += speed;
for (int i = 0; i < 8; i++) {
if ((i * height + topy - yco) < speed && (i * height + topy - yco) > -speed) {
if (app.control.bp[7 - i] == true) {
yco = i * height + topy;
count = 0;
stop = true;
level = 7 - i + 1;
}
}
}
if (yco + height >= bottomy) {
yco = bottomy - height;
up = true;
app.state.setText("The elevator is moving up.");
}
repaint();
}
} else { //when th elevator is stopped
if (count == 0) {
repaint();
app.state.setText("The elevator is picking up passengers at floor " + level);
}
count++;
int countN = 6;
if (speed > 10) {
countN -= (speed - 10) / 2;
}
if (speed < 10) {
countN += (10 - speed) / 3;
}
if (count > countN) {
app.control.b[level - 1].setBackground(Color.cyan);
app.control.bp[level - 1] = false;
stop = false;
if (up == true) {
app.state.setText("The elevator is moving up.");
}
if (up == false) {
app.state.setText("The elevator is moving down.");
}
}
}
}
// Paint elevator area
public void paintComponent(Graphics g) {
xco = this.getWidth() / 2 - width / 2;
width = app.control.getWidth();
height = app.control.getHeight() / 8;
topy = 0;
bottomy = height * 8;
//obtain geometric values of components for drawing the elevator area
super.paintComponent(g);
//clear the painting canvas
this.setBackground(Color.yellow);
for (int i = 0; i <= 8; i++) {
g.drawLine(0, height * i, this.getWidth(), height * i);
}
g.setColor(Color.black);
g.fillRect(xco, yco, width, height);
if (!stop) {
g.setColor(Color.lightGray);
g.fillRect(xco, yco, width / 2, height);
g.fillRect(xco + width / 2, yco, width / 2 + 1, height);
}
g.setColor(Color.black);
g.drawLine(xco + width / 2, yco, xco + width / 2, yco + height);
//draw horizontal lines and the elevator
}
} //the end of Elevator class