TimeLineJPanel.java 4.78 KB
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusListener, ActionListener {
	private static final long serialVersionUID = 1L;
	private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);

	private static final int SCROLL_SPEED_HORIZONTAL = 30;
	private static final int SCROLL_SPEED_VERTICAL = 30;
	
	private DefaultListModel<Music> listModel;
	private double zoomLevel = 1;
	
	private JScrollPane scrollPane;
	private MusicRenderer musicRenderer;
	private Interface interf;
	private JTextField currentTick;
	private JLabel maxTicks;

	public TimeLineJPanel(Interface interf, MusicList list) {
		this.interf = interf;
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
		
		// timing infos
		JPanel timingPanel = new JPanel();
		timingPanel.setLayout(new BoxLayout(timingPanel, BoxLayout.LINE_AXIS));
		
		JLabel title = new JLabel("Timeline : ");
		title.setFont(titleFont);
		timingPanel.add(title);
		
		currentTick = new JTextField("00:00.000", 8);
		currentTick.setMaximumSize( currentTick.getPreferredSize() );
		currentTick.addFocusListener(this);
		currentTick.addActionListener(this);
		timingPanel.add(currentTick);
		
		maxTicks = new JLabel(" / 00:00.0000 (MM:ss:ms)");
		timingPanel.add(maxTicks);
		
		timingPanel.add(Box.createHorizontalGlue());
		
		add(timingPanel);
		
		// timeline
		
        listModel = new DefaultListModel<>();
        for(Music music : list.getList())
        	listModel.addElement(music);
		
		interf.timeLineList = new TimeLineJList(listModel, interf);
		musicRenderer = new MusicRenderer(this);
		interf.timeLineList.setCellRenderer(musicRenderer);
		interf.timeLineList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		scrollPane = new JScrollPane(interf.timeLineList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scrollPane.addMouseWheelListener(this);
		scrollPane.setWheelScrollingEnabled(false);
		scrollPane.setPreferredSize(new Dimension(800, 400));
		add(scrollPane);
	}

	public double getZoomLevel() { return zoomLevel; }
	
	public void updateList(MusicList list) {
		listModel.clear();
        for(Music music : list.getList())
        	listModel.addElement(music);
	}
	
	public void updateTick() {
		currentTick.setText(Util.tickToText(interf.tick));
    	long maxTick = 0;
        for(PatternJPanel pattern : musicRenderer.patterns) {
        	pattern.refreshPreferedSize();
        	long tick = pattern.getMusic().getMusicPattern().getStop();
        	if(tick > maxTick)
        		maxTick = tick;
        }
		maxTicks.setText(Util.tickToText(maxTick) + " (MM:ss:ms)");
	}
	
	public void mouseWheelMoved(MouseWheelEvent e) {
		if(e.getSource() == scrollPane) {
	        if (e.isControlDown()) {
	        	if(e.getWheelRotation() < 0)
	        		zoomLevel *= (double) e.getWheelRotation() * -1.1;
	        	else
	        		zoomLevel *= (double) e.getWheelRotation() / 1.1;
	        	
	        	int maxWidth = 0;
	            for(PatternJPanel pattern : musicRenderer.patterns) {
	            	pattern.refreshPreferedSize();
	            	int width = pattern.getEnd();
	            	if(width > maxWidth)
	            		maxWidth = width;
	            }
	            
	            interf.timeLineList.setPreferredSize(new Dimension(maxWidth, interf.getPreferredSize().height));
	            scrollPane.repaint();
	            scrollPane.getViewport().revalidate();
	        } else if(e.isShiftDown()) {
	        	JScrollBar sb = scrollPane.getHorizontalScrollBar();
	        	sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_HORIZONTAL);
	        } else {
	        	JScrollBar sb = scrollPane.getVerticalScrollBar();
	        	sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_VERTICAL);
	        }
		}
    }

	@Override
	public void focusLost(FocusEvent e) {
		if(e.getSource() == currentTick) {
			interf.tick = Util.textToTick(currentTick.getText());
			currentTick.setText(Util.tickToText(interf.tick));
			interf.computeTick();
		}
	}
	@Override
	public void focusGained(FocusEvent e) {
		if(e.getSource() == currentTick)
			currentTick.setCaretPosition(currentTick.getDocument().getLength());
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == currentTick)
			interf.getContentPane().requestFocus();
	}
}