Created
September 29, 2010 09:26
-
-
Save Cellane/602494 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Cviceni1 { | |
public static void main (String[] args) { | |
new Form1 ().setVisible (true); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.*; | |
import java.awt.event.*; | |
import java.awt.image.BufferedImage; | |
import javax.swing.*; | |
public final class Form1 extends javax.swing.JFrame implements G_Controls { | |
public static int leftX, topY, rightX, bottomY; | |
public static G_Color foregroundColor = new G_Color (); | |
public static G_Point start = new G_Point (); | |
public static G_Point end = new G_Point (); | |
public static int activeTaskId = 0; | |
public static boolean allLocationsSet = false; | |
private static final long serialVersionUID = 1L; | |
private G_Graphics graphic; | |
private G_Canvas canvas; | |
private JMenuBar menuBar = new JMenuBar (); | |
private JMenu fileMenu = new JMenu ("File"); | |
private JToolBar toolBar = new JToolBar (); | |
private JButton pixelButton = new JButton (); | |
private JButton lineButton = new JButton (); | |
private JSeparator separator = new JSeparator (); | |
private JButton colorChooserButton = new JButton (); | |
private int[][] kernel;// = {{0, -1, 0}, {-1, 5, -1}, {0, -1, 0}}; | |
public Form1 () { | |
super (); | |
init (); | |
leftX = 0; | |
topY = 0; | |
rightX = canvas.getWidth () - 1; | |
bottomY = canvas.getHeight () - 1; | |
G_draw (); | |
} | |
public void G_draw () { | |
graphic.clear (); | |
G_repaint (); | |
} | |
public void G_mousePressed (G_Button button, int x, int y) { | |
G_ButtonPressed.buttonPressed (x, y); | |
G_repaint (); | |
} | |
public void G_mouseReleased (G_Button button, int x, int y) { | |
G_ButtonReleased.buttonReleased (x, y, graphic); | |
G_repaint (); | |
} | |
public void G_repaint () { | |
canvas.repaint (); | |
} | |
private void init () { | |
Action openMenuItem, closeMenuItem; | |
BufferedImage image; | |
int shortcutKeyMask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask (); | |
// JFrame | |
setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE); | |
this.setTitle ("Mion Painting Tool"); | |
this.setSize (800, 600); | |
this.setLocationRelativeTo (null); | |
// JMenu | |
openMenuItem = new openActionClass ("Open", | |
KeyStroke.getKeyStroke (KeyEvent.VK_O, shortcutKeyMask)); | |
closeMenuItem = new closeActionClass ("Close", | |
KeyStroke.getKeyStroke (KeyEvent.VK_W, shortcutKeyMask)); | |
fileMenu.add (new JMenuItem (openMenuItem)); | |
fileMenu.add (new JMenuItem (closeMenuItem)); | |
menuBar.add (fileMenu); | |
this.setJMenuBar (menuBar); | |
// JToolBar | |
pixelButton.setText ("Pixel"); | |
pixelButton.addActionListener (new pixelActionClass ()); | |
lineButton.setText ("Line"); | |
lineButton.addActionListener (new lineActionClass ()); | |
separator.setOrientation (1); | |
colorChooserButton.setText ("Color"); | |
colorChooserButton.addActionListener (new colorChooserActionClass ()); | |
toolBar.add (pixelButton); | |
toolBar.add (lineButton); | |
toolBar.add (separator); | |
toolBar.add (colorChooserButton); | |
toolBar.setFloatable (false); | |
getContentPane ().add (toolBar, BorderLayout.NORTH); | |
// BufferedImage | |
image = new BufferedImage (this.getSize ().width, this.getSize ().height, BufferedImage.TYPE_INT_RGB); | |
// graphic | |
graphic = new G_Graphics (image); | |
// canvas | |
canvas = new G_Canvas (image); | |
canvas.setPreferredSize (new Dimension (this.getSize ().width, this.getSize ().height)); | |
// content | |
getContentPane ().add (canvas, java.awt.BorderLayout.CENTER); | |
// mouse listener | |
canvas.addMouseListener (new MouseAdapter() { | |
public void mousePressed (MouseEvent evt) { | |
G_Button button = G_Button.B_NONE; | |
if (evt.getButton () == MouseEvent.BUTTON1) button = G_Button.B_LEFT; | |
if (evt.getButton () == MouseEvent.BUTTON2) button = G_Button.B_RIGHT; | |
G_mousePressed (button, evt.getX (), evt.getY ()); | |
} | |
public void mouseReleased (MouseEvent evt) { | |
G_Button button = G_Button.B_NONE; | |
if (evt.getButton () == MouseEvent.BUTTON1) button = G_Button.B_LEFT; | |
if (evt.getButton () == MouseEvent.BUTTON2) button = G_Button.B_RIGHT; | |
G_mouseReleased (button, evt.getX (), evt.getY ()); | |
} | |
}); | |
pack (); | |
} | |
public class openActionClass extends AbstractAction { | |
public openActionClass (String text, KeyStroke shortcut) { | |
super (text); | |
putValue (ACCELERATOR_KEY, shortcut); | |
} | |
public void actionPerformed (ActionEvent e) { | |
FileDialog fileDialog = new FileDialog (new Frame (), "Open File", | |
FileDialog.LOAD); | |
String file; | |
fileDialog.setVisible (true); | |
if (fileDialog.getFile () != null) { | |
file = fileDialog.getDirectory () + fileDialog.getFile (); | |
graphic.showImage (file); | |
G_repaint (); | |
} | |
} | |
} | |
public class closeActionClass extends AbstractAction { | |
public closeActionClass (String text, KeyStroke shortcut) { | |
super (text); | |
putValue (ACCELERATOR_KEY, shortcut); | |
} | |
public void actionPerformed (ActionEvent e) { | |
System.exit (0); | |
} | |
} | |
public class pixelActionClass implements ActionListener { | |
public void actionPerformed (ActionEvent e) { | |
activeTaskId = 0; | |
} | |
} | |
public class lineActionClass implements ActionListener { | |
public void actionPerformed (ActionEvent e) { | |
activeTaskId = 1; | |
} | |
} | |
private class colorChooserActionClass implements ActionListener { | |
public void actionPerformed (ActionEvent e) { | |
Color color = JColorChooser.showDialog (getContentPane (), "Choose color", getForeground ()); | |
if (color != null) { | |
foregroundColor.setR (color.getRed ()); | |
foregroundColor.setG (color.getGreen ()); | |
foregroundColor.setB (color.getBlue ()); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Graphics; | |
import java.awt.image.BufferedImage; | |
public class G_Canvas extends java.awt.Canvas { | |
private static final long serialVersionUID = 1L; | |
private BufferedImage bitmap; | |
G_Canvas (BufferedImage b) { | |
bitmap = b; | |
} | |
public void paint (Graphics g) { | |
bitmap.flush (); | |
g.drawImage (bitmap, 0, 0, this); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class G_Color { | |
public static G_Color G_cBlack = new G_Color (0, 0, 0); | |
public static G_Color G_cRed = new G_Color (255, 0, 0); | |
public static G_Color G_cGreen = new G_Color (0, 255, 0); | |
public static G_Color G_cBlue = new G_Color (0, 0, 255); | |
public static G_Color G_cYellow = new G_Color (255, 255, 0); | |
public static G_Color G_cWhite = new G_Color (255, 255, 255); | |
public int r; | |
public int g; | |
public int b; | |
public G_Color () { | |
} | |
public G_Color (int rc, int gc, int bc) { | |
r = rc; | |
g = gc; | |
b = bc; | |
} | |
public void setR (int r) { | |
this.r = r; | |
} | |
public void setG (int g) { | |
this.g = g; | |
} | |
public void setB (int b) { | |
this.b = b; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface G_Controls { | |
public void G_mousePressed (G_Button button, int x, int y); | |
public void G_mouseReleased (G_Button button, int x, int y); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.*; | |
import java.awt.image.BufferedImage; | |
import java.io.File; | |
import java.io.IOException; | |
import javax.imageio.ImageIO; | |
public class G_Graphics { | |
private BufferedImage bitmap; | |
private Graphics2D g; | |
public G_Graphics (BufferedImage b) { | |
bitmap = b; | |
g = bitmap.createGraphics (); | |
} | |
public void putPixel (int x, int y, G_Color color) { | |
Color colorHelp = new Color (color.r, color.g, color.b); | |
bitmap.setRGB (x, y, colorHelp.getRGB ()); | |
} | |
/** | |
* Public overloaded method that accepts raw color channel values as arguments, | |
* and stores result into specified bitmap | |
* | |
* @param x x-position of pixel | |
* @param y y-position of pixel | |
* @param r red channel value | |
* @param g green channel value | |
* @param b blue channel value | |
* @param image bitmap to store the pixel | |
*/ | |
public void putPixel (int x, int y, int r, int g, int b, BufferedImage image) { | |
Color color = new Color (r, g, b); | |
image.setRGB (x, y, color.getRGB ()); | |
} | |
/** | |
* Public method that grabs everything that's on canvas at the moment of method call | |
* and applies convolution edit on canvas using specified kernel; result is stored | |
* temporarily in new raster, and when the convolution is done, that raster is | |
* displayed to user | |
* | |
* @param kernel kernel used for convolution | |
*/ | |
public void convolution (int[][] kernel) { | |
BufferedImage bitmapHelp = new BufferedImage (bitmap.getWidth (), bitmap.getHeight (), | |
BufferedImage.TYPE_INT_RGB); | |
G_Color originalColor; | |
float finalRed, finalGreen, finalBlue; | |
int kernelCount; | |
kernelCount = kernelCount (kernel); | |
// We don't know how to deal with borders yet | |
for (int helpY = 1; helpY < (bitmap.getHeight () - 1); helpY++) { | |
for (int helpX = 1; helpX < (bitmap.getWidth () - 1); helpX++) { | |
finalRed = 0; | |
finalGreen = 0; | |
finalBlue = 0; | |
for (int y = -1, i = 0; y < 2; y++, i++) { | |
for (int x = -1, j = 0; x < 2; x++, j++) { | |
float temporary; | |
originalColor = getPixel (helpX + x, helpY + y); | |
temporary = kernel[i][j] / (float) kernelCount; | |
finalRed += (float) originalColor.r * temporary; | |
finalGreen += (float) originalColor.g * temporary; | |
finalBlue += (float) originalColor.b * temporary; | |
} | |
} | |
finalRed = fixColor (finalRed); | |
finalGreen = fixColor (finalGreen); | |
finalBlue = fixColor (finalBlue); | |
putPixel (helpX, helpY, (int) finalRed, (int) finalGreen, (int) finalBlue, bitmapHelp); | |
} | |
} | |
// Replace current canvas | |
g.drawImage (bitmapHelp, 0, 0, null); | |
} | |
/** | |
* Private method that calculates sum of values stored in kernel or matrix | |
* | |
* @param kernel kernel to count with | |
* @return sum of values stored in kernel | |
*/ | |
private int kernelCount (int[][] kernel) { | |
int kernelCount = 0; | |
for (int[] row : kernel) { | |
for (int element : row) { | |
kernelCount += element; | |
} | |
} | |
return (kernelCount); | |
} | |
/** | |
* Private method that does last-time correction of color channel values | |
* | |
* @param color color to fix | |
* @return fixed value | |
*/ | |
private float fixColor (float color) { | |
if (color > 255) { | |
color = 255; | |
} else if (color < 0) { | |
color = 0; | |
} | |
return (color); | |
} | |
/** | |
* Public method that fixes coordinates of a line using Cohen-Sutherland algorithm, | |
* then calls drawLineBresenham () method to draw the line with corrected coordinates | |
* TODO write an overloaded method that allows the user to create own clipping mask, | |
* TODO then move this algorithm into that overloaded method | |
* | |
* @param startX x coordinate of start point | |
* @param startY y coordinate of start point | |
* @param endX x coordinate of end point | |
* @param endY y coordinate of end point | |
* @param color color of painted line | |
*/ | |
public void drawLine (int startX, int startY, int endX, int endY, G_Color color) { | |
int codeStart, codeEnd; | |
boolean accept; | |
codeStart = generateCode (startX, startY); | |
codeEnd = generateCode (endX, endY); | |
accept = false; | |
while (true) { | |
if ((codeStart == 0) && (codeEnd == 0)) { | |
accept = true; | |
break; | |
} else if ((codeStart & codeEnd) != 0) { | |
break; | |
} else { | |
boolean codeWhich; | |
int workX, workY, codeWork; | |
// if start code isn't 0 –> true, we're working with start point | |
// if start code is 0 –> false, we're working with end point | |
codeWhich = (codeStart != 0); | |
if (codeWhich) { | |
codeWork = codeStart; | |
workX = startX; | |
workY = startY; | |
} else { | |
codeWork = codeEnd; | |
workX = endX; | |
workY = endY; | |
} | |
if ((codeWork & 1) != 0) { | |
workY = ((endY - startY) / (endX - startX)) * (Form1.leftX - workX) + workY; | |
workX = Form1.leftX; | |
} else if ((codeWork & 2) != 0) { | |
workY = ((endY - startY) / (endX - startX)) * (Form1.rightX - workX) + workY; | |
workX = Form1.rightX; | |
} else if ((codeWork & 4) != 0) { | |
workX = ((endX - startX) / (endY - startX)) * (Form1.bottomY - workY) + workX; | |
workY = Form1.bottomY; | |
} else if ((codeWork & 8) != 0) { | |
workX = ((endX - startX) / (endY - startX)) * (Form1.topY - workY) + workX; | |
workY = Form1.topY; | |
} | |
if (codeWork == codeStart) { | |
startX = workX; | |
startY = workY; | |
codeStart = generateCode (startX, startY); | |
} else { | |
endX = workX; | |
endY = workY; | |
codeEnd = generateCode (endX, endY); | |
} | |
} | |
} | |
if (accept) { | |
drawLineBresenham (startX, startY, endX, endY, color); | |
} | |
} | |
/** | |
* Generates code required for clipping for given point | |
* 1 = left | |
* 2 = right | |
* 4 = bottom | |
* 8 = top | |
* | |
* @param x x coordinate of given point | |
* @param y y coordinate of given point | |
* @return calculated code | |
*/ | |
private int generateCode (int x, int y) { | |
int code = 0; | |
if (x < Form1.leftX) { | |
code += 1; | |
} else if (x > Form1.rightX) { | |
code += 2; | |
} | |
if (y > Form1.bottomY) { | |
code += 4; | |
} else if (y < Form1.topY) { | |
code += 8; | |
} | |
return (code); | |
} | |
/** | |
* Private method that draws a line with given start & end coordinates, | |
* using Bresenham algorithm | |
* This method should be never called directly; call drawLine () instead! | |
* | |
* @param startX x coordinate of start point | |
* @param startY y coordinate of start point | |
* @param endX x coordinate of end point | |
* @param endY y coordinate of end point | |
* @param color color of painted line | |
*/ | |
private void drawLineBresenham (int startX, int startY, int endX, int endY, G_Color color) { | |
int dY = endY - startY; | |
int dX = endX - startX; | |
int fraction, stepX, stepY; | |
if (dY < 0) { | |
dY = -dY; | |
stepY = -1; | |
} else { | |
stepY = 1; | |
} | |
if (dX < 0) { | |
dX = -dX; | |
stepX = -1; | |
} else { | |
stepX = 1; | |
} | |
dY = 2 * dY; | |
dX = 2 * dX; | |
putPixel (startX, startY, color); | |
if (dX > dY) { | |
fraction = (2 * dY) - dX; | |
while (startX != endX) { | |
if (fraction >= 0) { | |
startY += stepY; | |
fraction -= dX; | |
} | |
startX += stepX; | |
fraction += dY; | |
putPixel (startX, startY, color); | |
} | |
} else { | |
fraction = (2 * dX) - dY; | |
while (startY != endY) { | |
if (fraction >= 0) { | |
startX += stepX; | |
fraction -= dY; | |
} | |
startY += stepY; | |
fraction += dX; | |
putPixel (startX, startY, color); | |
} | |
} | |
} | |
/** | |
* Public method that draws a rectangle using drawLine () method | |
* @param startX top left X-coordinate | |
* @param startY top left Y-coordinate | |
* @param endX bottom right X-coordinate | |
* @param endY bottom right Y-coordinate | |
* @param color color of the line | |
*/ | |
public void drawRectangle (int startX, int startY, int endX, int endY, G_Color color) { | |
drawLine (startX, startY, startX, endY, color); | |
drawLine (startX, startY, endX, startY, color); | |
drawLine (endX, endY, startX, endY, color); | |
drawLine (endX, endY, endX, startY, color); | |
} | |
/** | |
* Public method that draws a triangle using drawLine () method | |
* @param aX X-coordinate of the first point | |
* @param aY Y-coordinate of the first point | |
* @param bX X-coordinate of the second point | |
* @param bY Y-coordinate of the second point | |
* @param cX X-coordinate of the third point | |
* @param cY Y-coordinate of the third point | |
* @param color color of the line | |
*/ | |
public void drawTriangle (int aX, int aY, int bX, int bY, int cX, int cY, G_Color color) { | |
drawLine (aX, aY, bX, bY, color); | |
drawLine (bX, bY, cX, cY, color); | |
drawLine (cX, cY, aX, aY, color); | |
} | |
public void drawPolygon (G_Point[] coordinates, G_Color color) { | |
for (int i = 0; i < coordinates.length - 1; i++) { | |
drawLine (coordinates[i].x, coordinates[i].y, coordinates[i + 1].x, coordinates[i + 1].y, color); | |
} | |
drawLine (coordinates[coordinates.length - 1].x, coordinates[coordinates.length - 1].y, coordinates[0].x, | |
coordinates[0].y, color); | |
} | |
public void drawPolygon (G_Point3[] coordinates, G_Color color) { | |
} | |
public void movePolygon (G_Point[] coordinates, G_Color color, int moveX, int moveY) { | |
for (G_Point coordinate : coordinates) { | |
coordinate.x += moveX; | |
coordinate.y += moveY; | |
} | |
drawPolygon (coordinates, color); | |
} | |
public void scalePolygon (G_Point[] coordinates, G_Color color, float factor) { | |
for (G_Point coordinate : coordinates) { | |
coordinate.x *= factor; | |
coordinate.y *= factor; | |
} | |
drawPolygon (coordinates, color); | |
} | |
public void geometryFill (int startX, int startY, int endX, int endY, G_Color color) { | |
for (int i = startY; i <= endY; i++) { | |
drawLine (startX, i, endX, i, color); | |
} | |
} | |
public void fill (int x, int y, G_Color targetColor, G_Color borderColor) { | |
int r, g, b; | |
r = getPixel (x, y).r; | |
g = getPixel (x, y).g; | |
b = getPixel (x, y).b; | |
if (((r != targetColor.r) && (r != borderColor.r)) || | |
((g != targetColor.g) && (g != borderColor.g)) || | |
((b != targetColor.b) && (b != borderColor.b))) { | |
putPixel (x, y, targetColor); | |
fill (x + 1, y, targetColor, borderColor); | |
fill (x - 1, y, targetColor, borderColor); | |
fill (x, y + 1, targetColor, borderColor); | |
fill (x, y - 1, targetColor, borderColor); | |
} | |
} | |
public int move (int coordination, int movement) { | |
return (coordination + movement); | |
} | |
public G_Color getPixel (int x, int y) { | |
Color colorHelp = new Color (bitmap.getRGB (x, y)); | |
G_Color color = new G_Color (); | |
color.r = colorHelp.getRed (); | |
color.g = colorHelp.getGreen (); | |
color.b = colorHelp.getBlue (); | |
return (color); | |
} | |
public void clear () { | |
g.setBackground (new Color (255, 255, 255)); | |
g.clearRect (0, 0, bitmap.getWidth (), bitmap.getHeight ()); | |
} | |
public void showImage (String path) { | |
try { | |
BufferedImage bitmapHelp = (BufferedImage) ImageIO.read (new File (path)); | |
g.drawImage (bitmapHelp, 0, 0, null); | |
} catch (IOException e) { | |
e.printStackTrace (); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class G_Point { | |
protected int x, y; | |
public G_Point () { | |
this (0, 0); | |
} | |
public G_Point (int x, int y) { | |
this.x = x; | |
this.y = y; | |
} | |
public int getX () { | |
return (x); | |
} | |
public void setX (int x) { | |
this.x = x; | |
} | |
public int getY () { | |
return (y); | |
} | |
public void setY (int y) { | |
this.y = y; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment