package frond.frames;
import frond.actions.*;
import frond.colourschemes.*;
import frond.fractals.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.UndoableEditEvent;
import javax.swing.undo.*;
import java.util.Timer;
import java.util.TimerTask;
public class FractalViewer extends JFrame implements KeyListener {
private Fractal fractal;
private JPanel overlay;
private Timer overlayTimer = new Timer();
private JPopupMenu contextMenu = new JPopupMenu();
private JMenuItem undoButton = new JMenuItem("Undo");
private JMenuItem redoButton = new JMenuItem("Redo");
private GraphicsDevice device;
private Dimension selectionStart = new Dimension();
private Dimension selectionEnd = new Dimension();
private Boolean dragged = false;
private Boolean isFullScreen;
private UndoManager undoManager = new UndoManager();
MouseAdapter mouseAdapter = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
selectionStart = new Dimension(e.getX(), e.getY());
if (e.isPopupTrigger()) {
contextMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
public void mouseReleased(MouseEvent e) {
selectionEnd = new Dimension(e.getX(), e.getY());
fractal.selectionBox = false;
if (dragged) {
double scaleX = fractal.getCoordinateWidth();
double scaleY = fractal.getCoordinateHeight();
double[] old = fractal.getCoordinates();
double oldX = old[0];
double oldY = old[3];
double x1, x2, y1, y2;
if (selectionStart.getWidth() < selectionEnd.getWidth()) {
x1 = selectionStart.getWidth();
x2 = selectionEnd.getWidth();
} else {
x1 = selectionEnd.getWidth();
x2 = selectionStart.getWidth();
}
if (selectionStart.getHeight() < selectionEnd.getHeight()) {
y1 = selectionStart.getHeight();
y2 = selectionEnd.getHeight();
} else {
y1 = selectionEnd.getHeight();
y2 = selectionStart.getHeight();
}
double[] b = fractal.getCoordinates();
Dimension size = fractal.getSize();
fractal.setCoordinates(
oldX + x1 * scaleX/size.getWidth(),
oldY + y2 * scaleY/size.getHeight(),
oldX + x2 * scaleX/size.getWidth(),
oldY + y1 * scaleY/size.getHeight()
);
undoManager.undoableEditHappened(new UndoableEditEvent(fractal, new UndoableCoordinateChange(fractal, b, fractal.getCoordinates())));
updateUndo();
}
dragged = false;
if (e.isPopupTrigger()) {
contextMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
double[] b = fractal.getCoordinates();
fractal.setCoordinates(-1, 1, 1, -1);
undoManager.undoableEditHappened(new UndoableEditEvent(fractal, new UndoableReset(fractal, b , fractal.getCoordinates())));
updateUndo();
}
}
public void mouseDragged(MouseEvent e) {
dragged = true;
selectionEnd = new Dimension(e.getX(), e.getY());
fractal.boxStart = selectionStart;
fractal.boxEnd = selectionEnd;
fractal.selectionBox = true;
fractal.repaint();
}
public void mouseMoved(MouseEvent e) {
if (overlay != null) {
overlay.setVisible(true);
overlayTimer.cancel();
overlayTimer = new Timer();
overlayTimer.schedule(new HideTask(), 2 * 1000);
}
}
};
class HideTask extends TimerTask {
public void run() {
overlay.setVisible(false);
}
}
public FractalViewer(Fractal fractal, GraphicsDevice device) {
super(fractal.getName());
this.fractal = fractal;
this.device = device;
overlay = new JPanel();
overlay.setLayout(new BorderLayout());
overlay.setOpaque(false);
fractal.addMouseListener(mouseAdapter);
fractal.addMouseMotionListener(mouseAdapter);
fractal.addKeyListener(this);
fractal.setFocusable(true);
this.add(fractal);
this.setGlassPane(overlay);
overlay.setVisible(false);
undoButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
undoManager.undo();
} catch (CannotUndoException ex){
System.out.println("Can't undo");
}
updateUndo();
}
});
undoButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
contextMenu.add(undoButton);
redoButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
undoManager.redo();
} catch (CannotRedoException ex){
System.out.println("Can't redo");
}
updateUndo();
}
});
redoButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, (java.awt.event.InputEvent.SHIFT_MASK | (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()))));
contextMenu.add(redoButton);
contextMenu.addSeparator();
JMenu itterationsMenu = new JMenu("Itterations");
itterationsMenu.add(new ItterationAdjuster(fractal, 200));
itterationsMenu.add(new ItterationAdjuster(fractal, 400));
itterationsMenu.add(new ItterationAdjuster(fractal, 600));
itterationsMenu.add(new ItterationAdjuster(fractal, 800));
itterationsMenu.add(new ItterationAdjuster(fractal, 1000));
itterationsMenu.add(new ItterationAdjuster(fractal, 2000));
itterationsMenu.add(new ItterationAdjuster(fractal, 5000));
contextMenu.add(itterationsMenu);
JMenu colourSchemeMenu = new JMenu("Colour Scheme");
colourSchemeMenu.add(new CustomColourSchemeCreator(fractal));
colourSchemeMenu.addSeparator();
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new StandardColourScheme()));
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new InvertedColourScheme()));
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new BlackWhiteColourScheme()));
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new BluesColourScheme()));
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new LavaColourScheme()));
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new HalvesColourScheme()));
colourSchemeMenu.add(new ColourSchemeAdjuster(fractal, new ChalkColourScheme()));
contextMenu.add(colourSchemeMenu);
fractal.add(contextMenu);
HudPanel hudPanel = new HudPanel();
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 200)));
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 400)));
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 600)));
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 800)));
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 1000)));
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 2000)));
hudPanel.add(new HudButton(new ItterationAdjuster(fractal, 5000)));
hudPanel.add(new HudButton(new FullScreenToggle(this)));
JPanel hudPanelContainer = new JPanel();
hudPanelContainer.setOpaque(false);
hudPanelContainer.setLayout(new BoxLayout(hudPanelContainer, BoxLayout.LINE_AXIS));
hudPanelContainer.add(Box.createHorizontalGlue());
hudPanelContainer.add(hudPanel);
hudPanelContainer.add(Box.createHorizontalGlue());
overlay.add(hudPanelContainer, BorderLayout.SOUTH);
updateUndo();
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
isFullScreen = false;
fractal.setPreferredSize(new Dimension(1024, 768));
pack();
setVisible(true);
}
public void updateUndo() {
undoButton.setEnabled(undoManager.canUndo());
undoButton.setText(undoManager.getUndoPresentationName());
redoButton.setEnabled(undoManager.canRedo());
redoButton.setText(undoManager.getRedoPresentationName());
}
/**
* Full Screen action
*
* switches the fractal viewer to the given full screen state
* if the parameter is true the window will be mande fullScreen,
* if false the window will be returned to windowed mode
*
* @param use full screen
*/
public void setFullScreen(boolean fullScreen) {
if (fullScreen != isFullScreen) {
setVisible(false);
if (isDisplayable())
dispose();
setUndecorated(fullScreen);
setResizable(!fullScreen);
if (fullScreen) {
if (device.isFullScreenSupported()) {
device.setFullScreenWindow(this);
validate();
isFullScreen = fullScreen;
}
} else {
device.setFullScreenWindow(null);
pack();
isFullScreen = fullScreen;
}
setVisible(true);
}
}
public void keyPressed(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_ESCAPE) {
if (isFullScreen) {
setFullScreen(false);
}
}
double[] b = fractal.getCoordinates();
if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
fractal.translate(0.0, fractal.getCoordinateHeight()/10);
undoManager.undoableEditHappened(new UndoableEditEvent(fractal, new UndoablePan(fractal, b, fractal.getCoordinates())));
} else if (ke.getKeyCode() == KeyEvent.VK_UP) {
fractal.translate(0.0, -fractal.getCoordinateHeight()/10);
undoManager.undoableEditHappened(new UndoableEditEvent(fractal, new UndoablePan(fractal, b, fractal.getCoordinates())));
} if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
fractal.translate(-fractal.getCoordinateWidth()/10, 0.0);
undoManager.undoableEditHappened(new UndoableEditEvent(fractal, new UndoablePan(fractal, b, fractal.getCoordinates())));
} if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
fractal.translate(fractal.getCoordinateWidth()/10, 0.0);
undoManager.undoableEditHappened(new UndoableEditEvent(fractal, new UndoablePan(fractal, b, fractal.getCoordinates())));
}
updateUndo();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}