mirror of
https://github.com/alterdekim/Fractal-Generator.git
synced 2025-04-08 10:40:31 +03:00
Initial commit
This commit is contained in:
commit
4cba9cd8ba
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Project exclude paths
|
||||
/out/
|
208
src/com/alterdekim/fractals/Canvas.java
Normal file
208
src/com/alterdekim/fractals/Canvas.java
Normal file
@ -0,0 +1,208 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class Canvas extends JPanel implements KeyListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final int MAX_ITER = 200;
|
||||
|
||||
private static double RE_START = -2;
|
||||
private static double RE_END = 0.5;
|
||||
private static double IM_START = -1;
|
||||
private static double IM_END = 1;
|
||||
|
||||
private double juliaRez = 0;
|
||||
private double juliaImz = 0;
|
||||
|
||||
private int mArg = 3;
|
||||
|
||||
private double sizeX = 1;
|
||||
private double sizeY = 1;
|
||||
|
||||
private int type = 0;
|
||||
|
||||
public Canvas() {
|
||||
this.addKeyListener(this);
|
||||
}
|
||||
|
||||
public void setInterval( double r_s, double r_e, double i_s, double i_e, double sX, double sY ) {
|
||||
Canvas.RE_START = r_s;
|
||||
Canvas.RE_END = r_e;
|
||||
Canvas.IM_START = i_s;
|
||||
Canvas.IM_END = i_e;
|
||||
this.sizeX = sX;
|
||||
this.sizeY = sY;
|
||||
}
|
||||
|
||||
private int mandelbrot( Complex c ) {
|
||||
Complex z = new Complex(0,0);
|
||||
int n = 0;
|
||||
while ( ComplexUtils.abs(z) <= 2 && n < MAX_ITER) {
|
||||
z = ComplexUtils.pow(z);
|
||||
z = ComplexUtils.sum(z, c);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private int bship( Complex c ) {
|
||||
Complex z = new Complex(0,0);
|
||||
int n = 0;
|
||||
while ( ComplexUtils.abs(z) <= 2 && n < MAX_ITER) {
|
||||
z = new Complex( Math.abs(z.Rez), Math.abs(z.Imz) );
|
||||
z = ComplexUtils.pow(z);
|
||||
z = ComplexUtils.sum(z, c);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private int customMandelbrot( Complex c ) {
|
||||
Complex z = new Complex(0,0);
|
||||
int n = 0;
|
||||
while( ComplexUtils.abs(z) <= 2 && n < MAX_ITER ) {
|
||||
z = ComplexUtils.pow(z, mArg);
|
||||
z = ComplexUtils.sum(z, c);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private int julia( Complex c, Complex j ) {
|
||||
Complex z = c;
|
||||
c = j;
|
||||
int n = 0;
|
||||
while ( ComplexUtils.abs(z) <= 2 && n < MAX_ITER) {
|
||||
z = ComplexUtils.pow(z);
|
||||
z = ComplexUtils.sum(z, c);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public void paintMandel() {
|
||||
this.type = 0;
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public void paintJulia( String arg, String _arg ) {
|
||||
this.type = 1;
|
||||
this.juliaRez = Double.parseDouble(arg);
|
||||
this.juliaImz = Double.parseDouble(_arg);
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public void paintBurningship() {
|
||||
this.type = 2;
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public void paintCustom( String arg ) {
|
||||
this.mArg = Integer.parseInt(arg);
|
||||
this.type = 3;
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent( Graphics g ) {
|
||||
int width = this.getWidth();
|
||||
int height = this.getHeight();
|
||||
for( int x = 0; x < width; x++ ) {
|
||||
for( int y = 0; y < height; y++ ) {
|
||||
Complex c = new Complex( ((((x) * (RE_END-RE_START)) / (width) ) + RE_START) / sizeX, ((((y) * (IM_END-IM_START)) / (height)) + IM_START) / sizeY );
|
||||
float color = 0.0f;
|
||||
if( this.type == 1 ) {
|
||||
color = ((float) julia(c, new Complex(juliaRez, juliaImz))) / ((float) MAX_ITER);
|
||||
} else if( this.type == 0 ) {
|
||||
color = ((float) mandelbrot(c)) / ((float) MAX_ITER);
|
||||
} else if( this.type == 2 ) {
|
||||
color = ((float) bship(c)) / ((float) MAX_ITER);
|
||||
} else if( this.type == 3 ) {
|
||||
color = ((float) customMandelbrot(c)) / ((float) MAX_ITER);
|
||||
}
|
||||
|
||||
float val = rangeConvert( color, 0f, 1f, Window.hueStart, Window.hueEnd ) * 0.01f;
|
||||
float sat = rangeConvert( color, 0f, 1f, Window.satStart, Window.satEnd ) * 0.01f;
|
||||
g.setColor(Color.getHSBColor(val, sat, 1 - val));
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float rangeConvert( float value, float leftMin, float leftMax, float rightMin, float rightMax ) {
|
||||
float leftSpan = leftMax - leftMin;
|
||||
float rightSpan = rightMax - rightMin;
|
||||
float valueScaled = (value - leftMin) / (leftSpan);
|
||||
return rightMin + (valueScaled * rightSpan);
|
||||
}
|
||||
|
||||
private static class ComplexUtils {
|
||||
public static double abs( Complex c ) {
|
||||
return Math.sqrt( Math.pow(c.Rez, 2) + Math.pow(c.Imz, 2) );
|
||||
}
|
||||
|
||||
public static Complex sum( Complex f, Complex s ) {
|
||||
return new Complex( f.Rez + s.Rez, f.Imz + s.Imz );
|
||||
}
|
||||
|
||||
public static Complex pow( Complex c ) {
|
||||
return new Complex((c.Rez * c.Rez) + ((-1) * (c.Imz * c.Imz)), (2 * c.Rez * c.Imz));
|
||||
}
|
||||
|
||||
public static Complex pow( Complex c, int num ) {
|
||||
Complex n = c;
|
||||
for( int i = 0; i < num; i++ ) {
|
||||
n = ComplexUtils.multiply(n, c);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public static Complex multiply( Complex f, Complex s ) {
|
||||
return new Complex(((f.Rez * s.Rez)-(f.Imz*s.Imz)), (f.Rez * s.Imz) + (f.Imz * s.Rez));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
|
||||
RE_START += 0.01/sizeX;
|
||||
RE_END += 0.01/sizeY;
|
||||
this.repaint();
|
||||
} else if( e.getKeyCode() == KeyEvent.VK_LEFT ) {
|
||||
RE_START -= 0.01/sizeX;
|
||||
RE_END -= 0.01/sizeY;
|
||||
this.repaint();
|
||||
} else if( e.getKeyCode() == KeyEvent.VK_UP ) {
|
||||
IM_START -= 0.01/sizeX;
|
||||
IM_END -= 0.01/sizeY;
|
||||
this.repaint();
|
||||
} else if( e.getKeyCode() == KeyEvent.VK_DOWN ) {
|
||||
IM_START += 0.01/sizeX;
|
||||
IM_END += 0.01/sizeY;
|
||||
this.repaint();
|
||||
} else if( e.getKeyCode() == KeyEvent.VK_P ) {
|
||||
sizeX += 0.01;
|
||||
sizeY += 0.01;
|
||||
this.repaint();
|
||||
} else if( e.getKeyCode() == KeyEvent.VK_O ) {
|
||||
sizeX -= 0.01;
|
||||
sizeY -= 0.01;
|
||||
this.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {}
|
||||
}
|
11
src/com/alterdekim/fractals/Complex.java
Normal file
11
src/com/alterdekim/fractals/Complex.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
public class Complex {
|
||||
public double Rez;
|
||||
public double Imz;
|
||||
|
||||
public Complex( double Rez, double Imz ) {
|
||||
this.Rez = Rez;
|
||||
this.Imz = Imz;
|
||||
}
|
||||
}
|
133
src/com/alterdekim/fractals/GradientChoice.java
Normal file
133
src/com/alterdekim/fractals/GradientChoice.java
Normal file
@ -0,0 +1,133 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JSlider;
|
||||
import java.awt.Dialog.ModalityType;
|
||||
|
||||
public class GradientChoice extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final JPanel contentPanel = new JPanel();
|
||||
|
||||
public boolean isOk = false;
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
/*public static void main(String[] args) {
|
||||
try {
|
||||
GradientChoice dialog = new GradientChoice();
|
||||
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
dialog.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Create the dialog.
|
||||
*/
|
||||
public GradientChoice() {
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
setBounds(100, 100, 350, 300);
|
||||
setResizable(false);
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
getContentPane().add(contentPanel, BorderLayout.CENTER);
|
||||
contentPanel.setLayout(null);
|
||||
|
||||
JLabel lblNewLabel = new JLabel("Hue:");
|
||||
lblNewLabel.setBounds(6, 6, 338, 25);
|
||||
contentPanel.add(lblNewLabel);
|
||||
|
||||
HuePanel huePanel = new HuePanel();
|
||||
huePanel.setBounds(6, 36, 338, 40);
|
||||
contentPanel.add(huePanel);
|
||||
huePanel.endX = 338;
|
||||
huePanel.repaint();
|
||||
|
||||
RangeSlider hueSlider = new RangeSlider();
|
||||
hueSlider.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
huePanel.startX = (int) ((((double)hueSlider.getValue()) / ((double)100)) * ((double)huePanel.getWidth()));
|
||||
huePanel.endX = (int) ((((double)hueSlider.getUpperValue()) / ((double)100)) * ((double)huePanel.getWidth()));
|
||||
huePanel.repaint();
|
||||
}
|
||||
});
|
||||
hueSlider.setValue((int)Window.hueStart);
|
||||
hueSlider.setUpperValue((int)Window.hueEnd);
|
||||
hueSlider.setBounds(6, 81, 338, 29);
|
||||
contentPanel.add(hueSlider);
|
||||
huePanel.repaint();
|
||||
|
||||
JLabel lblNewSat = new JLabel("Saturation:");
|
||||
lblNewSat.setBounds(6, 115, 338, 25);
|
||||
contentPanel.add(lblNewSat);
|
||||
|
||||
SatPanel satPanel = new SatPanel();
|
||||
satPanel.setBounds(6, 140, 338, 40);
|
||||
contentPanel.add(satPanel);
|
||||
satPanel.endX = 338;
|
||||
satPanel.repaint();
|
||||
|
||||
RangeSlider satSlider = new RangeSlider();
|
||||
satSlider.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
satPanel.startX = (int) ((((double)satSlider.getValue()) / ((double)100)) * ((double)satPanel.getWidth()));
|
||||
satPanel.endX = (int) ((((double)satSlider.getUpperValue()) / ((double)100)) * ((double)satPanel.getWidth()));
|
||||
satPanel.repaint();
|
||||
}
|
||||
});
|
||||
satSlider.setValue((int)Window.satStart);
|
||||
satSlider.setUpperValue((int)Window.satEnd);
|
||||
satSlider.setBounds(6, 180, 338, 29);
|
||||
contentPanel.add(satSlider);
|
||||
satPanel.repaint();
|
||||
|
||||
{
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
|
||||
getContentPane().add(buttonPane, BorderLayout.SOUTH);
|
||||
{
|
||||
JButton okButton = new JButton("OK");
|
||||
okButton.setActionCommand("OK");
|
||||
buttonPane.add(okButton);
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Window.satStart = Canvas.rangeConvert(satPanel.startX, 0, 338, 0, 100);
|
||||
Window.satEnd = Canvas.rangeConvert(satPanel.endX, 0, 338, 0, 100);
|
||||
Window.hueStart = Canvas.rangeConvert(huePanel.startX, 0, 338, 0, 100);
|
||||
Window.hueEnd = Canvas.rangeConvert(huePanel.endX, 0, 338, 0, 100);
|
||||
isOk = true;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
}
|
||||
{
|
||||
JButton cancelButton = new JButton("Cancel");
|
||||
cancelButton.setActionCommand("Cancel");
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
buttonPane.add(cancelButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
src/com/alterdekim/fractals/HuePanel.java
Normal file
24
src/com/alterdekim/fractals/HuePanel.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class HuePanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public int startX = 0;
|
||||
public int endX = getWidth();
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
float color = ((float) 1) / ((float) getWidth()) * ((float) startX);
|
||||
for( int x = startX; x < endX; x++ ) {
|
||||
g.setColor(Color.getHSBColor(color, 1f, 0.7f));
|
||||
g.fillRect(x, 0, 1, getHeight());
|
||||
color += ((float) 1) / ((float) getWidth());
|
||||
}
|
||||
}
|
||||
}
|
103
src/com/alterdekim/fractals/RangeSlider.java
Normal file
103
src/com/alterdekim/fractals/RangeSlider.java
Normal file
@ -0,0 +1,103 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
import javax.swing.JSlider;
|
||||
|
||||
/**
|
||||
* An extension of JSlider to select a range of values using two thumb controls.
|
||||
* The thumb controls are used to select the lower and upper value of a range
|
||||
* with predetermined minimum and maximum values.
|
||||
*
|
||||
* <p>Note that RangeSlider makes use of the default BoundedRangeModel, which
|
||||
* supports an inner range defined by a value and an extent. The upper value
|
||||
* returned by RangeSlider is simply the lower value plus the extent.</p>
|
||||
*/
|
||||
public class RangeSlider extends JSlider {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs a RangeSlider with default minimum and maximum values of 0
|
||||
* and 100.
|
||||
*/
|
||||
public RangeSlider() {
|
||||
initSlider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RangeSlider with the specified default minimum and maximum
|
||||
* values.
|
||||
*/
|
||||
public RangeSlider(int min, int max) {
|
||||
super(min, max);
|
||||
initSlider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the slider by setting default properties.
|
||||
*/
|
||||
private void initSlider() {
|
||||
setOrientation(HORIZONTAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the superclass method to install the UI delegate to draw two
|
||||
* thumbs.
|
||||
*/
|
||||
@Override
|
||||
public void updateUI() {
|
||||
setUI(new RangeSliderUI(this));
|
||||
// Update UI for slider labels. This must be called after updating the
|
||||
// UI of the slider. Refer to JSlider.updateUI().
|
||||
updateLabelUIs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lower value in the range.
|
||||
*/
|
||||
@Override
|
||||
public int getValue() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lower value in the range.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(int value) {
|
||||
int oldValue = getValue();
|
||||
if (oldValue == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute new value and extent to maintain upper value.
|
||||
int oldExtent = getExtent();
|
||||
int newValue = Math.min(Math.max(getMinimum(), value), oldValue + oldExtent);
|
||||
int newExtent = oldExtent + oldValue - newValue;
|
||||
|
||||
// Set new value and extent, and fire a single change event.
|
||||
getModel().setRangeProperties(newValue, newExtent, getMinimum(),
|
||||
getMaximum(), getValueIsAdjusting());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the upper value in the range.
|
||||
*/
|
||||
public int getUpperValue() {
|
||||
return getValue() + getExtent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the upper value in the range.
|
||||
*/
|
||||
public void setUpperValue(int value) {
|
||||
// Compute new extent.
|
||||
int lowerValue = getValue();
|
||||
int newExtent = Math.min(Math.max(0, value - lowerValue), getMaximum() - lowerValue);
|
||||
|
||||
// Set extent to set upper value.
|
||||
setExtent(newExtent);
|
||||
}
|
||||
}
|
596
src/com/alterdekim/fractals/RangeSliderUI.java
Normal file
596
src/com/alterdekim/fractals/RangeSliderUI.java
Normal file
@ -0,0 +1,596 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.plaf.basic.BasicSliderUI;
|
||||
|
||||
/**
|
||||
* UI delegate for the RangeSlider component. RangeSliderUI paints two thumbs,
|
||||
* one for the lower value and one for the upper value.
|
||||
*/
|
||||
class RangeSliderUI extends BasicSliderUI {
|
||||
|
||||
/** Color of selected range. */
|
||||
private Color rangeColor = Color.BLACK;
|
||||
|
||||
/** Location and size of thumb for upper value. */
|
||||
private Rectangle upperThumbRect;
|
||||
/** Indicator that determines whether upper thumb is selected. */
|
||||
private boolean upperThumbSelected;
|
||||
|
||||
/** Indicator that determines whether lower thumb is being dragged. */
|
||||
private transient boolean lowerDragging;
|
||||
/** Indicator that determines whether upper thumb is being dragged. */
|
||||
private transient boolean upperDragging;
|
||||
|
||||
/**
|
||||
* Constructs a RangeSliderUI for the specified slider component.
|
||||
* @param b RangeSlider
|
||||
*/
|
||||
public RangeSliderUI(RangeSlider b) {
|
||||
super(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs this UI delegate on the specified component.
|
||||
*/
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
upperThumbRect = new Rectangle();
|
||||
super.installUI(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a listener to handle track events in the specified slider.
|
||||
*/
|
||||
@Override
|
||||
protected TrackListener createTrackListener(JSlider slider) {
|
||||
return new RangeTrackListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a listener to handle change events in the specified slider.
|
||||
*/
|
||||
@Override
|
||||
protected ChangeListener createChangeListener(JSlider slider) {
|
||||
return new ChangeHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the dimensions for both thumbs.
|
||||
*/
|
||||
@Override
|
||||
protected void calculateThumbSize() {
|
||||
// Call superclass method for lower thumb size.
|
||||
super.calculateThumbSize();
|
||||
|
||||
// Set upper thumb size.
|
||||
upperThumbRect.setSize(thumbRect.width, thumbRect.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the locations for both thumbs.
|
||||
*/
|
||||
@Override
|
||||
protected void calculateThumbLocation() {
|
||||
// Call superclass method for lower thumb location.
|
||||
super.calculateThumbLocation();
|
||||
|
||||
// Adjust upper value to snap to ticks if necessary.
|
||||
if (slider.getSnapToTicks()) {
|
||||
int upperValue = slider.getValue() + slider.getExtent();
|
||||
int snappedValue = upperValue;
|
||||
int majorTickSpacing = slider.getMajorTickSpacing();
|
||||
int minorTickSpacing = slider.getMinorTickSpacing();
|
||||
int tickSpacing = 0;
|
||||
|
||||
if (minorTickSpacing > 0) {
|
||||
tickSpacing = minorTickSpacing;
|
||||
} else if (majorTickSpacing > 0) {
|
||||
tickSpacing = majorTickSpacing;
|
||||
}
|
||||
|
||||
if (tickSpacing != 0) {
|
||||
// If it's not on a tick, change the value
|
||||
if ((upperValue - slider.getMinimum()) % tickSpacing != 0) {
|
||||
float temp = (float)(upperValue - slider.getMinimum()) / (float)tickSpacing;
|
||||
int whichTick = Math.round(temp);
|
||||
snappedValue = slider.getMinimum() + (whichTick * tickSpacing);
|
||||
}
|
||||
|
||||
if (snappedValue != upperValue) {
|
||||
slider.setExtent(snappedValue - slider.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate upper thumb location. The thumb is centered over its
|
||||
// value on the track.
|
||||
if (slider.getOrientation() == JSlider.HORIZONTAL) {
|
||||
int upperPosition = xPositionForValue(slider.getValue() + slider.getExtent());
|
||||
upperThumbRect.x = upperPosition - (upperThumbRect.width / 2);
|
||||
upperThumbRect.y = trackRect.y;
|
||||
|
||||
} else {
|
||||
int upperPosition = yPositionForValue(slider.getValue() + slider.getExtent());
|
||||
upperThumbRect.x = trackRect.x;
|
||||
upperThumbRect.y = upperPosition - (upperThumbRect.height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a thumb.
|
||||
*/
|
||||
@Override
|
||||
protected Dimension getThumbSize() {
|
||||
return new Dimension(12, 12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the slider. The selected thumb is always painted on top of the
|
||||
* other thumb.
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
super.paint(g, c);
|
||||
|
||||
Rectangle clipRect = g.getClipBounds();
|
||||
if (upperThumbSelected) {
|
||||
// Paint lower thumb first, then upper thumb.
|
||||
if (clipRect.intersects(thumbRect)) {
|
||||
paintLowerThumb(g);
|
||||
}
|
||||
if (clipRect.intersects(upperThumbRect)) {
|
||||
paintUpperThumb(g);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Paint upper thumb first, then lower thumb.
|
||||
if (clipRect.intersects(upperThumbRect)) {
|
||||
paintUpperThumb(g);
|
||||
}
|
||||
if (clipRect.intersects(thumbRect)) {
|
||||
paintLowerThumb(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the track.
|
||||
*/
|
||||
@Override
|
||||
public void paintTrack(Graphics g) {
|
||||
// Draw track.
|
||||
super.paintTrack(g);
|
||||
|
||||
Rectangle trackBounds = trackRect;
|
||||
|
||||
if (slider.getOrientation() == JSlider.HORIZONTAL) {
|
||||
// Determine position of selected range by moving from the middle
|
||||
// of one thumb to the other.
|
||||
int lowerX = thumbRect.x + (thumbRect.width / 2);
|
||||
int upperX = upperThumbRect.x + (upperThumbRect.width / 2);
|
||||
|
||||
// Determine track position.
|
||||
int cy = (trackBounds.height / 2) - 2;
|
||||
|
||||
// Save color and shift position.
|
||||
Color oldColor = g.getColor();
|
||||
g.translate(trackBounds.x, trackBounds.y + cy);
|
||||
|
||||
// Draw selected range.
|
||||
g.setColor(rangeColor);
|
||||
for (int y = 0; y <= 3; y++) {
|
||||
g.drawLine(lowerX - trackBounds.x, y, upperX - trackBounds.x, y);
|
||||
}
|
||||
|
||||
// Restore position and color.
|
||||
g.translate(-trackBounds.x, -(trackBounds.y + cy));
|
||||
g.setColor(oldColor);
|
||||
|
||||
} else {
|
||||
// Determine position of selected range by moving from the middle
|
||||
// of one thumb to the other.
|
||||
int lowerY = thumbRect.x + (thumbRect.width / 2);
|
||||
int upperY = upperThumbRect.x + (upperThumbRect.width / 2);
|
||||
|
||||
// Determine track position.
|
||||
int cx = (trackBounds.width / 2) - 2;
|
||||
|
||||
// Save color and shift position.
|
||||
Color oldColor = g.getColor();
|
||||
g.translate(trackBounds.x + cx, trackBounds.y);
|
||||
|
||||
// Draw selected range.
|
||||
g.setColor(rangeColor);
|
||||
for (int x = 0; x <= 3; x++) {
|
||||
g.drawLine(x, lowerY - trackBounds.y, x, upperY - trackBounds.y);
|
||||
}
|
||||
|
||||
// Restore position and color.
|
||||
g.translate(-(trackBounds.x + cx), -trackBounds.y);
|
||||
g.setColor(oldColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides superclass method to do nothing. Thumb painting is handled
|
||||
* within the <code>paint()</code> method.
|
||||
*/
|
||||
@Override
|
||||
public void paintThumb(Graphics g) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the thumb for the lower value using the specified graphics object.
|
||||
*/
|
||||
private void paintLowerThumb(Graphics g) {
|
||||
Rectangle knobBounds = thumbRect;
|
||||
int w = knobBounds.width;
|
||||
int h = knobBounds.height;
|
||||
|
||||
// Create graphics copy.
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
|
||||
// Create default thumb shape.
|
||||
Shape thumbShape = createThumbShape(w - 1, h - 1);
|
||||
|
||||
// Draw thumb.
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.translate(knobBounds.x, knobBounds.y);
|
||||
|
||||
g2d.setColor(Color.GRAY);
|
||||
g2d.fill(thumbShape);
|
||||
|
||||
g2d.setColor(Color.GRAY);
|
||||
g2d.draw(thumbShape);
|
||||
|
||||
// Dispose graphics.
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the thumb for the upper value using the specified graphics object.
|
||||
*/
|
||||
private void paintUpperThumb(Graphics g) {
|
||||
Rectangle knobBounds = upperThumbRect;
|
||||
int w = knobBounds.width;
|
||||
int h = knobBounds.height;
|
||||
|
||||
// Create graphics copy.
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
|
||||
// Create default thumb shape.
|
||||
Shape thumbShape = createThumbShape(w - 1, h - 1);
|
||||
|
||||
// Draw thumb.
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.translate(knobBounds.x, knobBounds.y);
|
||||
|
||||
g2d.setColor(Color.GRAY);
|
||||
g2d.fill(thumbShape);
|
||||
|
||||
g2d.setColor(Color.GRAY);
|
||||
g2d.draw(thumbShape);
|
||||
|
||||
// Dispose graphics.
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Shape representing a thumb.
|
||||
*/
|
||||
private Shape createThumbShape(int width, int height) {
|
||||
// Use circular shape.
|
||||
Ellipse2D shape = new Ellipse2D.Double(0, 0, width, height);
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location of the upper thumb, and repaints the slider. This is
|
||||
* called when the upper thumb is dragged to repaint the slider. The
|
||||
* <code>setThumbLocation()</code> method performs the same task for the
|
||||
* lower thumb.
|
||||
*/
|
||||
private void setUpperThumbLocation(int x, int y) {
|
||||
Rectangle upperUnionRect = new Rectangle();
|
||||
upperUnionRect.setBounds(upperThumbRect);
|
||||
|
||||
upperThumbRect.setLocation(x, y);
|
||||
|
||||
SwingUtilities.computeUnion(upperThumbRect.x, upperThumbRect.y, upperThumbRect.width, upperThumbRect.height, upperUnionRect);
|
||||
slider.repaint(upperUnionRect.x, upperUnionRect.y, upperUnionRect.width, upperUnionRect.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the selected thumb in the specified direction by a block increment.
|
||||
* This method is called when the user presses the Page Up or Down keys.
|
||||
*/
|
||||
public void scrollByBlock(int direction) {
|
||||
synchronized (slider) {
|
||||
int blockIncrement = (slider.getMaximum() - slider.getMinimum()) / 10;
|
||||
if (blockIncrement <= 0 && slider.getMaximum() > slider.getMinimum()) {
|
||||
blockIncrement = 1;
|
||||
}
|
||||
int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL);
|
||||
|
||||
if (upperThumbSelected) {
|
||||
int oldValue = ((RangeSlider) slider).getUpperValue();
|
||||
((RangeSlider) slider).setUpperValue(oldValue + delta);
|
||||
} else {
|
||||
int oldValue = slider.getValue();
|
||||
slider.setValue(oldValue + delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the selected thumb in the specified direction by a unit increment.
|
||||
* This method is called when the user presses one of the arrow keys.
|
||||
*/
|
||||
public void scrollByUnit(int direction) {
|
||||
synchronized (slider) {
|
||||
int delta = 1 * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL);
|
||||
|
||||
if (upperThumbSelected) {
|
||||
int oldValue = ((RangeSlider) slider).getUpperValue();
|
||||
((RangeSlider) slider).setUpperValue(oldValue + delta);
|
||||
} else {
|
||||
int oldValue = slider.getValue();
|
||||
slider.setValue(oldValue + delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener to handle model change events. This calculates the thumb
|
||||
* locations and repaints the slider if the value change is not caused by
|
||||
* dragging a thumb.
|
||||
*/
|
||||
public class ChangeHandler implements ChangeListener {
|
||||
public void stateChanged(ChangeEvent arg0) {
|
||||
if (!lowerDragging && !upperDragging) {
|
||||
calculateThumbLocation();
|
||||
slider.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener to handle mouse movements in the slider track.
|
||||
*/
|
||||
public class RangeTrackListener extends TrackListener {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (!slider.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentMouseX = e.getX();
|
||||
currentMouseY = e.getY();
|
||||
|
||||
if (slider.isRequestFocusEnabled()) {
|
||||
slider.requestFocus();
|
||||
}
|
||||
|
||||
// Determine which thumb is pressed. If the upper thumb is
|
||||
// selected (last one dragged), then check its position first;
|
||||
// otherwise check the position of the lower thumb first.
|
||||
boolean lowerPressed = false;
|
||||
boolean upperPressed = false;
|
||||
if (upperThumbSelected || slider.getMinimum() == slider.getValue()) {
|
||||
if (upperThumbRect.contains(currentMouseX, currentMouseY)) {
|
||||
upperPressed = true;
|
||||
} else if (thumbRect.contains(currentMouseX, currentMouseY)) {
|
||||
lowerPressed = true;
|
||||
}
|
||||
} else {
|
||||
if (thumbRect.contains(currentMouseX, currentMouseY)) {
|
||||
lowerPressed = true;
|
||||
} else if (upperThumbRect.contains(currentMouseX, currentMouseY)) {
|
||||
upperPressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle lower thumb pressed.
|
||||
if (lowerPressed) {
|
||||
switch (slider.getOrientation()) {
|
||||
case JSlider.VERTICAL:
|
||||
offset = currentMouseY - thumbRect.y;
|
||||
break;
|
||||
case JSlider.HORIZONTAL:
|
||||
offset = currentMouseX - thumbRect.x;
|
||||
break;
|
||||
}
|
||||
upperThumbSelected = false;
|
||||
lowerDragging = true;
|
||||
return;
|
||||
}
|
||||
lowerDragging = false;
|
||||
|
||||
// Handle upper thumb pressed.
|
||||
if (upperPressed) {
|
||||
switch (slider.getOrientation()) {
|
||||
case JSlider.VERTICAL:
|
||||
offset = currentMouseY - upperThumbRect.y;
|
||||
break;
|
||||
case JSlider.HORIZONTAL:
|
||||
offset = currentMouseX - upperThumbRect.x;
|
||||
break;
|
||||
}
|
||||
upperThumbSelected = true;
|
||||
upperDragging = true;
|
||||
return;
|
||||
}
|
||||
upperDragging = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
lowerDragging = false;
|
||||
upperDragging = false;
|
||||
slider.setValueIsAdjusting(false);
|
||||
super.mouseReleased(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (!slider.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentMouseX = e.getX();
|
||||
currentMouseY = e.getY();
|
||||
|
||||
if (lowerDragging) {
|
||||
slider.setValueIsAdjusting(true);
|
||||
moveLowerThumb();
|
||||
|
||||
} else if (upperDragging) {
|
||||
slider.setValueIsAdjusting(true);
|
||||
moveUpperThumb();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldScroll(int direction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the location of the lower thumb, and sets its corresponding
|
||||
* value in the slider.
|
||||
*/
|
||||
private void moveLowerThumb() {
|
||||
int thumbMiddle = 0;
|
||||
|
||||
switch (slider.getOrientation()) {
|
||||
case JSlider.VERTICAL:
|
||||
int halfThumbHeight = thumbRect.height / 2;
|
||||
int thumbTop = currentMouseY - offset;
|
||||
int trackTop = trackRect.y;
|
||||
int trackBottom = trackRect.y + (trackRect.height - 1);
|
||||
int vMax = yPositionForValue(slider.getValue() + slider.getExtent());
|
||||
|
||||
// Apply bounds to thumb position.
|
||||
if (drawInverted()) {
|
||||
trackBottom = vMax;
|
||||
} else {
|
||||
trackTop = vMax;
|
||||
}
|
||||
thumbTop = Math.max(thumbTop, trackTop - halfThumbHeight);
|
||||
thumbTop = Math.min(thumbTop, trackBottom - halfThumbHeight);
|
||||
|
||||
setThumbLocation(thumbRect.x, thumbTop);
|
||||
|
||||
// Update slider value.
|
||||
thumbMiddle = thumbTop + halfThumbHeight;
|
||||
slider.setValue(valueForYPosition(thumbMiddle));
|
||||
break;
|
||||
|
||||
case JSlider.HORIZONTAL:
|
||||
int halfThumbWidth = thumbRect.width / 2;
|
||||
int thumbLeft = currentMouseX - offset;
|
||||
int trackLeft = trackRect.x;
|
||||
int trackRight = trackRect.x + (trackRect.width - 1);
|
||||
int hMax = xPositionForValue(slider.getValue() + slider.getExtent());
|
||||
|
||||
// Apply bounds to thumb position.
|
||||
if (drawInverted()) {
|
||||
trackLeft = hMax;
|
||||
} else {
|
||||
trackRight = hMax;
|
||||
}
|
||||
thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
|
||||
thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);
|
||||
|
||||
setThumbLocation(thumbLeft, thumbRect.y);
|
||||
|
||||
// Update slider value.
|
||||
thumbMiddle = thumbLeft + halfThumbWidth;
|
||||
slider.setValue(valueForXPosition(thumbMiddle));
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the location of the upper thumb, and sets its corresponding
|
||||
* value in the slider.
|
||||
*/
|
||||
private void moveUpperThumb() {
|
||||
int thumbMiddle = 0;
|
||||
|
||||
switch (slider.getOrientation()) {
|
||||
case JSlider.VERTICAL:
|
||||
int halfThumbHeight = thumbRect.height / 2;
|
||||
int thumbTop = currentMouseY - offset;
|
||||
int trackTop = trackRect.y;
|
||||
int trackBottom = trackRect.y + (trackRect.height - 1);
|
||||
int vMin = yPositionForValue(slider.getValue());
|
||||
|
||||
// Apply bounds to thumb position.
|
||||
if (drawInverted()) {
|
||||
trackTop = vMin;
|
||||
} else {
|
||||
trackBottom = vMin;
|
||||
}
|
||||
thumbTop = Math.max(thumbTop, trackTop - halfThumbHeight);
|
||||
thumbTop = Math.min(thumbTop, trackBottom - halfThumbHeight);
|
||||
|
||||
setUpperThumbLocation(thumbRect.x, thumbTop);
|
||||
|
||||
// Update slider extent.
|
||||
thumbMiddle = thumbTop + halfThumbHeight;
|
||||
slider.setExtent(valueForYPosition(thumbMiddle) - slider.getValue());
|
||||
break;
|
||||
|
||||
case JSlider.HORIZONTAL:
|
||||
int halfThumbWidth = thumbRect.width / 2;
|
||||
int thumbLeft = currentMouseX - offset;
|
||||
int trackLeft = trackRect.x;
|
||||
int trackRight = trackRect.x + (trackRect.width - 1);
|
||||
int hMin = xPositionForValue(slider.getValue());
|
||||
|
||||
// Apply bounds to thumb position.
|
||||
if (drawInverted()) {
|
||||
trackRight = hMin;
|
||||
} else {
|
||||
trackLeft = hMin;
|
||||
}
|
||||
thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);
|
||||
thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);
|
||||
|
||||
setUpperThumbLocation(thumbLeft, thumbRect.y);
|
||||
|
||||
// Update slider extent.
|
||||
thumbMiddle = thumbLeft + halfThumbWidth;
|
||||
slider.setExtent(valueForXPosition(thumbMiddle) - slider.getValue());
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
src/com/alterdekim/fractals/SatPanel.java
Normal file
24
src/com/alterdekim/fractals/SatPanel.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class SatPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public int startX = 0;
|
||||
public int endX = getWidth();
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
float color = ((float) 1) / ((float) getWidth()) * ((float) startX);
|
||||
for( int x = startX; x < endX; x++ ) {
|
||||
g.setColor(Color.getHSBColor(0f, color, 0.7f));
|
||||
g.fillRect(x, 0, 1, getHeight());
|
||||
color += ((float) 1) / ((float) getWidth());
|
||||
}
|
||||
}
|
||||
}
|
201
src/com/alterdekim/fractals/Window.java
Normal file
201
src/com/alterdekim/fractals/Window.java
Normal file
@ -0,0 +1,201 @@
|
||||
package com.alterdekim.fractals;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Graphics2D;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class Window {
|
||||
|
||||
private JFrame frame;
|
||||
|
||||
public static float hueStart = 0f;
|
||||
public static float hueEnd = 100f;
|
||||
|
||||
public static float satStart = 80f;
|
||||
public static float satEnd = 100f;
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
Window window = new Window();
|
||||
window.frame.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the application.
|
||||
*/
|
||||
public Window() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the contents of the frame.
|
||||
*/
|
||||
private void initialize() {
|
||||
frame = new JFrame();
|
||||
frame.setBounds(100, 100, 800, 600);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setTitle("Fractal generator");
|
||||
Canvas panel = new Canvas();
|
||||
frame.addKeyListener(panel);
|
||||
frame.getContentPane().add(panel, BorderLayout.CENTER);
|
||||
|
||||
JMenuBar mainMenu = new JMenuBar();
|
||||
frame.getContentPane().add(mainMenu, BorderLayout.NORTH);
|
||||
|
||||
JMenu formula_menu = new JMenu("Formula");
|
||||
mainMenu.add(formula_menu);
|
||||
|
||||
JMenuItem mntmmandelbrot = new JMenuItem("Mandelbrot");
|
||||
formula_menu.add(mntmmandelbrot);
|
||||
|
||||
mntmmandelbrot.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
panel.paintMandel();
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem juliamntm = new JMenuItem("Julia");
|
||||
formula_menu.add(juliamntm);
|
||||
|
||||
juliamntm.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String arg = JOptionPane.showInputDialog("Enter arg0: ");
|
||||
String _arg = JOptionPane.showInputDialog("Enter arg1: ");
|
||||
if( arg != null && _arg != null ) {
|
||||
panel.paintJulia(arg, _arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem bshipmntm = new JMenuItem("Burning ship");
|
||||
formula_menu.add(bshipmntm);
|
||||
|
||||
bshipmntm.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
panel.paintBurningship();
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem cmmntm = new JMenuItem("Custom mandelbrot");
|
||||
formula_menu.add(cmmntm);
|
||||
|
||||
JMenu mnNewMenu = new JMenu("GUI");
|
||||
mainMenu.add(mnNewMenu);
|
||||
|
||||
JMenuItem mntmNewMenuItem = new JMenuItem("Choose");
|
||||
mnNewMenu.add(mntmNewMenuItem);
|
||||
|
||||
JMenu mnPos = new JMenu("Position");
|
||||
mainMenu.add(mnPos);
|
||||
|
||||
JMenuItem mntmRes = new JMenuItem("Reset");
|
||||
mnPos.add(mntmRes);
|
||||
|
||||
mntmRes.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
panel.setInterval(-2, 0.5, -1, 1, 1, 1);
|
||||
panel.repaint();
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem mntmPosJump = new JMenuItem("Jump into...");
|
||||
mnPos.add(mntmPosJump);
|
||||
|
||||
JMenu mnExport = new JMenu("Export");
|
||||
mainMenu.add(mnExport);
|
||||
|
||||
JMenuItem mntmExportPNG = new JMenuItem("Export to PNG");
|
||||
mnExport.add(mntmExportPNG);
|
||||
mntmExportPNG.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
BufferedImage image = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
panel.printAll(g);
|
||||
g.dispose();
|
||||
try {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setDialogTitle("Choose file");
|
||||
|
||||
int userSelection = fileChooser.showSaveDialog(frame);
|
||||
|
||||
if (userSelection == JFileChooser.APPROVE_OPTION) {
|
||||
ImageIO.write(image, "png", fileChooser.getSelectedFile());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mntmPosJump.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String arg = JOptionPane.showInputDialog("Enter Rez: ");
|
||||
String _arg = JOptionPane.showInputDialog("Enter Imz: ");
|
||||
String __arg = JOptionPane.showInputDialog("Enter zoom: ");
|
||||
if( arg != null && _arg != null && __arg != null ) {
|
||||
double centerX = Double.parseDouble(arg);
|
||||
double centerY = Double.parseDouble(_arg);
|
||||
double size = Double.parseDouble(__arg);
|
||||
panel.setInterval(centerX-size, centerX+size, centerY-size, centerY+size, 1, 1);
|
||||
panel.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mntmNewMenuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
GradientChoice dialog = new GradientChoice();
|
||||
dialog.setVisible(true);
|
||||
if( dialog.isOk ) {
|
||||
panel.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cmmntm.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String arg = JOptionPane.showInputDialog("Enter arg0: ");
|
||||
if( arg != null ) {
|
||||
panel.paintCustom(arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user