Creating object of the class with paint method - java

I created a menu with some options to choose. One of those options is "Play with computer" which starts the game.
JButton ai = new JButton("Play with computer");
ai.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
GameBoard play = new GameBoard();
hi.dispose(); //jframe
}
});
And then comes GameBoard:
#SuppressWarnings("serial")
public class GameBoard extends Canvas {
private Image dbi;
private Graphics db;
private JFrame okno;
Rectangle aiPaddle = new Rectangle(10, 590, 10, 50);
Rectangle pPaddle = new Rectangle(10, 100, 10, 50);
Rectangle ball = new Rectangle(560, 10, 10, 10);
Player p = new Player(this);
Ai a = new Ai(this);
Ball b = new Ball(this);
GameBoard() {
okno = new JFrame();
okno.setTitle("Pink Ponk");
okno.setSize(600, 300);
okno.getContentPane().setBackground(Color.black);
okno.setResizable(false);
okno.setVisible(true);
okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(p);
}
public static void main(String[] args) {
GameBoard gra = new GameBoard();
gra.okno.add(gra);
}
#Override
public void update(Graphics g) {
dbi = createImage(10, 50);
db = dbi.getGraphics();
paint(db);
g.clearRect(0, 0, 600, 300);
g.setColor(Color.white);
g.drawRect(p.getX(), p.getY(), 10, 50);
g.fillRect(p.getX(), p.getY(), 10, 50);
g.drawOval(b.getX(), b.getY(), 10, 10);
g.fillOval(b.getX(), b.getY(), 10, 10);
g.drawRect(a.getX(), a.getY(), 10, 50);
g.fillRect(a.getX(), a.getY(), 10, 50);
}
#Override
public void paint(Graphics g) {
pPaddle = new Rectangle(p.getX(), p.getY(), 10, 50);
aiPaddle = new Rectangle(a.getX(), a.getY(), 10, 50);
ball = new Rectangle(b.getX(), b.getY(), 10, 10);
g.clearRect(0, 0, 600, 300);
g.setColor(Color.white);
g.drawRect(p.getX(), p.getY(), 10, 50);
g.fillRect(p.getX(), p.getY(), 10, 50);
g.drawOval(b.getX(), b.getY(), 10, 10);
g.fillOval(b.getX(), b.getY(), 10, 10);
g.drawRect(a.getX(), a.getY(), 10, 50);
g.fillRect(a.getX(), a.getY(), 10, 50);
}
}
I'm sure it should work, but it does not. I'm getting black screen, without any rectangles or ovals. Threads from other classes are working, because I'm still losing the game. :)

The GameBoard constructor, which is the only thing you call when your start button is pressed, creates a new frame, sets its background, and makes it visible. But it doens't add any component to the frame. You probably need to add
okno.add(this);
Note that it's not really the responsibility of the constructor of your Canvas to display a frame and add itself to this frame, though. I would move the frame creation outside of the constructor. Let the constructor do what it's supposed to do: construct the object.

Related

why when i add a for loop my jframe turns black?

I am trying to make a flashing light in my jframe by creating a list of the colors and then cycling through them with a for loop and then repainting. but when I add a for loop to my code the whole thing bugs out and I get a black screen and it frezzes. Why is this happening?
public class bb {
static Color colors[] = {Color.ORANGE, Color.GRAY};
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(400, 525);
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
JButton smallerButton = new JButton("Flash");
JButton largerButton = new JButton("Steady");
JPanel southPanel = new JPanel();
southPanel.add(smallerButton);
southPanel.add(largerButton);
frame.add(southPanel, BorderLayout.SOUTH);
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(180, 110, 10, 30);
g.drawRect(180, 140, 9, 30);
g.fillRect(180, 170, 10, 30);
g.drawRect(180, 200, 9, 30);
g.fillRect(180, 230, 10, 30);
g.drawRect(180, 260, 9, 30);
g.fillRect(180, 290, 10, 30);
g.drawRect(180, 310, 9, 30);
g.fillRect(180, 340, 10, 30);
int i = 0;
g.setColor(colors[i]);
for(i=0; i <= colors.length; i++){
g.fillOval(160, 70, 50, 50);
if (i ==colors.length){
i=0;
}
frame.repaint();
}
smallerButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals("Flash")){
}
}
});
}
};
frame.add(panel);
frame.validate();
}
}
This statement resets your loop index to 0 causing it to loop indefinitely blocking the EDT
if (i == colors.length) {
i = 0;
}
since you exceed the last array index in the for statement.
Take a look at using a Swing Timer to achieve this functionality.

