I am trying to draw a circle when a button is pressed.
public Buttons(Panel panel){
addStud = new JButton("+ Student");
addStud.setToolTipText("Add a student");
addStud.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//draw circle here
}
});
This is my button in Button.java
public void draw(Graphics g){
g.setColor(Color.BLUE);
g.fillOval(200, 200, 400, 50);
}
This is what I am trying to call in Panel.java
I have a public void paintComponent(Graphics g) but I don't want the circle to be drawn immediately.
I have tried initializing Panel() and calling it with no success. What can I do here?
class MyPanel extends JPanel {
Boolean drawBlue = false;
public void drawBlueCircle( Boolean draw ) {
drawBlue = draw;
repaint();
}
protected void paintComponent( Graphics g ) {
if ( drawBlue ) {
g.setColor(Color.BLUE);
g.fillOval(200, 200, 400, 50);
}
}
}
Then in your button's actionPerformed method call
myPanel.drawBlueCircle(true);
where myPanel is the instance of MyPanel that you created.
Related
I've done this plenty of times but I'm stuck. I've checked previous projects of mine and can't find the answer. The rectangle is supposed to show up at 400,400 and be 100,100 big, (Bottom right corner). When the start button is press I want it to show the rectangle. Thanks in advance!
!!!: There are multiple classes in this I just didn't post them since they don't have a use, if they do I'll post them.
class MazeRunner extends JFrame implements ActionListener, MouseMotionListener {
JButton b1;
int pkp = 0;
MazeRunner(){
b1= new JButton("Start");
add(b1);
b1.addActionListener(this);
b1.setBounds(10,10,50,50);
addMouseMotionListener(this);
setTitle("Maze Runner");
setLayout(null);
setSize(500, 500);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new MazeRunner();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == b1){
remove(b1);
pkp++;
validate();
repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
if (pkp == 1) {
if(e.getX() >= 400 && e.getX() <= 500 && e.getY() >= 400 && e.getY() <= 500) {
dispose();
}
}
}
protected void paintComponent(Graphics g) {
draw(g);
}
private void draw(Graphics g) {
if(pkp == 1) {
g.setColor(Color.BLACK);
g.fillRect(400, 400, 100, 100);
}
repaint();
}
}
First of all the method paintComponent() is missing it's constructor so it should look like
public void paintComponent(Graphics g){
super.paintComponent(g);
draw(g);
}
second of all, im not sure if Graphics g object has a method called "fillRect"
so I would recommend you to convert it to object of type Graphics2D, so in this case it would be:
public void draw(Graphics g){
Graphics2D g2 = (Graphics2D) g;
if(pkp == 1) {
g2.setColor(Color.BLACK);
g2.fillRect(400, 400, 100, 100);
}
repaint();
}
I have two classes that extend JPanel: MapPanel and CityPanel. I am trying to draw a CityPanel into a MapPanel but nothing appears. I do not understand why if I add a JButton in the same way it will be displayed perfectly.
Here's the code:
public class PanelMap extends JPanel {
public PanelMap() {
CityPanel city = new CityPanel();
city.setVisible(true);
this.add(city);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
public class CityPanel extends JPanel {
private BufferedImage image;
public CityPanel() {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Test", 0, 0); }
}
EDIT:
I have this code in CityMap. It display the string but no the image.
public CityPanel(String filePath, int red, int green, int blue) {
this.image = colorImage(filePath, red, green, blue);
this.setSize(100, 100);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 50, 50, null);
g.drawString("sdjkfpod", 50, 50);
}
Could you please replace your following constructor of PanelMap.java:
public PanelMap() {
CityPanel city = new CityPanel();
city.setVisible(true);
this.add(city);
}
By following constructor:
public PanelMap() {
String filePath = "C:\\...\\city2.png";
CityPanel city = new CityPanel(filePath, 0, 255, 255);
this.setLayout(new BorderLayout());
this.add(city, BorderLayout.CENTER);
}
and see the result?
Following changes have been made to your code:
The statement city.setVisible(true); is removed since it is not
required at all.
The statement this.add(city); was indeed adding CityPanel to
PanelMap but CityPanel took up very small space and looked as a
very small rectangle. This is the reason the BorderLayout has been
used.
Following PanelMapDemo.java adds PanelMap to a JFrame and creates an executable example.
public class PanelMapDemo extends javax.swing.JFrame {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
PanelMapDemo demoFrame = new PanelMapDemo("PanelMapDemo");
demoFrame.setVisible(true);
}
});
}
public PanelMapDemo(String title) {
super(title);
setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
add(new PanelMap());
setSize(new java.awt.Dimension(400, 200));
setLocationRelativeTo(null);
}
}
On my system when the original picture was:
Your MapPanel changes the picture to:
Hope, this helps.
I have a question. I created the Round Button, the code references from someone else cause I'm beginner. I want to set the position for it, but It seem to be unsuccessful. I thought the error is from its contains.
public final class ButtonDesigned extends JButton {
public ButtonDesigned (String label) {
super(label);
Dimension size = getPreferredSize();
size.width = size.height = Math.max(size.width,size.height);
setPreferredSize(size);
setContentAreaFilled(false);
}
protected void paintComponent(Graphics g) {
if (getModel().isArmed()) {
g.setColor(Color.lightGray);
} else {
g.setColor(getBackground());
}
g.fillOval(0, 0, getSize().width-1,getSize().height-1);
super.paintComponent(g);
}
protected void paintBorder(Graphics g) {
g.setColor(getForeground());
g.drawOval(0, 0, getSize().width-1, getSize().height-1);
}
Shape shape;
public boolean contains(int x, int y) {
if (shape == null ||
!shape.getBounds().equals(getBounds())) {
shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
}
return shape.contains(x, y);
}
public static void main(String[] args) {
JButton button = new ButtonDesigned ("Click");
button.setBackground(Color.gray);
button.setLocation(70, 70);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "you have clicked");
}
});
enter code here
JFrame frame = new JFrame();
frame.getContentPane().add(button);
frame.getContentPane().setLayout(new FlowLayout());
frame.setSize(300, 300);
frame.setVisible(true);
}
}
I have to draw some ovals in Java, and at click to change their color.
For the beginning I tried to change the color after 20 ms, but it doesn't work.
My code is:
public class MyComponentNew extends Frame {
public Graphics2D g2d;
public MyComponentNew(String title) {
super(title);
setSize(400, 550);
}
#Override
public void paint(Graphics g) {
this.g2d = (Graphics2D) g;
this.g2d.setColor(Color.red);
this.g2d.fillOval(10, 55, 50, 100);
}
public void changeColor () {
this.g2d.setColor(Color.blue);
this.g2d.fillOval(10, 55, 50, 100);
}
}
And in the class with main method I have:
MyComponentNew m;
m = new MyComponentNew("Fereastra cu baloane");
m.setVisible(true);
m.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
try {
Thread.sleep(20);
} catch(InterruptedException e) {}
m.changeColor();
The color of the oval remains red.
You need to look at Performing Custom Painting. You kinda have the concept, but your changeColor method isn't going to do anything for you.
Some things to note.
First you need to add a MouseListener. See more at How to Write MouseListeners
Second what you want to do is just have a Color color variable. You use that variable to set the color. Your method changeColor should only change the color and repaint(). Something like
public class MyComponentNew extends JPanel {
private Color color = Color.BLUE;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
}
public void changeColor() {
if (color == Color.BLUE) {
color = Color.RED:
} else {
color = color.BLUE;
}
repaint();
}
}
Third notice how I use JPanel instead of JFrame. This is the preferred approach.
Fourth you should be using Swing and not AWT.
Here's a full example, with those points above
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CircleChangeColor extends JPanel {
private Ellipse2D circle = new Ellipse2D.Double(0, 0, 200, 200);
private Color color = Color.blue;
public CircleChangeColor() {
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
if (circle.contains(e.getPoint())) {
changeColor();
}
}
});
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(color);
g2.fill(circle);
}
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void changeColor() {
if (color == Color.BLUE) {
color = Color.RED;
} else {
color = color.BLUE;
}
repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame frame = new JFrame();
frame.add(new CircleChangeColor());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
The reason is that your paint method will be called periodically by AWT and it will quickly draw over your new blue oval with the original red one. You can get the behavior you want by storing the oval color in a member variable, reading it in the paint method, and changing it in your changeColor method.
public class MyComponentNew extends Frame {
private Color ovalColor;
public MyComponentNew(String title) {
super(title);
setSize(400, 550);
ovalColor = Color.red; // initial oval color
}
#Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(ovalColor); // use whatever the current color is
g2d.fillOval(10, 55, 50, 100);
}
public void changeColor() {
ovalColor = Color.blue; // change color
repaint(); // force redraw with new color
}
}
You need to call the repaint() method on the JFrame, but as the code is, the red oval will be drawn again since the paint-method will be called. You need to alter it something like this:
import java.awt.Graphics2D;
public class MyComponentNew extends Frame{
public Graphics2D g2d;
public Color color = Color.red;
public MyComponentNew(String title) {
super(title);
setSize(400, 550);
}
#Override
public void paint(Graphics g) {
this.g2d = (Graphics2D) g;
this.g2d.setColor(color);
this.g2d.fillOval(10, 55, 50, 100);
//this.g2d.drawLine (WIDTH, WIDTH, WIDTH, WIDTH);
}
public void changeColor (){
color = Color.blue;
this.repaint();
}
}
The color is now an instance variable which is set during the changeColor method.
/Nick
I have an application which has a swing user interface class, which has buttons that send variables to a canvas class like so;
public class createWindow extends JFrame implements ActionListener
{
createCanvas canvas = new createCanvas(10, 10);
JPanel mainPanel = new JPanel();
public createWindow()
{
mainPanel.add(canvas, BorderLayout.CENTER);
}
}
createCanvas is a class which declares a paintComponent;
public class createCanvas extends JPanel
{
int xValue;
int yValue;
int xCoordinate;
int yCoordinate;
public createCanvas(int x, int y)
{
xValue = x;
yValue = y;
}
public void setXCoordinate(int x)
{
xCoordinate = x;
}
public void setYCoordinate(int y)
{
yCoordinate = y;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawGrid(g, this.xValue, this.yValue);
g.fillArc(xCoordinate, yCoordinate, 6, 6, 0, 360);
}
public drawGrid(Graphics g, int xLength, int yLength)
{
//creates a grid that is xLength x yLength
}
}
However, I also have a selection of Objects which I want to have a .draw() function, which can use the paintComponent in createCanvas.
The problem is, of course, when I need to draw the node on the grid, I can set the coordinates, but how do I display the node on the canvas I declared in createWindow?
public class Node()
{
int xCoordinate;
int yCoordinate;
//Suitable constructors, sets, gets
public void draw()
{
createCanvas canvas = new createCanvas();
canvas.setXCoordinate(this.xCoordinate);
canvas.setYCoordinate(this.yCoordinate);
canvas.repaint();
}
}
So, I am wondering if there is a way for me to keep what I have drawn on the canvas in createWindow, as well as what I draw in my Object class.
Thanks.
What you want to do is have the draw method in your object take a Graphics argument. This Graphics object will be the same Graphics context in your paintComponent method. You can create the object in your JPanel class. Something like this
public class Circle {
int x, y;
public Circle(int x, int y) {
this.x = x;
this.y = y;
}
public void drawCirlce(Graphics g) {
g.fillRect(x, y, 50, 50);
}
}
Then in you JPanel class
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}
You can have a setter for the x and y in your Circle class. You should change them somewhere in your JPanel class then call repaint() afterwards. You could move it with the press of a key or you can animate it with a java.util.Timer. For example
With a Timer
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
public CirclePanel() {
Timer timer = new Timer(50, new ActionListener(){
#Override
public void actionPerfomed(ActionEvent e) {
circle.x += 10;
repaint();
}
});
timer.start();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}
With a key binding
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
public CirclePanel() {
InputMap inputMap = getInputMap(JComponent.WHEN_FOCUSED_IN_WINDOW);
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "moveRight");
getActionMap().put("moveRight", new AbstractAction(){
public void actionPerformed(ActionEvent e) {
circle.x += 10;
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}
With a button press
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
public CirclePanel() {
JButton button = new JButton("Move Right");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
circle.x += 10;
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}