尝试从GUI绘制烟花时出现问题

时间:2018-11-17 06:19:59

标签: java swing paintcomponent

我有两个类,一个叫做“用户界面”,另一个是“画布”,我需要用户能够输入速度,角度和时间的值才能将烟花渲染到画布上。但是,当我使用按钮触发捕获JTextFields值的内容时,Canvas不会repaint()。无论我输入什么值,都不会发生。我在另一个类中定义了x和y,但getter和setter不会产生任何值。

为什么我打电话给class DepositsSpider(CrawlSpider): name = 'deposits' allowed_domains = ['doi.org'] start_urls = ['https://minerals.usgs.gov/science/mineral-deposit-database/#products', ] rules = ( Rule(LinkExtractor(restrict_xpaths='//*[@id="products"][1]/p/a'), callback='parse_x'), ) def parse_x(self, response): i = ItemLoader(item=DepositsusaItem(), response=response) i.add_xpath('name', '//*[@class="container"][1]/header/h1/text()') i.add_value('url', response.url) i.add_value('project', self.settings.get('BOT_NAME')) i.add_value('spider', self.name) i.add_value('server', socket.gethostname()) i.add_value('date', datetime.datetime.now()) return i.load_item() 时不能在Canvase上绘制形状?

repaint()

1 个答案:

答案 0 :(得分:0)

对象之间的共享状态有时可能很复杂。在最基本的级别上,您要做的就是将它们所依赖的对象的相同实例传递给它。

在这里,您将要设置一个可以在两个类之间共享的“模型” ...

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

}

现在,因为在您的示例中,UserInterfaceCanvas类都没有真正直接相互交谈,所以该模型设置了一个“观察者模式”,该模式用于通知相关方模型的状态已更改。

您还将注意到,findx/y方法也已移至此处,这样,那些需要它们的团体就可以方便地访问它们。

接下来,我们更改Canvas(由于SDK中有一个FireworksPane类,我将其重命名为Canvas)以使用此模型...

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

如果您希望这两个类都能正常工作,则这两个类都需要将模型的SAME实例传递给他们。

FireworkModel model = new FireworkModel();
Userinterface userinterface = new Userinterface(model);
FireworksPane fireworksPane = new FireworksPane(model);
// Setup the remaining UI