Well, I'm developing a project that simulates the controlled environment of train tracks, where I have 3 trains running clockwise, where the three pass through the same place in certain sections. I'm having trouble implementing the train speed dynamically using the JSlider
component. I was able to create the 3 components, but I still could not associate them with my trains.
Follow the code:
public class Trens {
private static final double QUADROS_POR_SEGUNDO = 20.0;
public static void preparar() {
JFrame t = new JFrame();
t.setLayout(null);
t.setSize(1200, 900);
t.setTitle("Semáforo");
t.setLocationRelativeTo(null);
t.setResizable(false);
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Trilho t1 = new Trilho(300, 100, 300, 170);
Trilho t2 = new Trilho(600, 100, 300, 170);
Trilho t3 = new Trilho(450, 270, 300, 170);
Jslider slider = new Jslider(30, 150, 300, 170);
Jslider slider2 = new Jslider(900, 150, 300, 170);
Jslider slider3 = new Jslider(150, 330, 300, 170);
Trem a = new Trem(t1, Color.BLUE, 350, 100, 100.0);
Trem b = new Trem(t2, Color.GREEN, 650, 100, 100.0);
Trem c = new Trem(t3, Color.RED, 450, 335, 100.0);
t.add(a);
t.add(b);
t.add(c);
t.add(t1);
t.add(t2);
t.add(t3);
t.add(slider);
t.add(slider2);
t.add(slider3);
Runnable moverTudo = () -> {
EventQueue.invokeLater(() -> {
a.mover(1 / QUADROS_POR_SEGUNDO);
b.mover(1 / QUADROS_POR_SEGUNDO);
c.mover(1 / QUADROS_POR_SEGUNDO);
});
};
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(moverTudo, 0, (int) (1000 / QUADROS_POR_SEGUNDO), TimeUnit.MILLISECONDS);
t.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(Trens::preparar);
}
public static class Trilho extends JComponent {
public Trilho(int x, int y, int width, int height) {
this.setBounds(x, y, width, height);
this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
}
}
public static class Trem extends JComponent {
private Color cor;
private Trilho trilho;
private int x;
private int y;
private double velocidade; // pixels por segundo
private double restante; // Frações de pixels que faltou andar.
public Trem(Trilho trilho, Color cor, int x, int y, double velocidade) {
this.trilho = trilho;
this.cor = cor;
this.x = x;
this.y = y;
this.velocidade = velocidade;
this.setBounds(x - 5, y - 5, 10, 10);
}
@Override
public void paintComponent(Graphics g) {
g.setColor(cor);
g.fillRect(0, 0, getWidth(), getHeight());
}
public void mover(double deltaT) {
if (velocidade == 0) return;
boolean sentidoHorario = velocidade > 0;
double distancia = Math.abs(restante + velocidade * deltaT);
int tLeft = trilho.getX();
int tTop = trilho.getY();
int tRight = tLeft + trilho.getWidth();
int tBottom = tTop + trilho.getHeight();
for (int i = 0; i < (int) distancia; i++) {
// Se deve ir à esquerda:
if (x > tLeft && y == (sentidoHorario ? tBottom : tTop)) {
x--;
// Se deve ir à direita:
} else if (x < tRight && y == (sentidoHorario ? tTop : tBottom)) {
x++;
// Se deve ir para cima:
} else if (y > tTop && x == (sentidoHorario ? tLeft : tRight)) {
y--;
// Se deve ir para baixo:
} else if (y < tBottom && x == (sentidoHorario ? tRight : tLeft)) {
y++;
// Se não for nenhum dos anteriores, o trem está descarrilhado. Coloca de novo no trilho.
} else {
x = tLeft;
y = tTop;
}
}
restante = distancia % 1;
setLocation(x - 5, y - 5);
}
}
public static class Jslider extends JPanel{
private Jslider(int x, int y, int width, int height){
this.setBounds(x, y, width, height);
JSlider control = new JSlider(0,100,25);
control.setMajorTickSpacing(50);
control.setMinorTickSpacing(10);
control.setPaintTicks(true);
control.setFont(new Font("Serfi", Font.ITALIC, 12));
control.setPaintLabels(true);
control.setSnapToTicks(true);
add(control);
}
}
public class EventoSlider implements ChangeListener{
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
int fps = (int) source.getValue();
System.out.println(fps);
}
}
}