SignalPanel.java 6,39 ko
Newer Older
Ynvers's avatar
Ynvers a validé
package TP1_NathanADOHO;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;

public class SignalPanel extends JPanel {
	private String signal = "";
	private String type = "NRZ";
	private static final int PADDING = 50;

	public SignalPanel() {
		setPreferredSize(new Dimension(400, 300));
		setBackground(Color.WHITE);
	}

	public void updateSignal(String signal, String type) {
		this.signal = signal;
		this.type = type;
		this.repaint();
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (signal.isEmpty() || type.isEmpty()) {
			return;
		}

		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		int width = getWidth();
		int height = getHeight();
		int graphWidth = width - 2 * PADDING;
		int graphHeight = height - 2 * PADDING;
		int stepX = graphWidth / signal.length();
		int yLow = height - PADDING - graphHeight / 4;
		int yHigh = PADDING + graphHeight / 4;

		drawGrid(g2d, width, height, stepX, yLow, yHigh);
		drawAxes(g2d, width, height, yLow, yHigh);

		g2d.setStroke(new BasicStroke(3));

		switch (type) {
			case "NRZ":
				tracerNRZ(g2d, stepX, yLow, yHigh);
				break;
			case "Manchester":
				tracerManchester(g2d, stepX, yLow, yHigh);
				break;
			case "Manchester Différentiel":
				tracerManchesterDifferentiel(g2d, stepX, yLow, yHigh);
				break;
			case "Miller":
				tracerMiller(g2d, stepX, yLow, yHigh);
				break;
		}
	}

	private void drawGrid(Graphics2D g2d, int width, int height, int stepX, int yLow, int yHigh) {
		g2d.setColor(new Color(230, 230, 230));
		g2d.setStroke(
				new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 5.0f }, 0.0f));

		// Lignes verticales (séparation des bits)
		for (int i = 0; i <= signal.length(); i++) {
			int x = PADDING + i * stepX;
			g2d.drawLine(x, PADDING, x, height - PADDING);
		}
		// Lignes horizontales (niveaux)
		g2d.drawLine(PADDING, yLow, width - PADDING, yLow);
		g2d.drawLine(PADDING, yHigh, width - PADDING, yHigh);
	}

	private void drawAxes(Graphics2D g2d, int width, int height, int yLow, int yHigh) {
		g2d.setColor(Color.BLACK);
		g2d.setStroke(new BasicStroke(2));
		g2d.setFont(new Font("Arial", Font.BOLD, 12));

		// Axe Y
		g2d.drawLine(PADDING, PADDING, PADDING, height - PADDING);
		g2d.drawString("+V", PADDING - 25, yHigh + 5);
		g2d.drawString("-V", PADDING - 25, yLow + 5);
		g2d.drawString("Voltage", PADDING - 40, PADDING - 10);

		// Axe X
		g2d.drawLine(PADDING, height - PADDING, width - PADDING, height - PADDING);
		g2d.drawString("Temps", width - PADDING, height - PADDING + 20);

		// Labels des bits
		for (int i = 0; i < signal.length(); i++) {
			int x = PADDING + i * (width - 2 * PADDING) / signal.length();
			g2d.drawString(String.valueOf(signal.charAt(i)), x + (width - 2 * PADDING) / signal.length() / 2,
					height - PADDING + 20);
		}
	}

	private void tracerNRZ(Graphics2D g2d, int stepX, int yLow, int yHigh) {
		g2d.setColor(Color.BLUE);
		int currentX = PADDING;
		int currentY = PADDING; // Initialisation arbitraire

		for (int i = 0; i < signal.length(); i++) {
			char bit = signal.charAt(i);
			int targetY = (bit == '0') ? yLow : yHigh;

			if (i == 0) {
				currentY = targetY; // Position initiale correcte
			}

			g2d.drawLine(currentX, currentY, currentX, targetY); // Transition verticale
			g2d.drawLine(currentX, targetY, currentX + stepX, targetY); // Palier horizontal

			currentX += stepX;
			currentY = targetY;
		}
	}

	private void tracerManchester(Graphics2D g2d, int stepX, int yLow, int yHigh) {
		g2d.setColor(Color.RED);
		int currentX = PADDING;
		int halfStep = stepX / 2;

		int prevY = -1;

		for (int i = 0; i < signal.length(); i++) {
			char bit = signal.charAt(i);
			int startY, midY;

			if (bit == '0') {
				startY = yLow;
				midY = yHigh;
			} else {
				startY = yHigh;
				midY = yLow;
			}

			if (i > 0 && prevY != -1) {
				g2d.drawLine(currentX, prevY, currentX, startY);
			}

			g2d.drawLine(currentX, startY, currentX + halfStep, startY);
			g2d.drawLine(currentX + halfStep, startY, currentX + halfStep, midY);
			g2d.drawLine(currentX + halfStep, midY, currentX + stepX, midY);

			prevY = midY;
			currentX += stepX;
		}
	}

	private void tracerManchesterDifferentiel(Graphics2D g2d, int stepX, int yLow, int yHigh) {
		g2d.setColor(Color.GREEN);
		int currentX = PADDING;
		int halfStep = stepX / 2;
		boolean inverse = false; // false = montant, true = descendant au milieu

		for (int i = 0; i < signal.length(); i++) {
			char bit = signal.charAt(i);

			if (bit == '1') {
				// Transition au début si 1
				inverse = !inverse;
			}
		}

		int currentLevel = yLow;

		for (int i = 0; i < signal.length(); i++) {
			char bit = signal.charAt(i);
			boolean isZero = (bit == '0');

			if (isZero) {
				currentLevel = (currentLevel == yLow) ? yHigh : yLow;
				g2d.drawLine(currentX, (currentLevel == yLow) ? yHigh : yLow, currentX, currentLevel);
			}

			g2d.drawLine(currentX, currentLevel, currentX + halfStep, currentLevel);

			int nextLevel = (currentLevel == yLow) ? yHigh : yLow;
			g2d.drawLine(currentX + halfStep, currentLevel, currentX + halfStep, nextLevel);
			g2d.drawLine(currentX + halfStep, nextLevel, currentX + stepX, nextLevel);

			currentLevel = nextLevel;
			currentX += stepX;
		}
	}

	private void tracerMiller(Graphics2D g2d, int stepX, int yLow, int yHigh) {
		g2d.setColor(Color.MAGENTA);
		int currentX = PADDING;
		int halfStep = stepX / 2;

		int currentLevel = yLow;

		for (int i = 0; i < signal.length(); i++) {
			char bit = signal.charAt(i);
			boolean isOne = (bit == '1');
			boolean prevIsOne = (i > 0 && signal.charAt(i - 1) == '1');

			if (!isOne && !prevIsOne && i > 0) {
				int nextLevel = (currentLevel == yLow) ? yHigh : yLow;
				g2d.drawLine(currentX, currentLevel, currentX, nextLevel);
				currentLevel = nextLevel;
			}

			if (isOne) {
				g2d.drawLine(currentX, currentLevel, currentX + halfStep, currentLevel);

				int nextLevel = (currentLevel == yLow) ? yHigh : yLow;
				g2d.drawLine(currentX + halfStep, currentLevel, currentX + halfStep, nextLevel);

				g2d.drawLine(currentX + halfStep, nextLevel, currentX + stepX, nextLevel);
				currentLevel = nextLevel;
			} else {
				g2d.drawLine(currentX, currentLevel, currentX + stepX, currentLevel);
			}

			currentX += stepX;
		}
	}
}