package interpolation; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.RenderingHints; import java.util.ArrayList; import java.util.List; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public abstract class Interpolator extends JFrame { private static final long serialVersionUID = -453395025925148885L; protected JTextArea instructionArea; public interface GetSet { public boolean isAnimationMode(); public float getTime(); public void set(Object o); } protected GetSet gs; protected List<ChangeListener> listeners = new ArrayList<ChangeListener>(); protected boolean animated; protected GridBagConstraints gbc; protected JButton animationButton; public Interpolator(GetSet gs, ChangeListener... listener) { this.gs = gs; for(ChangeListener l : listener) listeners.add(l); initializeComponents(); addActionListeners(); } private void initializeComponents() { instructionArea = new JTextArea(getInstructions()); instructionArea.setLineWrap(true); instructionArea.setWrapStyleWord(true); instructionArea.setEditable(false); instructionArea.setOpaque(false); animationButton = new JButton() { private static final long serialVersionUID = 225462629234945413L; @Override public void paint(Graphics ga) { Graphics2D g = (Graphics2D) ga; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); super.paint(ga); double xs = .9, ys = .75; g.translate(animationButton.getWidth()*((1-xs)/2), animationButton.getHeight()*((1-ys)/2)); g.scale(xs, ys); paintButton(g, animationButton.getWidth(), animationButton.getHeight()); } @Override public Dimension getPreferredSize() { return new Dimension(super.getPreferredSize().width, 50); } }; } private void addActionListeners() { animationButton.addActionListener(ae -> {setVisible(true);}); } public JButton getAnimationButton() { return animationButton; } public void refreshValue() { if(gs != null) gs.set(getValue(gs.isAnimationMode(), gs.getTime())); } protected Object getValue(boolean animated, float time) { if(isKeyframable() && animated) return getAnimationValue(time); else return getStaticValue(); } protected void fireChangeEvent() { refreshValue(); for(ChangeListener l : listeners) { l.stateChanged(new ChangeEvent(this)); } } public abstract void paintButton(Graphics2D g, int width, int height); protected abstract Object getAnimationValue(float time); protected abstract Object getStaticValue(); public abstract String getInstructions(); public abstract JComponent getManualController(); //only use for non-standard keyframable interpolators like FilterInterpolator public void enterAnimationMode() {} public void exitAnimationMode() {} public abstract boolean isKeyframable(); }