package nbtool.gui.logviews.sound.whistle; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public abstract class SoundPane extends JPanel implements ChangeListener, MouseMotionListener { private int channels, frames; private JSlider multiplier; private Display display; private JLabel peak; private JLabel selection; public SoundPane(int channel, int frame) { this.channels = channel; this.frames = frame; channelRectLast = new Rectangle[channels]; requested = new Dimension(frames * 2, 150 * channels); multiplier = new JSlider(JSlider.VERTICAL); multiplier.setMinimum(1); multiplier.setValue(1); multiplier.addChangeListener(this); peak = new JLabel(peakString()); selection = new JLabel(""); display = new Display(); display.addMouseMotionListener(this); this.setLayout(new BorderLayout()); this.add(peak, BorderLayout.NORTH); this.add(multiplier, BorderLayout.WEST); this.add(display, BorderLayout.CENTER); this.add(selection, BorderLayout.SOUTH); } public abstract int pixels(int c, int f, int radius); public abstract String peakString(); public abstract String selectionString(int c, int f); private Rectangle[] channelRectLast; private class Display extends JPanel { private Color[] defined = {Color.RED, Color.GREEN, Color.BLUE, Color.ORANGE}; private Color getChannelColor(int i) { if (i < defined.length) return defined[i]; return Color.ORANGE; } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Dimension size = this.getSize(); if (size.height < 100 || size.width < frames) { g.drawString("make me bigger", 0, 0); return; } int channelSpace = (size.height - channels * 5) / channels; //Logger.printf("%s space for each channel.", channelSpace); int mult = multiplier.getValue(); for (int c = 0; c < channels; ++c) { int channelBottom = c * (channelSpace + 5); int channelTop = channelBottom + channelSpace; int diameter = channelTop - channelBottom; int channelMid = channelBottom + diameter / 2; g.setColor(getChannelColor(c)); for (int i = 0; i < frames; ++i) { int pix = pixels(c, i, diameter / 2); pix *= mult; g.drawLine(i, channelMid, i, channelMid + pix); } g.setColor(Color.BLACK); g.drawLine(0, channelBottom, frames, channelBottom); g.drawLine(0, channelMid, frames, channelMid); g.drawLine(0, channelTop, frames, channelTop); channelRectLast[c] = new Rectangle(0, channelBottom, frames, diameter); } } } private Dimension requested; @Override public Dimension getPreferredSize() { return requested; } @Override public Dimension getMinimumSize() { return requested; } @Override public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); } @Override public void stateChanged(ChangeEvent e) { display.repaint(); } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { for (int i = 0; i < channels; ++i) { if (channelRectLast[i] != null && channelRectLast[i].contains(e.getPoint())) { int f = e.getX(); String text = selectionString(i, f); selection.setText(text); return; } } } }