What is wrong with my listener?

I have created the interface gui and added the buttons. But now I am stuck with the "Steady" button. When I click it I want to the circle "light bulb" to change color from yellow to orange.
What am I doing wrong in my code and when I press the "Steady" button nothing is happening?
/**
* Created by Metallion on 30/03/2015.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
public class BelishaBeacon {
public class Drawing extends JPanel {
private int x = 125;
private int y = 80;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//creating the shapes
Rectangle box1 = new Rectangle(165, 180, 20, 45);
Rectangle box2 = new Rectangle(165, 225, 20, 45);
Rectangle box3 = new Rectangle(165, 270, 20, 45);
Rectangle box4 = new Rectangle(165, 315, 20, 45);
Rectangle box5 = new Rectangle(165, 360, 20, 45);
Rectangle box6 = new Rectangle(165, 405, 20, 45);
//drawing the shapes
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 100, 100);
g2.draw(ball);
g2.draw(box1);
g2.draw(box2);
g2.draw(box3);
g2.draw(box4);
g2.draw(box5);
g2.draw(box6);
//coloring the shapes
g2.setColor(Color.BLACK);
g2.fill(box1);
g2.fill(box3);
g2.fill(box5);
g2.setColor(Color.YELLOW);
g2.fill(ball);
}
}
public class changeColors extends JPanel {
private boolean choseColor = false;
private int x = 125;
private int y = 80;
public void changeColor(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.ORANGE);
if (!choseColor) {
g2.fill(new Ellipse2D.Double(x, y, 100, 100));
}
}
public void changeColor() { choseColor = false; }
}
public BelishaBeacon() {
//Creation of frame
JFrame frame = new JFrame();
frame.setSize(350, 570);
frame.setTitle("Belisha Beacon");
frame.setLayout(new BorderLayout(0, 0));
final Drawing shapes = new Drawing();
final changeColors colorinG = new changeColors();
JButton jbtFlash = new JButton("Flash");
final JButton jbtSteady = new JButton("Steady");
jbtSteady.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
colorinG.changeColor();
colorinG.repaint();
}
});
//Positioning
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new GridLayout(1, 2, 0, 0));
controlPanel.add(jbtFlash);
controlPanel.add(jbtSteady);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.add(shapes);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
new BelishaBeacon();
}
}
You need to add handling logic to your Drawing Swing component, e.g.:
add method to your Drawing to change the color
modify the paintComponent(Graphics) according to the first step
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
public class BelishaBeacon {
public class Drawing extends JPanel {
private int x = 125;
private int y = 80;
private boolean changeColors = false;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//creating the shapes
Rectangle box1 = new Rectangle(165, 180, 20, 45);
Rectangle box2 = new Rectangle(165, 225, 20, 45);
Rectangle box3 = new Rectangle(165, 270, 20, 45);
Rectangle box4 = new Rectangle(165, 315, 20, 45);
Rectangle box5 = new Rectangle(165, 360, 20, 45);
Rectangle box6 = new Rectangle(165, 405, 20, 45);
//drawing the shapes
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 100, 100);
g2.draw(ball);
g2.draw(box1);
g2.draw(box2);
g2.draw(box3);
g2.draw(box4);
g2.draw(box5);
g2.draw(box6);
//coloring the shapes
g2.setColor(Color.BLACK);
g2.fill(box1);
g2.fill(box3);
g2.fill(box5);
g2.setColor(Color.YELLOW);
g2.fill(ball);
if (changeColors) {
g2.setColor(Color.ORANGE);
g2.fill(new Ellipse2D.Double(x, y, 100, 100));
}
changeColors = false;
}
public void changeColors() {
changeColors = true;
repaint();
}
}
public BelishaBeacon() {
//Creation of frame
JFrame frame = new JFrame();
frame.setSize(350, 570);
frame.setTitle("Belisha Beacon");
frame.setLayout(new BorderLayout(0, 0));
final Drawing shapes = new Drawing();
JButton jbtFlash = new JButton("Flash");
final JButton jbtSteady = new JButton("Steady");
jbtSteady.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
shapes.changeColors();
}
});
//Positioning
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new GridLayout(1, 2, 0, 0));
controlPanel.add(jbtFlash);
controlPanel.add(jbtSteady);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.add(shapes);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
new BelishaBeacon();
}
}

How to make a section of code start first-Java Small error/last little step

So the task I've been set is to make an animation of a lamp. There are buttons added that do different actions such as change colour of the sphere etc.
Code: Sphere Class
public class Sphere extends JPanel {
private boolean flashinglights = false;
private int x = 168;
private int y = 75;
private Color[] colors = new Color[] {Color.ORANGE, Color.LIGHT_GRAY };
private int colorIndex = 0;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Graphics2D g3 = (Graphics2D) g;
if (!flashinglights) {
Rectangle box0 = new Rectangle(x+16, y+50,14, 50);
g3.setColor(Color.black);
g3.draw(box0);
g3.fill(box0);
Rectangle box1 = new Rectangle(x+16, y+90,14, 50);
g3.setColor(Color.white);
g3.draw(box1);
g3.fill(box1);
Rectangle box2 = new Rectangle(x+16, y+130,14, 50);
g3.setColor(Color.black);
g3.draw(box2);
g3.fill(box2);
Rectangle box3 = new Rectangle(x+16, y+170,14, 50);
g3.setColor(Color.white);
g3.draw(box3);
g3.fill(box3);
Rectangle box4 = new Rectangle(x+16, y+210,14, 50);
g3.setColor(Color.black);
g3.draw(box4);
g3.fill(box4);
Rectangle box5 = new Rectangle(x+16, y+250,14, 50);
g3.setColor(Color.white);
g3.draw(box5);
g3.fill(box5);
Rectangle box6 = new Rectangle(x+16, y+290,14, 50);
g3.setColor(Color.black);
g3.draw(box6);
g3.fill(box6);
Rectangle box7 = new Rectangle(x+16, y+330,14, 50);
g3.setColor(Color.white);
g3.draw(box7);
g3.fill(box7);
Rectangle box8 = new Rectangle(x+16, y+370,14, 50);
g3.setColor(Color.black);
g3.draw(box8);
g3.fill(box8);
Rectangle box9 = new Rectangle(x+16, y+410,14, 50);
g3.setColor(Color.white);
g3.draw(box9);
g3.fill(box9);
Rectangle box10 = new Rectangle(x+16, y+450,14, 50);
g3.setColor(Color.black);
g3.draw(box10);
g3.fill(box10);
g2.setColor(Color.ORANGE);
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
g2.draw(ball);
g2.fill(ball);
} else {
if(colorIndex > colors.length - 1)
colorIndex = 0;
Rectangle box0 = new Rectangle(x+16, y+50,14, 50);
g3.setColor(Color.black);
g3.draw(box0);
g3.fill(box0);
Rectangle box1 = new Rectangle(x+16, y+90,14, 50);
g3.setColor(Color.white);
g3.draw(box1);
g3.fill(box1);
Rectangle box2 = new Rectangle(x+16, y+130,14, 50);
g3.setColor(Color.black);
g3.draw(box2);
g3.fill(box2);
Rectangle box3 = new Rectangle(x+16, y+170,14, 50);
g3.setColor(Color.white);
g3.draw(box3);
g3.fill(box3);
Rectangle box4 = new Rectangle(x+16, y+210,14, 50);
g3.setColor(Color.black);
g3.draw(box4);
g3.fill(box4);
Rectangle box5 = new Rectangle(x+16, y+250,14, 50);
g3.setColor(Color.white);
g3.draw(box5);
g3.fill(box5);
Rectangle box6 = new Rectangle(x+16, y+290,14, 50);
g3.setColor(Color.black);
g3.draw(box6);
g3.fill(box6);
Rectangle box7 = new Rectangle(x+16, y+330,14, 50);
g3.setColor(Color.white);
g3.draw(box7);
g3.fill(box7);
Rectangle box8 = new Rectangle(x+16, y+370,14, 50);
g3.setColor(Color.black);
g3.draw(box8);
g3.fill(box8);
Rectangle box9 = new Rectangle(x+16, y+410,14, 50);
g3.setColor(Color.white);
g3.draw(box9);
g3.fill(box9);
Rectangle box10 = new Rectangle(x+16, y+450,14, 50);
g3.setColor(Color.black);
g3.draw(box10);
g3.fill(box10);
g2.setColor(colors[colorIndex++]);
Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
g2.draw(ball);
g2.fill(ball);
}
}
public void chooseflashinglights(){
flashinglights = true;
}
public void choosesteady(){
flashinglights = false;
}
public static void main(String[] args) {
JFrame scFrame = new AnimationViewer();
scFrame.setTitle("Belisha Beacon");
scFrame.setSize(400, 500);
scFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
scFrame.setVisible(true);
}
}
Code: Animation Viewer CLass
public class AnimationViewer extends JFrame {
JButton jbtFlash = new JButton("Flash");
JButton jbtSteady = new JButton("Steady");
JPanel bPanel = new JPanel();
Sphere sphPanel = new Sphere();
Timer timer;
public AnimationViewer() {
timer = new Timer(500, new TimerListener());
this.add(bPanel, BorderLayout.SOUTH);
bPanel.add(jbtFlash);
bPanel.setLayout(new GridLayout(1, 1));
bPanel.add(jbtSteady);
this.add(sphPanel, BorderLayout.CENTER);
jbtFlash.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
sphPanel.chooseflashinglights();
timer.start();
}
});
jbtSteady.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
sphPanel.choosesteady();
timer.stop();
sphPanel.repaint();
}
});
}
class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
sphPanel.repaint();
}
}
}
The main two buttons do two different things. One makes the sphere stay a solid orange colour (Steady) and the other makes the sphere alternate from Orange to grey. (flashing)
NOW THE PROBLEM:
When you start the program the sphere starts of in Steady mode were the colour is just solid orange.
I want the program to START in flashing mode. So when you click run the sphere should be straight in the flashing stage alternating from orange to grey straight away.
So how can I make it so I can start a piece of code first so it goes straight to the flashing lights mode?
Extract the code used to switch the mode to flashing in a method, to avoid code duplication:
private void flash() {
sphPanel.chooseflashinglights();
timer.start();
}
Call this method from the action listener:
jbtFlash.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
flash();
}
});
And also call it in the constructor:
public AnimationViewer() {
// existing code omitted
flash();
}

Using JButtons, JLabels, and JTextFields within a JPanel over a painted background

I'm pretty new to Java, but have been using JPanels, JButtons, JLabels and JTextFields successfully in other parts of my program, but I'm running into trouble when trying to have a JPanel with a couple JButtons, JLabels, and JTextFields inside of it overtop of a painted background.
Here is all of the relevant code for this portion of the program. Currently, when the program runs the only thing that will display is the p1_fireButton, player1PowerField, and player1AngleField overtop of the background (Even though I have the components created for player 2, I purposely commented out adding the p2_Panel so that I could concentrate on p1_Panel.
The weird thing is that those JComponents will only display if I hit the TAB key after the program is running for whatever reason, which I'm also hoping someone could help me fix. My goal will be to have the p1_panel occupy the left orange box and the p2_panel occupy the right orange box. Help would be greatly appreciated!
public class GameFrame extends JFrame
{ //start class GameFrame
ImageIcon background = new ImageIcon("background.jpg");
ImageIcon terrain1 = new ImageIcon("terrain1.png");
//ImageIcon tank_red = new ImageIcon("tank_red.png");
//ImageIcon tank_red = new ImageIcon(player1Tank);
private int x_rectangle = 50;
private int y_rectangle = 50;
private JButton p1_fireButton;
private JButton p2_fireButton;
private JPanel p1_Panel;
private JPanel p2_Panel;
private JLabel player1PowerLabel;
private static JTextField player1PowerField;
private JLabel player1AngleLabel;
private static JTextField player1AngleField;
private JLabel player2PowerLabel;
private static JTextField player2PowerField;
private JLabel player2AngleLabel;
private static JTextField player2AngleField;
String player1Name;
String player2Name;
final Timer gameTimer = new Timer(8, new timer());
Projectile projectile = new Projectile(200, 300);
public GameFrame(String title)
{ //start GameFrame constructor
super(title);
Dimension size = getPreferredSize();
size.width = 1000;
setPreferredSize(size);
setResizable(false);
setLayout(null);
Color trans = new Color(0, 0, 0, 0);
//player1 panel
p1_Panel = new JPanel();
p1_Panel.setLayout(null);
p1_Panel.setBounds(0, 0, 500, 300);
p1_Panel.setBackground(trans);
p2_Panel = new JPanel();
p2_Panel.setLayout(null);
p2_Panel.setBounds(500, 0, 500, 300);
p2_Panel.setBackground(trans);
//player2 panel
/*p2_fireButtonPanel = new JPanel();
p2_fireButtonPanel.setBounds(400, 85, 100, 100);
p2_fireButtonPanel.setBackground(trans);*/
//player1 angle/power fields
player1PowerLabel = new JLabel("Power");
player1PowerLabel.setLayout(null);
player1PowerLabel.setBounds(400, 20, 50, 50);
player1PowerField = new JTextField(3);
player1PowerField.setLayout(null);
player1PowerField.setBounds(400, 10, 50, 25);
player1AngleLabel = new JLabel("Angle");
player1AngleLabel.setLayout(null);
player1AngleLabel.setBounds(30, 10, 50, 50);
player1AngleField = new JTextField(3);
player1AngleField.setLayout(null);
player1AngleField.setBounds(300, 10, 50, 25);
//player2 angle/power fields
player2PowerLabel = new JLabel("Power");
player2PowerLabel.setLayout(null);
player2PowerLabel.setBounds(0, 0, 10, 10);
player2PowerField = new JTextField(3);
player2PowerField.setLayout(null);
player2PowerField.setBounds(10, 10, 10, 10);
player2AngleLabel = new JLabel("Angle");
player2AngleLabel.setLayout(null);
player2AngleLabel.setBounds(30, 10, 10, 10);
player2AngleField = new JTextField(3);
player2AngleField.setLayout(null);
player2AngleField.setBounds(60, 10, 10, 10);
//player1 fire button
p1_fireButton = new JButton("Fire!");
p1_fireButton.setLayout(null);
p1_fireButton.setBounds(430, 70, 50, 50);
ActionListener fireListener = new fireButtonListener();
p1_fireButton.addActionListener(fireListener);
//player2 fire button
p2_fireButton = new JButton("Fire AGAIN!");
p2_fireButton.setLayout(null);
p2_fireButton.setBounds(530, 70, 50, 50);
//add components to player1 panel
p1_Panel.add(p1_fireButton);
p1_Panel.add(player1PowerLabel);
p1_Panel.add(player1PowerField);
p1_Panel.add(player1AngleLabel);
p1_Panel.add(player1AngleField);
//add components to player2 panel
p2_Panel.add(p2_fireButton);
p2_Panel.add(player2PowerLabel);
p2_Panel.add(player2PowerField);
p2_Panel.add(player2AngleLabel);
p2_Panel.add(player2AngleField);
//add components to GameFrame
add(p1_Panel);
//add(p2_Panel);
projectile.fireProjectile(60, -60 * Math.PI / 180.0);
} //end GameFrame constructor
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Image bg = background.getImage();
Image t1 = terrain1.getImage();
Image p1tank = StartPanel.getPlayer1Tank();
Image p2tank = StartPanel.getPlayer2Tank();
//Image tank1 = tank_red.getImage();
g2.drawImage(bg, 0, 0, 1000, 800, this);
g2.drawImage(t1, 0, 420, 1000, 380, this);
g2.drawImage(p1tank, 50, 300, 66, 50, null);
g2.drawImage(p2tank, 500, 300, 66, 50, null);
player1Name = new String(StartPanel.getPlayer1Name());
player2Name = new String(StartPanel.getPlayer2Name());
g.drawString(player1Name, 50, 50);
g.drawString(player2Name, 525, 50);
g2.setColor(Color.green);
g2.fillOval((int)projectile.getXPosition(), (int)projectile.getYPosition(), 15, 15);
}
public class timer implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//TanksGUI.gameFrame.moveRectangle(1, 1);
projectile.advanceProjectile(0.05);
if (projectile.getYPosition() > 400)
{
gameTimer.stop();
}
repaint();
}
}
public class fireButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
gameTimer.start();
}
}
} //end class GameFrame
Check out BackgroundPanel to help you with this. The basic code would be:
JPanel north = new JPanel();
north.add( new JLabel(...) );
north.add( new JTextField(10) );
JPanel gamePanel = new GamePanel();
BackgroundPanel background = new BackgroundPanel(...);
background.add(north, BorderLayout.North);
background.add(gamePanel);
frame.add(background);
The GamePanel is the panel where you do all the custom painting for your game characters. As noted by MadProgrammer, this painting should never be done in the paint() method of the frame.
Don't extend from JFrame you're not adding any functionality to it that creating an instance couldn't achieve. It also makes you're project unportable.
Don't override paint of top level containers. If for no other reason they are not double buffered, which will cause you problems if you want to perform animation. The paint chain for a top level container is rather complex and you've just circumvent the whole process.
Instead, create a custom component (from something like JPanel) and use it as you primary canvas. Override it's paintComponent method and render your background to it, making sure you call super.paintComponent first.
Make sure that any containers you are placing on this "canvas" are transparent, otherwise your background won't show up.
Have a look at Performing Custom Painting and Painting in AWT and Swing for more information

