I have two classes in my project, Client and Card. When I try to import an image into the Card class, the paintComponent method in the client does not start. The timer still fires, and and outputs after repaint in the timer listener still print. The cause of this problem appears to be the try catch in the constructor of the card.
package card;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Card {
BufferedImage cardImage;
Point loc = new Point(50, 50);
int scale = 1;
public Card(){
try {
cardImage = ImageIO.read(new File("Penguins.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void draw(Graphics2D g2){
g2.setColor(Color.GRAY);
if(cardImage == null)
g2.fillRect(loc.x, loc.y, 150, 225);
else
g2.drawImage(cardImage, loc.x, loc.y, 50, 150, null);
}
}
New class
package core;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import card.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Client extends JPanel {
ArrayList<Card>[] board;
Card card;
Timer timer;
static Client player;
public static void main(String[] args) {
JFrame window = new JFrame("Game");
window.setSize(1080, 720);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setVisible(true);
window.setLocation(50, 50);
window.setBackground(Color.GREEN);
player = new Client();
window.setContentPane(player);
}
public Client() {
//board = new ArrayList<Card>[4];
card = new Card();
ActionListener game = new TimerListener();
timer = new Timer(100, game);
timer.start();
}
public class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
repaint();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(5));
g2.drawOval(15, 75, 200, 200);
g2.drawOval(15, 350, 200, 200);
g2.drawRoundRect(355, -10, 450, 60, 15, 15);
g2.drawRoundRect(230, 75, 700, 90, 20, 20);
g2.drawRoundRect(230, 190, 700, 90, 20, 20);
g2.drawRoundRect(230, 350, 700, 90, 20, 20);
g2.drawRoundRect(230, 475, 700, 90, 20, 20);
g2.drawRoundRect(355, 590, 450, 90, 15, 15);
g2.drawRoundRect(950, 75, 90, 90, 10, 10);
g2.drawRoundRect(950, 190, 90, 90, 10, 10);
g2.drawRoundRect(950, 350, 90, 90, 10, 10);
g2.drawRoundRect(950, 475, 90, 90, 10, 10);
card.draw(g2);
}
}
Related
I tried, adding the flowlayout as seen in other answers, but it still doesn't work.
I've also tried moving around my JLabel code into a constructor but that doesn't work either.
public class Paint {
public static void main(String[] args) {
JFrame frame = new JFrame("Paint");
frame.setSize(500,500);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
Draw draw = new Draw();
frame.add(draw);
frame.setVisible(true);
}
}
public class Draw extends JPanel{
public Draw(){
JLabel one = new JLabel("12",JLabel.CENTER);
setLayout(new FlowLayout());
add(one);
}
public void paint(Graphics g){
g.drawOval(70, 60, 190, 190);
g.setColor(Color.BLACK);
g.drawLine(90, 160, 170, 160);
g.drawLine(120, 190,170 , 160);
g.setColor(Color.GRAY);
g.fillOval(155, 153, 20, 20);
}
}
Change paint to override paintComponent
Call super.paintComponent before doing any custom painting
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Paint {
public static void main(String[] args) {
JFrame frame = new JFrame("Paint");
frame.setSize(500, 500);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
Draw draw = new Draw();
frame.add(draw);
frame.setVisible(true);
}
public static class Draw extends JPanel {
public Draw() {
JLabel one = new JLabel("12", JLabel.CENTER);
setLayout(new FlowLayout());
add(one);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(70, 60, 190, 190);
g.setColor(Color.BLACK);
g.drawLine(90, 160, 170, 160);
g.drawLine(120, 190, 170, 160);
g.setColor(Color.GRAY);
g.fillOval(155, 153, 20, 20);
}
}
}
so I have been make a JFrame background transparent by setting the background alpha to 0, however if I run the program in linux the JFrame background is white why is this?
ok I found its got something to do with rendering graphics to the frame, this method is old I don't need it in the program anymore but i would still like to know why this happens (its just in Linux works find in windows)
here is a runnable example
import java.awt.*;
import java.awt.Color;
import javax.swing.*;
class Main extends JFrame{
private void init() {
this.setPreferredSize(new Dimension(1420, 820));
this.setUndecorated(true);
this.setResizable(false);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.setBackground(new Color(0, 255, 0, 0));
this.requestFocus();
this.setVisible(true);
this.validate();
this.pack();
Color color = UIManager.getColor("activeCaptionBorder");
this.getRootPane().setBorder(BorderFactory.createLineBorder(color, 1));
paintInfo();
}
private void paintInfo() {
Graphics g = this.getGraphics();
g.setColor(new Color(222, 222, 222, 4));
g.setFont(new Font("Arial Black", Font.BOLD, 15));
g.setColor(Color.BLACK);
g.drawString("test String ",this.getWidth()/2, this.getHeight()/2);
g.dispose();
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
new Main().init();
}
}
Let's start with...
private void paintInfo() {
Graphics g = this.getGraphics();
g.setColor(new Color(222, 222, 222, 4));
g.setFont(new Font("Arial Black", Font.BOLD, 15));
g.setColor(Color.BLACK);
g.drawString("test String ",this.getWidth()/2, this.getHeight()/2);
g.dispose();
}
Isn't how painting is done in Swing and disposing of a Graphics context you didn't create will lead to manner of strange things...
Instead, create your frame, set up it's transparency and then add another component to it, which does the actual painting that you want, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
/**
*
* #author swhitehead
*/
public class JavaApplication233 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
GraphicsEnvironment ge
= GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
//If translucent windows aren't supported, exit.
if (!gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
System.err.println("Per-pixel translucency is not supported");
System.exit(0);
} else {
new JavaApplication233();
}
}
public JavaApplication233() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
setLayout(new GridBagLayout());
add(new JLabel("I'm not wearing anything"));
// Color color = UIManager.getColor("activeCaptionBorder");
setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
LinearGradientPaint lgp = new LinearGradientPaint(
new Point(0, 0),
new Point(0, getHeight()),
new float[]{0f, 1f},
new Color[]{applyAlpha(Color.RED), applyAlpha(Color.YELLOW)}
);
g2d.setPaint(lgp);
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
g2d.dispose();
}
protected Color applyAlpha(Color color) {
return new Color(color.getRed(), color.getGreen(), color.getBlue(), 64);
}
}
}
I am trying to write a program for class and I am stuck. I need to create a shape (my initial) and then fill it with it JColorChooser. I have been able to create my initial using paint, and graphics. Then I have been able to fill my shape by using g.setColor(new Color(11, 139, 198)); I don't know how to add a JColorChooser to this. This is my first post so let me know whatever I can do to make it easier to read.
Here is my code:
/* Program - Letter
* Program Desc -
* Programmer - Bradon Fredrickson
* Class -
* Created - Oct 1, 2014
*/
package letter;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Letter
{
public static void PlainLetter()
{
/*
* Creating GUI for letter
*/
LetterDraw plainLetter = new LetterDraw();
JFrame logo = new JFrame("My Logos");
JLabel plain = new JLabel("Plain Letter");
plain.setLocation(10, 0);
plain.add(plainLetter);
Container pane = logo.getContentPane();
pane.setLayout(new GridLayout(1, 1));
logo.setLocationRelativeTo(null); // Center the frame
logo.add(plainLetter);
logo.setVisible(true);
logo.setSize(400, 200);
logo.setLocation(400, 200);
logo.setVisible(true);
logo.setDefaultCloseOperation(logo.EXIT_ON_CLOSE);
}//end plain letter
public static void main(String[] args)
{
PlainLetter();
new ColorChooser();
}//end main method
}//end Letter
Second class - this is drawing my object
/* Program - ThirdLetter
* Program Desc -
* Programmer - Bradon Fredrickson
* Class -
* Created - Oct 6, 2014
*/
package letter;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.JPanel;
public class LetterDraw extends JPanel
{
/*
* Creating my shape/letter
*/
public void paint(Graphics graphics)
{
Path2D.Double path = new Path2D.Double();
Graphics2D g = (Graphics2D) graphics;
path.moveTo(17, 63);
/*
* Top Horizontal Line
*/
path.curveTo(21, 60, 21, 43, 17, 37); //left vert
path.curveTo(30, 43, 100, 43, 120, 37); //top horiz
path.curveTo(115, 45, 115, 57, 117, 62); //right vert
path.curveTo(105, 53, 60, 57, 17, 63); //bottom horiz right
/*
* Bottom Horizontal Line
*/
path.moveTo(32, 97);
path.curveTo(37, 85, 35, 79, 35, 77); //left vert
path.curveTo(45, 79, 45, 79, 100, 79); //top left horiz
path.curveTo(96, 85, 98, 92, 98, 98);//right vert
path.curveTo(89, 93, 79, 94, 32, 97);//bottom right horiz
/*
* Vertical Line
*/
path.moveTo(40, 130);
path.curveTo(48, 110, 46, 70, 37, 55); //left vert
path.curveTo(62, 55, 62, 55, 60, 55); //top horiz
path.curveTo(68, 80, 68, 100, 63, 130); //right vert
path.curveTo(60, 127, 50, 127, 40, 130);//bottom horiz
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(3));
//g.setStroke(new BasicStroke(4, BasicStroke.JOIN_BEVEL, 0));
g.draw(path);
g.setColor(new Color(11, 139, 198));
g.fill(path);
}//end paint
}//end LetterDraw
third - this is my colorChooser
/* Program - ColorChooser
* Program Desc -
* Programmer - Bradon Fredrickson
* Class -
* Created - Oct 10, 2014
*/
package letter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ColorChooser
{
/**
* Creating the color chooser
*/
public ColorChooser()
{
JFrame frame = new JFrame("JColorChooser Popup");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLabel label = new JLabel("www.java2s.com", JLabel.CENTER);
label.setFont(new Font("Serif", Font.BOLD | Font.ITALIC, 48));
frame.add(label, BorderLayout.NORTH);
final JColorChooser colorChooser = new JColorChooser(label.
getBackground());
ColorSelectionModel model = colorChooser.getSelectionModel();
ChangeListener changeListener = new ChangeListener()
{
public void stateChanged(ChangeEvent changeEvent)
{
Color newForegroundColor = colorChooser.getColor();
label.setForeground(newForegroundColor);
}
};
model.addChangeListener(changeListener);
frame.add(colorChooser, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}//end colorChooser
}//end colorChooser class
Right now i get to 2 JFrames 1 for my shape and 1 for the JColorChooser. I would like to put them all in 1 frame also.
In your LetterDraw class, instead of doing
g.setColor(new Color(11, 139, 198));
better to have a class member Color color, and have a setter for it. Then do just do this
public class LetterDraw extends JPanel {
private Color color = Color.BLUE; // default;
public void setColor(Color color) {
this.color = color;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
...
g.setColor(color);
}
}
Notice the paintComponent and super.paintComponent. See link from #trashgod in comments.
As for the color selection, JColorChooser has a static method, from which you can call to show a color chooser dialog and obtain a returned color from. You can then use that color to call setColor on the LetterDraw. No need to create your own frame. For instance.
Color color = JColorChooser.showDialog(null, "title", Color.BLUE);
letterDraw.setColor(color);
If you want to keep the color chooser frame open though and have the , using your current code, You would need to either use some kind of MVC/Observer design, or pass the instance of LetterDraw to the ColorChooser constructor, so that it can call LetterDraw's set color method, after it changes color.
"I would like to put them all in 1 frame also"
I just noticed that part of the question.
You could forget that ColorChooser class all together and create the JColorChooser in the Letter class. So you have access to the LetterDraw object. Here's how a refactor might look
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Letter {
LetterDraw letterDraw = new LetterDraw();
public Letter() {
JFrame frame = new JFrame();
JPanel letterDrawWrapper = new JPanel(new GridBagLayout());
letterDrawWrapper.add(letterDraw);
frame.add(letterDrawWrapper);
frame.add(createColorChooser(), BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JColorChooser createColorChooser() {
JColorChooser colorChooser = new JColorChooser();
colorChooser.getSelectionModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
letterDraw.setColor(colorChooser.getColor());
}
});
return colorChooser;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Letter();
}
});
}
}
class LetterDraw extends JPanel {
private Color color;
public void setColor(Color color) {
this.color = color;
repaint();
}
#Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Path2D.Double path = new Path2D.Double();
Graphics2D g = (Graphics2D) graphics;
path.moveTo(17, 63);
/*
* Top Horizontal Line
*/
path.curveTo(21, 60, 21, 43, 17, 37); //left vert
path.curveTo(30, 43, 100, 43, 120, 37); //top horiz
path.curveTo(115, 45, 115, 57, 117, 62); //right vert
path.curveTo(105, 53, 60, 57, 17, 63); //bottom horiz right
/*
* Bottom Horizontal Line
*/
path.moveTo(32, 97);
path.curveTo(37, 85, 35, 79, 35, 77); //left vert
path.curveTo(45, 79, 45, 79, 100, 79); //top left horiz
path.curveTo(96, 85, 98, 92, 98, 98);//right vert
path.curveTo(89, 93, 79, 94, 32, 97);//bottom right horiz
/*
* Vertical Line
*/
path.moveTo(40, 130);
path.curveTo(48, 110, 46, 70, 37, 55); //left vert
path.curveTo(62, 55, 62, 55, 60, 55); //top horiz
path.curveTo(68, 80, 68, 100, 63, 130); //right vert
path.curveTo(60, 127, 50, 127, 40, 130);//bottom horiz
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(3));
//g.setStroke(new BasicStroke(4, BasicStroke.JOIN_BEVEL, 0));
g.draw(path);
g.setColor(color);
g.fill(path);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
}
I am currently trying to draw a figure by clicking a button. My problems occurs when I click the button and it does not show up in the panel, but I know it's drawing because it runs through the loop.
The drawing will occur when I request the panel to draw it inside the constructor, but not inside the button, inside the constructor
If i put the code in the method "stuff()" inside the constructor it will draw everything just fine.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame{
public static void main(String[]args){
MainFrame f = new MainFrame();
}
public JFrame frame = new JFrame();
public JPanel panel = new JPanel(new BorderLayout());
public MainFrame(){
JButton button1 = new JButton("Shweet Button");
button1.setBounds(185, 10, 130, 20);
frame.setBounds(1680/4,1050/4,500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(panel);
panel.setBackground(Color.black);
frame.setVisible(true);
frame.getContentPane().setLayout(null);
frame.add(button1);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stuff();
}
});
}
public void stuff(){
for(int i = 0;i<1000;i++){
panel.add(new paintComponent());
panel.setBackground(Color.black);
frame.repaint();
try {
Thread.sleep(80);
} catch (InterruptedException e1){e1.printStackTrace();}
}
}
static class paintComponent extends JComponent{
public int options;
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.white);
if(options == 0){
options = 1;
g2.drawOval(50, (JFrame.HEIGHT/2)+100, 50, 50);
g2.drawOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
g2.fillOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
g2.drawOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
g2.fillOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
g2.drawArc(65, (JFrame.HEIGHT/2)+130, 100, 0, 140, 30);
g2.drawLine(75, (JFrame.HEIGHT/2)+150, 75, (JFrame.HEIGHT/2)+220);
g2.drawLine(75, (JFrame.HEIGHT/2)+180, 100, (JFrame.HEIGHT/2)+160);
g2.drawLine(75, (JFrame.HEIGHT/2)+180, 65, (JFrame.HEIGHT/2)+210);
g2.drawLine(75, (JFrame.HEIGHT/2)+220, 50, (JFrame.HEIGHT/2)+260);
g2.drawLine(75, (JFrame.HEIGHT/2)+220, 100, (JFrame.HEIGHT/2)+260);
}else if(options == 1){
options = 0;
g2.drawOval(50, (JFrame.HEIGHT/2)+100, 50, 50);
g2.drawOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
g2.fillOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
g2.drawOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
g2.fillOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
g2.drawArc(65, (JFrame.HEIGHT/2)+130, 100, 0, 140, 30);
g2.drawLine(75, (JFrame.HEIGHT/2)+150, 75, (JFrame.HEIGHT/2)+220);
g2.drawLine(75, (JFrame.HEIGHT/2)+180, 100, (JFrame.HEIGHT/2)+180);
g2.drawLine(75, (JFrame.HEIGHT/2)+180, 65, (JFrame.HEIGHT/2)+210);
g2.drawLine(75, (JFrame.HEIGHT/2)+220, 50, (JFrame.HEIGHT/2)+260);
g2.drawLine(75, (JFrame.HEIGHT/2)+220, 100, (JFrame.HEIGHT/2)+260);
}
}
}
}
You are blocking the Event Dispatching Thread, which is responsible for, amongst other things, processing paint requests.
You should never do anything like this...
for(int i = 0;i<1000;i++){
panel.add(new paintComponent());
panel.setBackground(Color.black);
frame.repaint();
try {
Thread.sleep(80);
} catch (InterruptedException e1){e1.printStackTrace();}
}
Within the EDT. Apart from the fact you are adding multiple new components to your UI every 80 milliseconds, you are also blocking the thread that is responsible for updating your screen...
Check out Concurrency in Swing for more details.
Animation of this type should be handled by a javax.swing.Timer.
Custom painting should be performed in the paintComponent method, as a general rule. You should also be calling super.paintXxx first as a matter of course. There's a lot of working going in the background that needs to be taken care of, especially if the component is transparent.
Check out Performing Custom Painting and Painting in AWT and Swing for more details.
Save your sanity and learn how to use layout managers, they will make your life easier in the long run.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MainFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
MainFrame f = new MainFrame();
}
});
}
public JFrame frame = new JFrame();
public JPanel panel = new JPanel(new BorderLayout());
private WavePane waver;
public MainFrame() {
waver = new WavePane();
JButton button1 = new JButton("Shweet Button");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
panel.setBackground(Color.black);
frame.add(button1, BorderLayout.SOUTH);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stuff();
}
});
panel.add(waver);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void stuff() {
// for (int i = 0; i < 1000; i++) {
// panel.add(new paintComponent());
// panel.setBackground(Color.black);
// frame.repaint();
// try {
// Thread.sleep(80);
// } catch (InterruptedException e1) {
// e1.printStackTrace();
// }
// }
waver.walk(!waver.isWaving());
}
public class WavePane extends JComponent {
private int options;
private Timer timer;
public WavePane() {
setOpaque(false);
timer = new Timer(80, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("tick");
options++;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void walk(boolean walk) {
if (walk) {
timer.start();
} else {
timer.stop();
}
}
public boolean isWaving() {
return timer.isRunning();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.white);
int height = getHeight();
if (options % 2 == 0) {
g2.drawOval(50, 100, 50, 50);
g2.drawOval(60, 110, 8, 8);
g2.fillOval(60, 110, 8, 8);
g2.drawOval(80, 110, 8, 8);
g2.fillOval(80, 110, 8, 8);
g2.drawArc(65, 130, 100, 0, 140, 30);
g2.drawLine(75, 150, 75, 220);
g2.drawLine(75, 180, 100, 160);
g2.drawLine(75, 180, 65, 210);
g2.drawLine(75, 220, 50, 260);
g2.drawLine(75, 220, 100, 260);
} else {
g2.drawOval(50, 100, 50, 50);
g2.drawOval(60, 110, 8, 8);
g2.fillOval(60, 110, 8, 8);
g2.drawOval(80, 110, 8, 8);
g2.fillOval(80, 110, 8, 8);
g2.drawArc(65, 130, 100, 0, 140, 30);
g2.drawLine(75, 150, 75, 220);
g2.drawLine(75, 180, 100, 180);
g2.drawLine(75, 180, 65, 210);
g2.drawLine(75, 220, 50, 260);
g2.drawLine(75, 220, 100, 260);
}
}
}
}
You shouldn't be using JFrame.HEIGHT this actually has nothing to do with the frames height, but is part of the ImageObserver support... or any type of magic number for that matter
Is there a way to duplicate a generalpath, mirror it, and move it?
I was creating a cartoon character, and I realized her left side of the hair, body is the same as the right side.
For example:
I have done the left part of her hair and body and the code is very long.
So to finish the character faster, I thought maybe there is a way of duplicating the code, flip it horizontally and move it to the right position.
I have this sample code:
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
GeneralPath body, mirror;
body = new GeneralPath();
mirror = new GeneralPath();
body.moveTo(205.5,97);
body.lineTo(207,132);
body.quadTo(193,105, 197,80);
body.curveTo(188,98, 156,127, 159,167);
body.quadTo(163,174, 166,184);
body.curveTo(173,196, 193,210, 213,208);
body.curveTo(247,208, 267,196, 274,184);
g2d.setPaint(new Color(255,251,223));
g2d.fill(body);
g2d.setPaint(Color.black);
g2d.draw(body);
//mirror = duplicate(body)
//flip(mirror)
//mirror.moveTo(x,y)
//..something like that
}
You can use a transformation. See Transforming Shapes, Text, and Images tutorial for some examples.
Here is an example based on the original code in the question:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JPanel panel = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 300);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponents(g);
final Graphics2D g2d = (Graphics2D) g.create();
try {
GeneralPath body, mirror;
body = new GeneralPath();
mirror = new GeneralPath();
body.moveTo(205.5, 97);
body.lineTo(207, 132);
body.quadTo(193, 105, 197, 80);
body.curveTo(188, 98, 156, 127, 159, 167);
body.quadTo(163, 174, 166, 184);
body.curveTo(173, 196, 193, 210, 213, 208);
body.curveTo(247, 208, 267, 196, 274, 184);
g2d.setPaint(new Color(255, 251, 223));
g2d.fill(body);
g2d.setPaint(Color.black);
g2d.draw(body);
AffineTransform tx = AffineTransform
.getScaleInstance(-1, 1);
tx.translate(-274 * 2, 0);
g2d.transform(tx);
g2d.setPaint(Color.YELLOW);
g2d.fill(body);
g2d.setPaint(Color.BLACK);
g2d.draw(body);
} finally {
g2d.dispose();
}
}
};
JOptionPane.showMessageDialog(null, panel, "Mirror",
JOptionPane.INFORMATION_MESSAGE);
}
});
}
}
The result looks like this: