Проблема при попытке нарисовать фейерверк из графического интерфейса - PullRequest
0 голосов
/ 17 ноября 2018

У меня есть два класса, один из которых называется Userinterface, а другой - Canvas. Мне нужно, чтобы пользователь мог вводить значения скорости, угла и времени для отображения фейерверков на Canvas.Однако, когда я использую кнопку, чтобы запустить то, что захватывает значения JTextFields, Canvas не перерисовывается ().Ничего не произойдет, независимо от того, какое значение я введу, я определил x и y в другом классе, но методы получения и установки не будут давать никакого значения.

Почему моя фигура не нарисована на холсте, когда я звоню repaint()?

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

1 Ответ

0 голосов
/ 17 ноября 2018

Совместное использование состояния между объектами может быть иногда сложным. На самом базовом уровне вам нужно передать тот же экземпляр объекта, на который они полагаются.

Здесь вы захотите настроить «модель», которую можно разделить между двумя классами ...

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 фактически не общаются напрямую друг с другом, модель устанавливает «шаблон наблюдателя», который используется для уведомления заинтересованных сторон о состоянии модели. изменилось.

Вы также заметите, что методы findx/y также были перемещены сюда, так что они легко доступны для тех сторон, которые в них нуждаются.

Далее мы меняем Canvas (который я переименовал на FireworksPane, поскольку в SDK есть класс 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);
        }
    }
}

Оба класса будут нуждаться в том же экземпляре модели, передаваемой им, если вы ожидаете, что это сработает ...

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