Stop infinite loop paint() method? Add JButton with paint()?

I wrote program to draw wheel (circle with 6 segments) and each segment with different colour. and animate the wheel..
here is the code:
public class ExamWheel extends JFrame implements ActionListener{
JButton b_start = new JButton("Start");
JButton b_stop = new JButton("Stop");
Thread th;
Boolean doDraw = true;
public ExamWheel(){
setSize(400,400);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setTitle("Wheel..");
//add(b_start);
this.setLayout (new FlowLayout());
this.add(b_stop);
b_start.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==b_start)
doDraw=true;
}
public void paint(Graphics graphics) {
if (doDraw){
super.paint(graphics);
Graphics2D g = (Graphics2D) graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
try{
// draw the circle
for(int i=0; ; i=i+1){
g.setColor(Color.CYAN);
g.fillArc(50, 50, 300, 300, i+0, 60);
th.sleep(1);
g.setColor(Color.red);
g.fillArc(50, 50, 300, 300, i+60, 60);
th.sleep(1);
g.setColor(Color.green);
g.fillArc(50, 50, 300, 300, i+120, 60);
th.sleep(1);
g.setColor(Color.blue);
g.fillArc(50, 50, 300, 300, i+180, 60);
th.sleep(1);
g.setColor(Color.gray);
g.fillArc(50, 50, 300, 300, i+240, 60);
th.sleep(1);
g.setColor(Color.pink);
g.fillArc(50, 50, 300, 300, i+300, 60);
th.sleep(1);
}
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
ExamWheel f = new ExamWheel();
}
}
Problems: it is infinite loop, and I can't stop it or close the Frame.
so I had idea:
I created Boolean variable (doDraw) with value true, and add JButton, when click the Button the variable will change to false, and in paint() method I'll use if condition at first of paint()
problem: I can't add JButton to the Frame with paint(), so what can I do?
Note: I tried to use paintComponent() but the loop (for with thread) doesn't work.
IT IS SOLVED
Thanks for Pete Kirham
I added Timer and replaced paint() by paintComponent()
public class ExamWheel extends JPanel implements ActionListener {
int i=0;
Timer tm = new Timer(10, this);
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g = (Graphics2D) graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.CYAN);
g.fillArc(50, 50, 300, 300, i+0, 60);
g.setColor(Color.red);
g.fillArc(50, 50, 300, 300, i+60, 60);
g.setColor(Color.green);
g.fillArc(50, 50, 300, 300, i+120, 60);
g.setColor(Color.blue);
g.fillArc(50, 50, 300, 300, i+180, 60);
g.setColor(Color.gray);
g.fillArc(50, 50, 300, 300, i+240, 60);
g.setColor(Color.pink);
g.fillArc(50, 50, 300, 300, i+300, 60);
tm.start();
}
public void actionPerformed(ActionEvent e) {
i++;
repaint();
}
public static void main(String[] args) {
ExamWheel wh = new ExamWheel();
JFrame jf = new JFrame();
jf.setSize(500,500);
jf.setResizable(false);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocationRelativeTo(null);
jf.setTitle("Wheel..");
jf.add(wh);
}
You need to return from paintComponent to allow the thread which runs the gui to do other stuff, like respond to button events or actually put the contents of the graphics onto the screen.
Use a timer to invalidate the component - see http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html and update the the animation based on the current time, for example current milliseconds modulo 5000 will give a cycle which repeats every five seconds.

Categories