当我尝试添加电梯类的第二个实例时,第一个实例消失。如何重新排列此代码才能看到这两个对象?
这是我的主要课程:
public class MainClass extends JPanel implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 700);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Component component1 = frame.add(new elevator(0,0));
Component component2 = frame.add(new elevator(505,50));
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
这是电梯类:
public class elevator extends JPanel implements ActionListener {
Timer timer;
private double angle = 0;
private double scale = 1;
private double delta = 0.01;
private int x=0;
private int y=0;
Rectangle.Float r = new Rectangle.Float(0, 0, 3, 3);
public elevator(int input_x, int input_y) {
x=input_x;
y=input_y;
timer = new Timer(10, this);
timer.start();
}
public elevator() {
timer = new Timer(10, this);
timer.start();
}
public void paint(Graphics g) {
this.setSize(100,200);
this.setLocation(x, y);
int h = getHeight();
int w = getWidth();
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.translate(w / 5, scale*140);
g2d.scale(20, 20);
g2d.fill(r);
}
public void actionPerformed(ActionEvent e) {
if (scale < 0.01 || scale > 0.99) {
delta = -delta;
}
scale += delta;
angle += 0.01;
repaint();
}
}
答案 0 :(得分:2)
不要让elevator
扩展JPanel
。只需将它作为保持状态,操纵状态和绘制状态的类。然后只需要一个主绘图面板,使用elevators
添加List<elevator>
。
Elevator.java(注意Java命名约定)
public class Elevator {
public void draw(Graphics g) {}
public void move() {}
}
ElevatorPanel.java
public class ElevatorPanel extends JPanel {
List<Elevator> elevators;
@Override
protected void paintComponent(Grapchics g) {
super.paintComponent(g);
for (Elevator elevator: elevators) {
elevator.draw(g);
}
}
}
只需拥有ElevatorPanel
课程中的计时器(只有一个),然后循环播放电梯列表并调用move
方法。
Timer timer = new Timer(40, new ActionListener(){
public void actionPerformed(ActionEvent e) {
for (Elevator elevator : elevators) {
elevator.move();
}
repaint();
}
});
您可以看到一系列类似的示例here和here以及here和here以及here和here。
旁注:
遵循Java命名约定。类名以大写字母开头。
您应该覆盖paintComponent
而不是paint
应在Event Dispatch Thread上运行Swing应用程序。请参阅Initial Threads
答案 1 :(得分:1)
您需要某种容器来放置两个组件。您可以使用JPanel
,在这种情况下您的代码将如下所示:
JPanel panel = new JPanel();
panel.add(new elevator(0,0));
panel.add(new elevator(505,50));
frame.add(panel);
对于他们两个占据相同区域(以及JPanel
填充所有空间),您可以将GridLayout
传递给JPanel
构造函数:
JPanel panel = new JPanel(new GridLayout(2, 1)); // 2 rows, 1 column
或
JPanel panel = new JPanel(new GridLayout(1, 2)); // 1 row, 2 columns
答案 2 :(得分:0)
默认情况下,一个框架只能处理一个组件。创建一个JPanel并将其添加到JFrame,然后为JPanel指定一个布局并开始向其添加组件,而不是框架
答案 3 :(得分:0)
已更新
严格来说,我认为你需要做的就是让代码正常工作。添加到框架时指定BorderLayout位置:
frame.add(new elevator(0, 0), BorderLayout.WEST);
frame.add(new elevator(505, 50), BorderLayout.EAST);
这里的其他答案当然是为您的项目代码提出更好的长期方法。
(感谢sbat指出默认布局实际上是BorderLayout而不是FlowLayout)。
干杯,