When I press somewhere near Top-Left of the window, for some reason the output result for e.getY() is higher by about 40 than e.getX(). I don't see why... do you? Something is not clear to me regarding e.getY().
//BBDemo.java - The main program and window creation
import javax.swing.*;
public class BBDemo extends JApplet{ //this isn't Applet !
public int offset=400;
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame win = new JFrame("Bouncing Ball Demo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setContentPane(new BBPanel());
win.pack();
win.setVisible(true);
}
}//endclass BBDemo
//BBPanel.java - The JPanel which organizes the GUI
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/////////////////////////////////////////////////////////////////// BBPanel
public class BBPanel extends JPanel {
BallInBox m_bb; // The bouncing ball panel ///in order to take the Timer->setAnimation from m_bb
Ball BallN;
//========================================================== constructor
/** Creates a panel with the controls and bouncing ball display. */
BBPanel() {
//... Create components
m_bb = new BallInBox();
BallN=new Ball(400,400,400);
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
//... Add Listeners
startButton.addActionListener(new StartAction());
stopButton.addActionListener(new StopAction());
addMouseListener(new PressBall());
//... Layout inner panel with two buttons horizontally ///why inner and outer?
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout()); ///Flow???
buttonPanel.add(startButton);
buttonPanel.add(stopButton);
//... Layout outer panel with button panel above bouncing ball ///???
this.setLayout(new BorderLayout()); ///this ??? ///Board???
this.add(buttonPanel, BorderLayout.NORTH); ///this, NORTH, ???
this.add(m_bb , BorderLayout.CENTER); ///this, CENTER, ???
}//end constructor
////////////////////////////////////// inner listener class StartAction
class StartAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
m_bb.setAnimation(true);
}
}
//////////////////////////////////////// inner listener class StopAction
class StopAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
m_bb.setAnimation(false);
}
}
public class PressBall implements MouseListener {
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
//System.out.print(BallN.m_x-BallN.getDiameter()/2+" ");
System.out.print(e.getX()+" ");
//System.out.print(BallN.m_x+BallN.getDiameter()/2+" ");
//System.out.print(BallN.m_y-BallN.getDiameter()/2+" ");
System.out.print(e.getY()+" ");
//System.out.println(BallN.m_y+BallN.getDiameter()/2+" ");
if ((e.getButton() == 1)
&& (e.getX() >= BallN.m_x-BallN.getDiameter()/2 && e.getX() <=
BallN.m_x+BallN.getDiameter()/2 && e.getY() >= BallN.m_y-BallN.getDiameter()/2 && e.getY() <=
BallN.m_y+BallN.getDiameter()/2 ))
{ m_bb.setAnimation(false);
}else{}
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
}//endclass BBPanel
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/////////////////////////////////////////////////////////////// BouncingBall
public class BallInBox extends JPanel {
//============================================== fields
public Ball m_ball = new Ball(400,400,400);
private int m_interval = 40; // Milliseconds between updates.
private Timer m_timer; // Timer fires to animate one step.
//=================================================== constructor
public BallInBox() {
setPreferredSize(new Dimension(800, 800));
setBorder(BorderFactory.createLineBorder(Color.BLACK));
m_timer = new Timer(m_interval, new TimerAction());
}
//========================================================= setAnimation
public void setAnimation(boolean turnOnOff) {
if (turnOnOff) {
m_timer.start(); // start animation by starting the timer.
} else {
m_timer.stop(); // stop timer
}
}
//======================================================= paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g); // Paint background, border
m_ball.draw(g); // Draw the ball.
// m_ball.changeColor(g);
}
class TimerAction implements ActionListener {
//================================================== actionPerformed
public void actionPerformed(ActionEvent e) {
m_ball.setBounds(getWidth(), getHeight()); ///???
m_ball.move(); // Move the ball.
repaint(); // Repaint indirectly calls paintComponent. ///why "indirectly"?
}
/* public void mousePressed(MouseEvent e) {
System.out.println("dfvsd");
if ((e.getButton() == 1)
&& (e.getX() >= 400- m_ball.m_x && e.getX() <= 400+ m_ball.m_x && e.getY() >=
400- m_ball.m_x && e.getY() <= 400+ m_ball.m_x)) {m_timer.stop();
// System.out.println("dfvsd");
}else{}
}*/
}
//////////////////////////////////////// inner listener class StopAction
}//endclass
import java.awt.*;
///////////////////////////////////////////////////////////////// BallModel
public class Ball {
//... Constants
final static int DIAMETER = 50;
//... Instance variables
static int m_x; // x and y coordinates upper left
static int m_y;
/*
private int m_velocityX; // Pixels to move each time move() is called.
private int m_velocityY;*/
private int m_rightBound; // Maximum permissible x, y values.
private int m_bottomBound;
public int i=0;
public int offset=400;
//======================================================== constructor
public Ball(int x, int y, int offset) {
m_x = x;
m_y = y;
//offset=400;
}
//======================================================== setBounds
public void setBounds(int width, int height) {
m_rightBound = width - DIAMETER;
m_bottomBound = height - DIAMETER;
}
//============================================================== move
public void move() {
double degrees=(double) i;
double radians=Math.toRadians(degrees);
double Sinu=Math.sin(radians);
double Sinu200=Math.sin(radians)*300;
int SinuInt=(int) Sinu200;
m_y=offset+SinuInt;
//z=offset-SinuInt;
double Cos=Math.cos(radians);
double Cos200=Math.cos(radians)*300;
int CosInt=(int) Cos200;
m_x=offset+CosInt;
i++; // j--;
if (i==360) i=0;
//w=offset-CosInt;
/*
//... Bounce the ball off the walls if necessary.
if (m_x < 0) { // If at or beyond left side
m_x = 0; // Place against edge and
m_velocityX = -m_velocityX; // reverse direction.
} else if (m_x > m_rightBound) { // If at or beyond right side
m_x = m_rightBound; // Place against right edge.
m_velocityX = -m_velocityX; // Reverse direction.
}
if (m_y < 0) { // if we're at top
m_y = 0;
m_velocityY = -m_velocityY;
} else if (m_y > m_bottomBound) { // if we're at bottom
m_y = m_bottomBound;
m_velocityY = -m_velocityY;
}*/
}
//============================================================== draw
public void draw(Graphics g) {
g.setColor(Color.green);
g.fillOval(m_x, m_y, DIAMETER, DIAMETER);
}
//======================================================== setPosition
public void setPosition(int x, int y) {
m_x = x;
m_y = y;
}
}
If the window is decorated, then you have to take into account the title bar height.
This is probably due to the blue strip (title bar, not sure if that's the right term) which most GUI programs have at their top.
Related
I have a task in university to draw an ellipse and make it move step by step on the screen pressing the button only once. Here is my code:
public class Window extends JPanel {
private static Ellipse2D.Double Ellipse;
private JFrame frame;
public Window() {
super();
int width = 20;
int height = 30;
Ellipse = new Ellipse2D.Double(width, height, 100, 50);
}
public Dimension getPreferredSize()
{
return (new Dimension(frame.getWidth(), frame.getHeight()));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D brush = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g.clearRect(0, 0, width, height);
brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
brush.draw(Ellipse);
}
public class MoveCircle implements KeyListener, ActionListener {
#Override
public void keyPressed(KeyEvent e) {
System.out.println("Working on top!");
double newX = 0; double newY = 0;
if (e.getKeyCode() == Event.ENTER) {
for (int i = 0; i < 26; i ++)
{
System.out.println("Working on bottom!");
newX = Ellipse.x + 10;
Ellipse.x = newX;
newY = Ellipse.y + 10;
Ellipse.y = newY;
repaint();
}
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
private void createAndDisplayGUI(Window window)
{
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
window.addKeyListener(new MoveCircle());
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
window.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Window window = new Window();
window.createAndDisplayGUI(window);
}
});
}
}
Although I call the function repaint() in cycle each time still the ellipse just moves radically from the original point to the point defined in the last iteration without drawing position of the ellipse in each iteration.
Is it possible to use a Swing Timer to make it repaint the ellipse in each iteration? I will be very glad to get help in this.
You have two problems: The first is that your loop is being run on the UI thread. The second is your misunderstanding in how repaint works. All repaint does is adds a request to the UI thread to do a repaining. It doesn't perform a repaint in and of itself. So if you are running operations on the UI thread, calling it multiple times will have no effect. As you suggested, you can fix this with a Swing Timer, as I've put together below
ActionListener al = new ActionListener() {
int iterations = 0;
public void actionPerformed(ActionEvent ae) {
if (iterations == 25) {
timer.stop();
}
interations++;
System.out.println("Working on bottom!");
newX = Ellipse.x + 10;
Ellipse.x = newX;
newY = Ellipse.y + 10;
Ellipse.y = newY;
repaint();
}
};
final timer = new javax.swing.Timer(delay, al);
timer.start();
These are the specific instruction but they are kind of confusing to me (are the instructions confusing/ambiguous or am I just not getting it?)
write a method public static void draw shooter(Graphics g, Color c);
call draw shooter using the shooter color as the last parameter in drawAll(?)
test the program you should see a red disk centered near the bottom of the screen(?)
import java.awt.*;
public class Project2{
public static final int PANEL_WIDTH = 300;
public static final int PANEL_HEIGHT = 300;
public static final int SLEEP_TIME = 50;
public static Color SHOOTER_COLOR = Color.RED;
public static Color BACKGROUND_COLOR = Color.WHITE;
public static final int SHOOTER_SIZE = 20; //diameter of the shooter
public static final int GUN_SIZE = 10; //length og the gun
public static final int SHOOTER_POSITION_Y = PANEL_HEIGHT - SHOOTER_SIZE;
public static final int SHOOTER_INITIAL_POSITION_X = 150;
int shooterPosition;
public static void initialize(){
int shooterPositionX = SHOOTER_INITIAL_POSITION_X;
}
public static void main(String[] args) {
DrawingPanel panel = new DrawingPanel(PANEL_WIDTH, PANEL_HEIGHT);
Graphics g = panel.getGraphics( );
initialize();
startGame(panel, g);
drawShooter(g, SHOOTER_COLOR);
}
public static void drawShooter(Graphics g, Color C){
g.setColor(Color);
g.fillOval(shooterPosition, SHOOTER_POSITION_Y, SHOOTER_SIZE, SHOOTER_SIZE);
}
public static void drawAll(Graphics g){
g.drawString("Project 2 by Jasmine Ramirez", 10, 15);
}
public static void startGame(DrawingPanel panel, Graphics g) {
for (int i = 0; i <= 10000; i++) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
}
}
this is my code I guessed that I needed to draw and color in a circle inside the method but I am getting errors with the g.setColor inside the method and I'm not sure what the second step means. Thanks just started learning to program.
Drawing Panel
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.ArrayList;
public class DrawingPanel implements ActionListener {
private static final String versionMessage =
"Drawing Panel version 1.1, January 25, 2015";
private static final int DELAY = 100; // delay between repaints in millis
private static final boolean PRETTY = false; // true to anti-alias
private static boolean showStatus = false;
private static final int MAX_KEY_BUF_SIZE = 10;
private int width, height; // dimensions of window frame
private JFrame frame; // overall window frame
private JPanel panel; // overall drawing surface
private BufferedImage image; // remembers drawing commands
private Graphics2D g2; // graphics context for painting
private JLabel statusBar; // status bar showing mouse position
private volatile MouseEvent click; // stores the last mouse click
private volatile boolean pressed; // true if the mouse is pressed
private volatile MouseEvent move; // stores the position of the mouse
private ArrayList<KeyInfo> keys;
// construct a drawing panel of given width and height enclosed in a window
public DrawingPanel(int width, int height) {
this.width = width;
this.height = height;
keys = new ArrayList<KeyInfo>();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
statusBar = new JLabel(" ");
statusBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));
statusBar.setText(versionMessage);
panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
panel.setBackground(Color.WHITE);
panel.setPreferredSize(new Dimension(width, height));
panel.add(new JLabel(new ImageIcon(image)));
click = null;
move = null;
pressed = false;
// listen to mouse movement
MouseInputAdapter listener = new MouseInputAdapter() {
public void mouseMoved(MouseEvent e) {
pressed = false;
move = e;
if (showStatus)
statusBar.setText("moved (" + e.getX() + ", " + e.getY() + ")");
}
public void mousePressed(MouseEvent e) {
pressed = true;
move = e;
if (showStatus)
statusBar.setText("pressed (" + e.getX() + ", " + e.getY() + ")");
}
public void mouseDragged(MouseEvent e) {
pressed = true;
move = e;
if (showStatus)
statusBar.setText("dragged (" + e.getX() + ", " + e.getY() + ")");
}
public void mouseReleased(MouseEvent e) {
click = e;
pressed = false;
if (showStatus)
statusBar.setText("released (" + e.getX() + ", " + e.getY() + ")");
}
public void mouseEntered(MouseEvent e) {
// System.out.println("mouse entered");
panel.requestFocus();
}
};
panel.addMouseListener(listener);
panel.addMouseMotionListener(listener);
new DrawingPanelKeyListener();
g2 = (Graphics2D)image.getGraphics();
g2.setColor(Color.BLACK);
if (PRETTY) {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(1.1f));
}
frame = new JFrame("Drawing Panel");
frame.setResizable(false);
try {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // so that this works in an applet
} catch (Exception e) {}
frame.getContentPane().add(panel);
frame.getContentPane().add(statusBar, "South");
frame.pack();
frame.setVisible(true);
toFront();
frame.requestFocus();
// repaint timer so that the screen will update
new Timer(DELAY, this).start();
}
public void showMouseStatus(boolean f) {
showStatus = f;
}
public void addKeyListener(KeyListener listener) {
panel.addKeyListener(listener);
panel.requestFocus();
}
// used for an internal timer that keeps repainting
public void actionPerformed(ActionEvent e) {
panel.repaint();
}
// obtain the Graphics object to draw on the panel
public Graphics2D getGraphics() {
return g2;
}
// set the background color of the drawing panel
public void setBackground(Color c) {
panel.setBackground(c);
}
// show or hide the drawing panel on the screen
public void setVisible(boolean visible) {
frame.setVisible(visible);
}
// makes the program pause for the given amount of time,
// allowing for animation
public void sleep(int millis) {
panel.repaint();
try {
Thread.sleep(millis);
} catch (InterruptedException e) {}
}
// close the drawing panel
public void close() {
frame.dispose();
}
// makes drawing panel become the frontmost window on the screen
public void toFront() {
frame.toFront();
}
// return panel width
public int getWidth() {
return width;
}
// return panel height
public int getHeight() {
return height;
}
// return the X position of the mouse or -1
public int getMouseX() {
if (move == null) {
return -1;
} else {
return move.getX();
}
}
// return the Y position of the mouse or -1
public int getMouseY() {
if (move == null) {
return -1;
} else {
return move.getY();
}
}
// return the X position of the last click or -1
public int getClickX() {
if (click == null) {
return -1;
} else {
return click.getX();
}
}
// return the Y position of the last click or -1
public int getClickY() {
if (click == null) {
return -1;
} else {
return click.getY();
}
}
// return true if a mouse button is pressed
public boolean mousePressed() {
return pressed;
}
public synchronized int getKeyCode() {
if (keys.size() == 0)
return 0;
return keys.remove(0).keyCode;
}
public synchronized char getKeyChar() {
if (keys.size() == 0)
return 0;
return keys.remove(0).keyChar;
}
public synchronized int getKeysSize() {
return keys.size();
}
private synchronized void insertKeyData(char c, int code) {
keys.add(new KeyInfo(c,code));
if (keys.size() > MAX_KEY_BUF_SIZE) {
keys.remove(0);
// System.out.println("Dropped key");
}
}
private class KeyInfo {
public int keyCode;
public char keyChar;
public KeyInfo(char keyChar, int keyCode) {
this.keyCode = keyCode;
this.keyChar = keyChar;
}
}
private class DrawingPanelKeyListener implements KeyListener {
int repeatCount = 0;
public DrawingPanelKeyListener() {
panel.addKeyListener(this);
panel.requestFocus();
}
public void keyPressed(KeyEvent event) {
// System.out.println("key pressed");
repeatCount++;
if ((repeatCount == 1) || (getKeysSize() < 2))
insertKeyData(event.getKeyChar(),event.getKeyCode());
}
public void keyTyped(KeyEvent event) {
}
public void keyReleased(KeyEvent event) {
repeatCount = 0;
}
}
}
1st Error
In your drawShooter() method you do:
g.setColor(Color)
This is incorrect, since you need to pass an instance of the class Color not the class itself.
So instead use this:
g.setColor(C);
2nd Error
change the shooterPosition to static so that it can be accessed by a static method.
I assume that the method initialize() is also wrong because you are declaring a new shooterPosition int for no reason so do these changes:
int shooterPosition;
To:
public static int shooterPosition;
And
public static void initialize(){
int shooterPositionX = SHOOTER_INITIAL_POSITION_X;
}
To:
public static void initialize() {
shooterPosition = SHOOTER_INITIAL_POSITION_X;
}
3rd Error
In startGame() you are looping for 10000 times and each time you are waiting for a bit more than 1/20th of a second, which means that you will have to wait for almost 10 minutes until the red circle is drawn. So you have two options.
1st option: decrease the amount of iterations or even better remove the loop.
public static void startGame(DrawingPanel panel, Graphics g) {
for (int i = 0; i <= 10000; i++) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
}
To:
public static void startGame(DrawingPanel panel, Graphics g) {
for (int i = 0; i <= 1; i++) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
}
or
public static void startGame(DrawingPanel panel, Graphics g) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
2nd option: execute the drawShooter() method before the startGame() method or don't execute the startGame() at all.
startGame(panel, g); drawShooter(g, SHOOTER_COLOR);
To:
drawShooter(g, SHOOTER_COLOR);
startGame(panel, g);
or
drawShooter(g, SHOOTER_COLOR);
Didn't you ask this same question or something similar to it yesterday? And you're passing in the class name to g.setColor(Color) method and need to pass in the parameter which holds the object: g.setColor(C)
Your use of Graphics is not good, as you shouldn't use a Graphics obtained from a component via getGraphics(), but I'm guessing that it's because that's what your instructor told you to do. Same for use of a while (true) loop. Instead you should use a Swing Timer.
Like stated before g.setcolor(c) is required
check your error msgs since it allows you to gather that error and the shooterPosition error(its not public so cant be used inside a method)
I'd like to state that this question is very possibly a duplicate, but I'm not sure exactly what the issue is: I'm unable to do a proper search because of this.
I'm currently working on a painting program in Java. I'm trying to store the instructions for drawing the shapes in an ArrayList of Shape objects. I'm also using a MouseListener to get the coordinates.
The goal is that when the mouse is pressed, it keeps a record of that point. When it is released, it keeps record of that second point, then sends the two coordinates to the constructor, in the line history.add(new Shape(x, y, x2, y2)).
The relevant code is the following:
// Create an ArrayList for the History
static ArrayList history = new ArrayList(0);
.
.
.
// Co-ordinates for rectangle painting
static int x = 0;
static int y = 0;
static int x2 = 0;
static int y2 = 0;
.
.
.
/**
* A class for handling mouse input
*
* All methods within the MouseHandler class MUST be there
* If not, the code will not compile.
*/
private static class MouseHandler implements MouseListener
{
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
public void mouseReleased(MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
//repaint() is a special method that must be called to "repaint"
//your shapes on the screen.
canvas.repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
// Create a new shape on the button unclick
history.add(new Shape(x, y, x2, y2));
}
}
This code throws an exception at the line history.add(new Shape(x, y, x2, y2)); : "Non-static method this cannot be referenced from a static context." The error seems to specifically reference (new Shape(x, y, x2, y2)). I don't understand why this method would be non-static.
Any help is greatly appreciated in advance,
Placowdepuss
Edit: Here is my full code:
//Import packages needed
// For the GUI
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// For the ArrayList
import java.util.*;
/**
* A simple drawing application.
*
* #author (Massimo A. Lipari)
* #version (1.0.0)
*/
public class PaintProgram
{
// Create the frame and the panels for the GUI
static JFrame frame = new JFrame("PaintIt");
static JPanel panel = new JPanel();
static JPanel buttonPanel = new JPanel();
static MyPanel canvas = new MyPanel();
static JLabel sampleText = new JLabel("Label");
// Create an array for the buttons
static JButton[] buttonArray = new JButton[12];
// Create an ArrayList for the History
static ArrayList<Shape> history = new ArrayList<Shape>();
// Co-ordinates for rectangle painting
static int x, y, x2, y2;
// Create a variable for keeping track of the active tool
static String activeTool;
// Variables for holding the current colour and fill settings
static boolean currentFill;
static Color currentColour;
public static void main(String[] args)
{
// Set the frame size
frame.setSize(1920,1040);
// Create the mouse listeners
canvas.addMouseListener(new MouseHandler());
// Set the size for the canvas portion of the screen
canvas.setSize(1920, 880);
// Add panels to frame
// Set layout for panel
panel.setLayout(new BorderLayout());
createButtonPanel();
panel.add(buttonPanel, BorderLayout.NORTH);
panel.add(canvas, BorderLayout.CENTER);
frame.getContentPane().add(panel);
// Set frame to visible and allows it to exit on closing of the frame
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void createButtonPanel()
{
// Set the buttonPanel size, and creates a grid layout for it
buttonPanel.setSize(1920, 160);
buttonPanel.setLayout(new GridLayout(1, 12));
// Initialize the buttons
for (int i = 0; i < buttonArray.length; i++) {
buttonArray[i] = new JButton("Button " + (i + 1));
// Create and add a button handler
buttonArray[i].addActionListener(new ButtonHandler());
buttonArray[i].setIcon(new ImageIcon("icon" + i + ".png"));
buttonArray[i].setBackground(Color.WHITE);
buttonPanel.add(buttonArray[i]);
}
}
/**
* A class for handling button input (the tools)
*/
private static class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == buttonArray[0]) {
buttonArray[0].setBackground(JColorChooser.showDialog(null, "Choose a Color", sampleText.getForeground()));
} else if (e.getSource() == buttonArray[1]) {
currentFill = true;
buttonArray[1].setBackground(Color.LIGHT_GRAY);
buttonArray[2].setBackground(null);
} else if (e.getSource() == buttonArray[2]) {
currentFill = false;
buttonArray[1].setBackground(null);
buttonArray[2].setBackground(Color.LIGHT_GRAY);
} else if (e.getSource() == buttonArray[3]) {
activeTool = "paint";
} else if (e.getSource() == buttonArray[4]) {
activeTool = "rectangle";
} else if (e.getSource() == buttonArray[5]) {
activeTool = "triangle";
} else if (e.getSource() == buttonArray[6]) {
activeTool = "circle";
} else if (e.getSource() == buttonArray[7]) {
activeTool = "line";
} else if (e.getSource() == buttonArray[8]) {
activeTool = "text";
} else if (e.getSource() == buttonArray[9]) {
} else if (e.getSource() == buttonArray[10]) {
} else if (e.getSource() == buttonArray[11]) {
}
}
}
/**
* A class for handling mouse input
*
* All methods within the MouseHandler class MUST be there
* If not, the code will not compile.
*/
private static class MouseHandler implements MouseListener
{
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
public void mouseReleased(MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
//repaint() is a special method that must be called to "repaint"
//your shapes on the screen.
canvas.repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
// Create a new shape on the button unclick
history.add(new Shape(x, y, x2, y2));
}
}
/**
* A class for painting the shapes
*/
private static class MyPanel extends JPanel
{
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
setBackground(Color.white);
}
public Dimension getPreferredSize() {
return new Dimension(600,600);
}
// ALL drawing of shapes must be done in the paintComponent method
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Drawing a basic rectangle from top left corner to bottom right on canvas
if (x2 >= x && y2 >= y)
g.drawRect(x, y, x2 - x, y2 - y);
else if (x2 >= x && y2 <= y)
g.drawRect(x, y2, x2 - x, y - y2);
else if (x2 <= x && y2 >= y)
g.drawRect(x2, y, x - x2, y2 - y);
else if (x2 <= x && y2 <= y)
g.drawRect(x2, y2, x - x2, y - y2);
}
}
/**
* A class that creates a colour picker
*
* This code is the property of Oracle Systems Inc. It is copyrighted.
*/
static class ColorChooser_01 extends JFrame
{
public static void main(String[] args) {
new ColorChooser_01();
}
public ColorChooser_01() {
this.setSize(300, 100);
JPanel panel1 = new JPanel();
sampleText.setBackground(null);
panel1.add(sampleText);
this.add(panel1);
this.setVisible(true);
}
public class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
Color c = JColorChooser.showDialog(null, "Choose a Color", sampleText.getForeground());
if (c != null){
sampleText.setForeground(c);
buttonArray[0].setBackground(c);
}
else{
sampleText.setForeground(Color.WHITE);
}
}
}
}
/**
* A class for creating objects of type Shape
*/
public class Shape
{
// Variable for storing the type of shape
String type;
// Initialize variables for storing points for shape creation
int xcoord;
int ycoord;
int xcoord2;
int ycoord2;
// Boolean variable to control whether the shape is filled or not -- defaults to false
boolean fill = false;
// Variable to hold the coulour
Color colour;
public Shape(int newX, int newY, int newX2, int newY2)
{
type = activeTool;
xcoord = newX;
ycoord = newY;
xcoord2 = newX2;
ycoord2 = newY2;
fill = currentFill;
colour = currentColour;
}
public String getType()
{
return type;
}
public int getX()
{
return xcoord;
}
public int getY()
{
return ycoord;
}
public int getX2()
{
return xcoord2;
}
public int getY2()
{
return ycoord2;
}
public boolean getFill()
{
return fill;
}
public Color getColour()
{
return colour;
}
}
}
You need to move the shape class to another file because you cannot have two public classes in the same file
My boolean drawFlag is being set to false in my code with nothing visible actually telling it to change value to false. This is preventing the code inside method mouseDragged(mouseEvent) to execute. If someone could point out what's making the flag become false so this would stop happening? Thanks.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class DrawAndDrag {
public static void main(String[] args) throws InterruptedException {
GraphicsFrame window = new GraphicsFrame("Draw Rectangle");
window.init();
}
}
class GraphicsFrame extends JFrame {
public GraphicsFrame(String title) {
super(title);
}
public void init() {
Container pane = this.getContentPane();
pane.add(new GraphicsContent().init());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
this.setVisible(true);
}
}
class GraphicsContent extends JPanel {
private int xStart, yStart;
private int width, height;
public JPanel init() {
this.setBackground(Color.WHITE);
this.addMouseListener(new MouseDrag());
this.addMouseMotionListener(new MouseDrag());
return this;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(xStart, yStart, width, height);
}
class MouseDrag implements MouseListener, MouseMotionListener {
private boolean drawFlag;
public void mousePressed(MouseEvent e) {
if(isOutside(e)) {
this.drawFlag = true;
xStart = e.getX();
yStart = e.getY();
width = 0; height = 0;
System.out.println(drawFlag);
}else {
// this.drawFlag = false;
}
}
public void mouseDragged(MouseEvent e) {
System.out.println(drawFlag);
if(drawFlag) {
width = e.getX() - xStart;
height = e.getY() - yStart;
repaint();
}
}
public boolean isOutside(MouseEvent e) {
int xMin = Math.min(xStart, xStart + width); int yMin = Math.min(yStart, yStart + height);
int xMax = Math.max(xStart, xStart + width); int yMax = Math.max(yStart, yStart + height);
if((e.getX() < xMin || e.getX() > xMax)
|| (e.getY() < yMin || e.getY() > yMax)) {
return true;
}else {
return false;
}
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
}
Try to move drawFlag attribute from the inner class MouseDrag to the outer class GraphicsContent as follow
class GraphicsContent extends JPanel {
private int xStart, yStart;
private int width, height;
private volatile boolean drawFlag;
// other code
}
However as you drag, the value is constantly being reported as being false
You've got two listeners. One is a motion listener:
this.addMouseListener(new MouseDrag());
this.addMouseMotionListener(new MouseDrag());
mousePressed will not be called on a motion listener, so it will always be false in the drag event.
I expect what you meant is this:
MouseDrag listener = new MouseDrag();
this.addMouseListener(listener);
this.addMouseMotionListener(listener);
Are you sure you need two MouseDrag elements? I.e. using something like
public JPanel init() {
this.setBackground(Color.WHITE);
MouseDrag md = new MouseDrag();
this.addMouseListener(md);
this.addMouseMotionListener(md);
return this;
}
I can at least plot a blue square....
I searched the entire web trying to find a solution but in the end i just ended up being much more confused and frustrated. I am trying to get my paddle to move (paddle_y). Paddle does not need an x coordinate and it just has to move up and down on the vertical line. I have no idea what syntax i need for the mouseListener to get my paddle to move. please provide an example or solution if possible. Thanks a ton, any help is appreciated.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;
public class PongGame extends JFrame implements Runnable, MouseMotionListener {
int ball_x, ball_y, ball_dx, ball_dy;
int ball_r;
int x_left, x_right, y_top, y_bottom;
int paddle_y = 30;
/**
* Constructor
*/
public PongGame(){
init();
}
/**
* UI
*/
protected void init(){
this.setSize(300,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int curX = -1, curY = -1;
ball_x = this.getWidth()/2;
ball_y = this.getHeight()/2;
ball_dx = ball_dy = 2;
ball_r = 20;
this.setVisible(true);
getFocus(this);
x_left = this.getInsets().left;
x_right = this.getWidth() - this.getInsets().right - ball_r;
y_top = this.getHeight() - this.getInsets().top + ball_r/3;
y_bottom = this.getInsets().bottom + ball_r;
addMouseMotionListener(this);
}
public void mouseMoved(MouseEvent e) {
//help
}
public void mouseDragged(MouseEvent e) {
//help
}
/**
* helper method which we use to get the focus
*/
public void getFocus(final JFrame frame)
{
EventQueue.invokeLater(new Runnable() {
public void run() {
frame.requestFocus();
}
});
}
/**
* implementation of the Runnable interface to be able to move the ball, etc.
*/
public void run(){
while(true){
ball_x += ball_dx;
if(ball_x <= x_left || ball_x >= x_right){
ball_dx *=-1;
ball_x += (2*ball_dx);
}
ball_y += ball_dy;
if(ball_y <= y_bottom || ball_y >= y_top){
ball_dy *=-1;
ball_y += (2*ball_dy);
}
repaint();
try{
Thread.sleep(50);
}catch(InterruptedException ex){
System.out.println(ex);
}
}
}
/**
* all rendering occurs here
*/
public void paint(Graphics g){
//Color paddleOne;
//paddleOne = new Color(0);
g.setColor(Color.white);
g.fillRect(0,0,this.getWidth(),this.getHeight());
g.setColor(Color.black);
g.fillOval(ball_x,ball_y, ball_r, ball_r);
g.setColor(Color.black);
g.fillRect(0,paddle_y,20,70);
}
/**
* entry point into the program
*/
public static void main(String[] args){
// create the class
PongGame application = new PongGame();
new Thread(application).start();
}
}
paddle:
int paddle_y = 30;
g.setColor(Color.black);
g.fillRect(0,paddle_y,20,70);
public void mouseMoved(MouseEvent e) {
//help
}
public void mouseDragged(MouseEvent e) {
//help
}
The Paddle class needs an instance of the JFrame class in order to add a mouse listener. If you pass a JFrame object into the constructor, you can then use the following code:
public class Paddle {
private JFrame frame;
private int paddle_y;
public Paddle(JFrame frame) {
this.frame = frame;
this.paddle_y = 30; //Or whatever number you want
frame.addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved(MouseEvent e) {
Paddle.this.paddle_y = e.getY(); //When the mouse is moved, it will call on this function to change the Paddle.paddle_y variable.
}
public void mouseDragged(MouseEvent e){} //This reacts when the mouse is clicked, moved, then released.
}
}
This should replace the Paddle class, and it should change the paddle_y variable when the mouse is moved.
EDIT: If you do not want to create a new class, put this into the JFrame class:
int paddle_y;
this.addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved(MouseEvent e) {
paddle_y = e.getY(); //When the mouse is moved, it will call on this function to change the paddle_y variable (Within the JFrame class).
}
Then you can call on the paddle_y variable when rendering.