如何使用frame.add方法创建多个可见对象

时间:2014-05-23 13:30:24

标签: java swing jframe jpanel

当我尝试添加电梯类的第二个实例时,第一个实例消失。如何重新排列此代码才能看到这两个对象?

这是我的主要课程:

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();
    }
}

4 个答案:

答案 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();
    }
});

您可以看到一系列类似的示例herehere以及herehere以及herehere


旁注:

  • 遵循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)。

干杯,