I am having two problems here. I'm making a simple program to test, basically when you click the button JColorChooser will pop up and you can choose what color you want your rectangle to be. And the second problem is i cannot position my buttons at BorderLayout.SOUTH or BorderLayout.NORTH Or anywhere. These are my code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI extends JPanel {
private Color a = (Color.WHITE);
private Color b = (Color.WHITE);
private final JPanel panel;
private final JButton ab;
private final JButton bb;
private int x = 1;
private int y = 1;
public GUI() {
panel = new JPanel();
panel.setBackground(Color.WHITE);
ab = new JButton("Choose your first Rectangle color");
ab.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
a = JColorChooser.showDialog(null, "Pick a Color", a);
x = 2;
}
});
bb = new JButton("Choose your second Rectangle color");
bb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
b = JColorChooser.showDialog(null, "Pick a Color", b);
y = 2;
}
});
add(ab, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
add(bb, BorderLayout.SOUTH);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.WHITE);
if (x == 2)
g.setColor(a);
g.fillRect(50, 50, 100, 20);
if (y == 2)
g.setColor(b);
g.fillRect(50, 200, 100, 20);
}
}
And the second problem is i cannot position my buttons at BorderLayout.SOUTH or BorderLayout.NORTH Or anywhere.
JPanel uses a FlowLayout by default, try adding setLayout(new BorderLayout()) before you add any components
setLayout(new BorderLayout());
add(ab, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
add(bb, BorderLayout.SOUTH);
I'm making a simple program to test, basically when you click the button jcolorchooser will pop up and you can choose what color you want your rectangle to be
Okay, I'm "guessing" that once you've selected a color, it's not changing the rectangle color.
Simply add a call to repaint after you've changed the color
ab.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
a = JColorChooser.showDialog(null, "Pick a Color", a);
x = 2;
repaint();
}
}
);
bb = new JButton("Choose your second Rectangle color");
bb.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
b = JColorChooser.showDialog(null, "Pick a Color", b);
y = 2;
repaint();
}
}
);
Related
I am trying to make a rectangle change color with GUI sliders. I know this can be done by changing the background but I'm trying to use repaint.
I know that repaint holds the requests and executes at will almost. I'm trying to find a workaround because I'm stuck.
I've read up on repaint(); and repaintManager and tried manipulating my code but I'm still unable to get my desired output.
Any help would be appreciated.
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
*
*/
public class MyColorChooser2 extends JPanel {
private JFrame frame;
private JLabel redLabel, greenLabel, blueLabel;
private JSlider redSlider, greenSlider, blueSlider;
private JTextField redTextField, greenTextField, blueTextField;
private JPanel redPanel, greenPanel, bluePanel, colorPanel, paintPanel;
private int holdNbr1, holdNbr2, holdNbr3;
DrawPanel rect = new DrawPanel();
public MyColorChooser2() {
JFrame frame = new JFrame();
frame.setTitle("Color Chooser");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set up labels
redLabel = new JLabel("Red:");
greenLabel = new JLabel("Green:");
blueLabel = new JLabel("Blue:");
// set up sliders and register their event handler:
redSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 50);
redSlider.setMajorTickSpacing(10); // create tick every 10
redSlider.setPaintTicks(true); // paint ticks on slider
greenSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 100);
greenSlider.setMajorTickSpacing(10); // create tick every 10
greenSlider.setPaintTicks(true); // paint ticks on slider
blueSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 200);
blueSlider.setMajorTickSpacing(10); // create tick every 10
blueSlider.setPaintTicks(true); // paint ticks on slider
//slider event handling:
SliderHandler sliderHandler = new SliderHandler();
redSlider.addChangeListener(sliderHandler);
greenSlider.addChangeListener(sliderHandler);
blueSlider.addChangeListener(sliderHandler);
//set up textFields and register their event handler:
redTextField = new JTextField(3);
redTextField.setText("50"); //initialize
redTextField.setEditable(false);
redTextField.setText("" + redSlider.getValue());
greenTextField = new JTextField(3);
greenTextField.setText("100"); //initialize
greenTextField.setEditable(false);
greenTextField.setText("" + greenSlider.getValue());
blueTextField = new JTextField(3);
blueTextField.setText("200"); //initialize
blueTextField.setEditable(false);
blueTextField.setText("" + blueSlider.getValue());
// build colorPanel:
// build redPanel:
redPanel = new JPanel();
redPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
redPanel.add(redLabel);
redPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
redPanel.add(redSlider);
redPanel.add(redTextField);
// build greenPanel:
greenPanel = new JPanel();
greenPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
greenPanel.add(greenLabel);
greenPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
greenPanel.add(greenSlider);
greenPanel.add(greenTextField);
// build bluePanel:
bluePanel = new JPanel();
bluePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
bluePanel.add(blueLabel);
bluePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
bluePanel.add(blueSlider);
bluePanel.add(blueTextField);
colorPanel = new JPanel();
colorPanel.add(redPanel);
colorPanel.add(greenPanel);
colorPanel.add(bluePanel);
frame.setLayout(new BorderLayout());
frame.add(rect, BorderLayout.CENTER);
frame.add(colorPanel, BorderLayout.SOUTH);
frame.setPreferredSize(new Dimension(900, 300));
frame.setVisible(true);
frame.pack();
}
public class DrawPanel extends JPanel {
private Color color;
private int red = 50, blue = 100, green = 200;
private Graphics g;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
changeColor();
g.setColor(color);
g.fillRect(10, 10, 880, 200);
g.dispose();
}
public void DrawPanel(Color c) {
color = c;
red = color.getRed();
green = color.getGreen();
blue = color.getBlue();
}
void changeColor() {
color = new Color(red, green, blue);
this.color = color;
}
public void setRed(int r) {
red = r;
changeColor();
}
public void setBlue(int b) {
blue = b;
changeColor();
}
public void setGreen(int g) {
green = g;
changeColor();
}
}
private class SliderHandler implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
JSlider change = (JSlider) e.getSource();
DrawPanel draw = new DrawPanel();
int value;
if (change == redSlider) {
value = change.getValue();
redTextField.setText(String.valueOf(value));
draw.setRed(value);
} else if (change == greenSlider) {
value = change.getValue();
greenTextField.setText(String.valueOf(value));
draw.setGreen(value);
} else if (change == blueSlider) {
value = change.getValue();
blueTextField.setText(String.valueOf(value));
draw.setBlue(value);
}
draw.changeColor();
draw.repaint();
}
}
public static void main(String args[]) {
MyColorChooser2 color = new MyColorChooser2();
}
}
It's not that it isn't doing anything. The problem is that you're stuck, because every time you make a change you're trying to update a different component. You're recreating multiple panels in your state changed.
I've added comments about the changes I've done to make it work properly. If you need more help, just ask. Cheers!
Would you care trying this code:
public class MyColorChooser2 extends JPanel {
private JFrame frame;
private DrawPanel drawPanel;
private JLabel redLabel, greenLabel, blueLabel;
private JSlider redSlider, greenSlider, blueSlider;
private JTextField redTextField, greenTextField, blueTextField;
private JPanel redPanel, greenPanel, bluePanel, colorPanel, paintPanel;
private int holdNbr1, holdNbr2, holdNbr3;
private Color initialColor = Color.RED;
public MyColorChooser2() {
JFrame frame = new JFrame();
frame.setTitle("Color Chooser");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Let DrawPanel choose the initial color. I don't care.
drawPanel = new DrawPanel();
// This way I control what is the initial color
//drawPanel = new DrawPanel(initialColor);
// set up labels
redLabel = new JLabel("Red:");
greenLabel = new JLabel("Green:");
blueLabel = new JLabel("Blue:");
// set up sliders and register their event handler:
redSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, initialColor.getRed());
redSlider.setMajorTickSpacing(10); // create tick every 10
redSlider.setPaintTicks(true); // paint ticks on slider
greenSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, initialColor.getGreen());
greenSlider.setMajorTickSpacing(10); // create tick every 10
greenSlider.setPaintTicks(true); // paint ticks on slider
blueSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 255, initialColor.getBlue());
blueSlider.setMajorTickSpacing(10); // create tick every 10
blueSlider.setPaintTicks(true); // paint ticks on slider
// slider event handling:
SliderHandler sliderHandler = new SliderHandler();
redSlider.addChangeListener(sliderHandler);
greenSlider.addChangeListener(sliderHandler);
blueSlider.addChangeListener(sliderHandler);
// set up textFields and register their event handler:
redTextField = new JTextField(3);
redTextField.setText("50"); // initialize
redTextField.setEditable(false);
redTextField.setText("" + redSlider.getValue());
greenTextField = new JTextField(3);
greenTextField.setText("100"); // initialize
greenTextField.setEditable(false);
greenTextField.setText("" + greenSlider.getValue());
blueTextField = new JTextField(3);
blueTextField.setText("200"); // initialize
blueTextField.setEditable(false);
blueTextField.setText("" + blueSlider.getValue());
// build colorPanel:
// build redPanel:
redPanel = new JPanel();
redPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
redPanel.add(redLabel);
redPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
redPanel.add(redSlider);
redPanel.add(redTextField);
// build greenPanel:
greenPanel = new JPanel();
greenPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
greenPanel.add(greenLabel);
greenPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
greenPanel.add(greenSlider);
greenPanel.add(greenTextField);
// build bluePanel:
bluePanel = new JPanel();
bluePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
bluePanel.add(blueLabel);
bluePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
bluePanel.add(blueSlider);
bluePanel.add(blueTextField);
colorPanel = new JPanel();
colorPanel.add(redPanel);
colorPanel.add(greenPanel);
colorPanel.add(bluePanel);
frame.setLayout(new BorderLayout());
frame.add(drawPanel, BorderLayout.CENTER);
frame.add(colorPanel, BorderLayout.SOUTH);
frame.setPreferredSize(new Dimension(900, 300));
frame.setVisible(true);
frame.pack();
}
private class DrawPanel extends JPanel {
private Color color;
private int red = 255, blue = 0, green = 0;
#Override
protected void paintComponent(Graphics g) {
// I've removed the call to changeColor because it was creating
// an infinite loop of revalidates and repaints.
// Now, the paintComponent just finishes the job it was required to.
super.paintComponent(g);
g.setColor(color);
g.fillRect(10, 10, 880, 200);
}
public DrawPanel() {
this(Color.BLUE);
}
public DrawPanel(Color c) {
color = c;
red = color.getRed();
green = color.getGreen();
blue = color.getBlue();
// I'm calling this first repaint here just to make
// sure the panel is initiated the way we want with
// the given Color
repaint();
}
void changeColor() {
color = new Color(red, green, blue);
// We just need to change the color and call this repaint here
// so that the paintComponent can do its job
repaint();
}
public void setRed(int r) {
red = r;
changeColor();
}
public void setBlue(int b) {
blue = b;
changeColor();
}
public void setGreen(int g) {
green = g;
changeColor();
}
}
private class SliderHandler implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
JSlider change = (JSlider) e.getSource();
int value;
// I've removed this line of code because you were
// recreating the drawingPanel. That's not what you want.
// You want to reuse the same panel.
// DrawPanel draw = new DrawPanel();
if (change == redSlider) {
value = change.getValue();
redTextField.setText(String.valueOf(value));
drawPanel.setRed(value);
} else if (change == greenSlider) {
value = change.getValue();
greenTextField.setText(String.valueOf(value));
drawPanel.setGreen(value);
} else if (change == blueSlider) {
value = change.getValue();
blueTextField.setText(String.valueOf(value));
drawPanel.setBlue(value);
}
// You don't need to call those methods, because the
// changeColor will be called by the settings
// of Red, Green and Blue
// draw.changeColor();
// draw.repaint();
}
}
public static void main(String args[]) {
MyColorChooser2 color = new MyColorChooser2();
}
}
I for some reason, unknown to me, I cannot figure out how to change the color of the ovals. They stay black even though I have set them up to be red and blue. Thanks for any help.
ControlPanel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.JFrame;
public class ControlPanel extends JPanel
{
private BallPanel ball1, ball2;
//declare all your components here
private JButton upR, downR, leftR, rightR, stopR, upB, downB, leftB, rightB, stopB;
private JSlider delayR, delayB;
private BallPanel redC, blueC;
private int DIAMETER = 30;
private JPanel redButtons, blueButtons, sliderR, sliderB, top, bottom, left, canvasCY;
private JLabel redDelay, blueDelay;
public ControlPanel(int width, int height)
{
width = 450;
height = 300;
//create 2 ball panels
redC = new BallPanel(0,10,Color.red,Color.cyan);
blueC = new BallPanel(0,10,Color.blue,Color.yellow);
//create 10 buttons
upR = new JButton("Up Red");
downR = new JButton("Down Red");
leftR = new JButton("Left Red");
rightR = new JButton("Right Red");
stopR = new JButton("Stop Red");
upB = new JButton("Up Blue");
downB = new JButton("Down Blue");
leftB = new JButton("Left Blue");
rightB = new JButton("Right Blue");
stopB = new JButton("Stop Blue");
//create 2 sliders
delayR=new JSlider(SwingConstants.VERTICAL,0,50,25);
delayB=new JSlider(SwingConstants.VERTICAL,0,50,25);
//add the corresponding listener to sliders and buttons
upR.addActionListener(new ButtonListener());
downR.addActionListener(new ButtonListener());
leftR.addActionListener(new ButtonListener());
rightR.addActionListener(new ButtonListener());
stopR.addActionListener(new ButtonListener());
upB.addActionListener(new ButtonListener());
downB.addActionListener(new ButtonListener());
leftB.addActionListener(new ButtonListener());
rightB.addActionListener(new ButtonListener());
stopB.addActionListener(new ButtonListener());
//organize 5 buttons into a panel using grid layout
redButtons= new JPanel(new GridLayout(5,1));
redButtons.add(upR);
redButtons.add(downR);
redButtons.add(leftR);
redButtons.add(rightR);
redButtons.add(stopR);
//organize 5 buttons into a panel using grid layout
blueButtons= new JPanel(new GridLayout(5,1));
blueButtons.add(upB);
blueButtons.add(downB);
blueButtons.add(leftB);
blueButtons.add(rightB);
blueButtons.add(stopB);
//create 2 labels
redDelay = new JLabel("Red Ball Delay");
blueDelay = new JLabel("Blue Ball Delay");
//organize a label and a slider into a panel using border layout
sliderR = new JPanel(new BorderLayout());
sliderR.add(redDelay, BorderLayout.NORTH);
sliderR.add(delayR, BorderLayout.SOUTH);
//organize the panel containing buttons and the panel with a slider
top = new JPanel(new GridLayout(1,2));
top.add(redButtons);
top.add(sliderR);
//organize a label and a slider into a panel using border layout
sliderB = new JPanel(new BorderLayout());
sliderB.add(blueDelay, BorderLayout.NORTH);
sliderB.add(delayB, BorderLayout.SOUTH);
//organize the panel containing buttons and the panel with a slider
bottom = new JPanel(new GridLayout(1,2));
bottom.add(blueButtons);
bottom.add(sliderB);
left=new JPanel(new GridLayout(2,1));
left.add(top);
left.add(bottom);
canvasCY = new JPanel(new GridLayout(2,1));
canvasCY.add(redC);
canvasCY.add(blueC);
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, canvasCY);
setLayout(new GridLayout(0,1));
add(sp);
sp.setVisible(true);
}
//The ButtonListener class defines actions to be taken in case
//each of 10 buttons are pushed.
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
Object action = event.getSource();
//if the up button for the red ball is pushed.
if (event.getSource() == upR)
redC.up();
else if (event.getSource() == downR)
redC.down();
else if (event.getSource() == leftR)
redC.left();
else if (event.getSource() == rightR)
redC.right();
else if (event.getSource() == stopR)
redC.suspend();
if (event.getSource() == upB)
blueC.up();
else if (event.getSource() == downB)
blueC.down();
else if (event.getSource() == leftB)
blueC.left();
else if (event.getSource() == rightB)
blueC.right();
else if (event.getSource() == stopB)
blueC.suspend();
}
} //end of ButtonListener
//The SliderListener defines actions to be taken in case
//each of the 2 sliders is moved by a user
private class SliderListener implements ChangeListener
{
public void stateChanged(ChangeEvent event)
{
}
} //end of SliderListener
}
BallPanel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Color;
import java.awt.Graphics;
public class BallPanel extends JPanel
{
int x;
int y;
Color ballColor;
Color backColor;
Timer timer;
int delay;
int stepX=3;
int stepY=0;
final int CIRCLE_DIAMETER = 20;
public BallPanel(int x, int y, Color ballColor, Color backColor)
{
this.x=x;
this.y=y;
this.ballColor=ballColor;
this.backColor=backColor;
delay=20;
stepX=3;
stepY=0;
timer= new Timer(delay, new MovingBallListener());
timer.start();
repaint();
}
public void up()
{
stepX=0;
stepY=-3;
repaint();
}
public void down()
{
stepX=0;
stepY=3;
repaint();
}
public void left()
{
stepX=-3;
stepY=0;
repaint();
}
public void right()
{
stepX=3;
stepY=0;
repaint();
}
public void suspend()
{
stepX=0;
stepY=0;
repaint();
}
public void setDelay(int delayNum)
{
timer.setDelay(delayNum);
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);
page.setColor(ballColor);
setBackground(backColor);
}
private class MovingBallListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (x > getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)
stepX=-3;
stepY=0;
repaint();
if(x < getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)
stepX=3;
stepY=0;
repaint();
}
}
}
hw12.html
Assignment 12 Applet
I believe it has to do with this in javadocs for setColor
"Sets this graphics context's current color to the specified color. All subsequent graphics operations using this graphics context use this specified color."
So flip this
page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);
page.setColor(ballColor);
to be
page.setColor(ballColor);
page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);
so that you are drawing with ballColor
Alright, I figured out everything that I got but now I am really stuck. Every time you choose a different shape the previously selected one disappears. How do I make it so they don't disappear and stay on the screen until you exit?
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class ShapeStamper extends JFrame{
Random rand = new Random();
public int x;
public int y;
private JPanel panel1, panel2;
private JButton button1, button2, button3, button4;
private int option = 0;
public ShapeStamper(){
super("Shape Stamper!");
panel1 = new JPanel();
button1 = new JButton("Circle");
button2 = new JButton("Square");
button3 = new JButton("Rectangle");
button4 = new JButton("Oval");
button1.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 1;
}
}
);
button2.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 2;
}
}
);
button3.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 3;
}
}
);
button4.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 4;
}
}
);
panel2 = new JPanel();
panel2.setBackground(Color.WHITE);
MouseHandler mouse = new MouseHandler();
setVisible(true);
addMouseListener(mouse);
addMouseMotionListener(mouse);
add(panel2);
panel1.add(button1);
panel1.add(button2);
panel1.add(button3);
panel1.add(button4);
add(panel1, BorderLayout.SOUTH);
setSize(500,500);
setVisible(true);
}
private class MouseHandler extends MouseAdapter implements MouseMotionListener{
#Override
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
repaint();
}
}
public void paint(Graphics g){
super.paintComponents(g);
Graphics2D g2d = (Graphics2D) g;
if(option == 0){
g.setFont(new Font("Serif", Font.BOLD, 32));
g.drawString("Shape Stamper!", 150, 220);
g.setFont(new Font("Serif", Font.ITALIC, 16));
g.drawString("Programmed by: Chris", 150, 230);
}
if(option == 1){
Color randColor1 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor1);
g2d.drawOval(50, 50, 100, 100);
}
if(option == 2){
Color randColor2 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor2);
g2d.drawRect(50, 50, 100, 100);
}
if(option == 3){
Color randColor3 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor3);
g2d.draw(new Rectangle2D.Double(75,50,150,100));
}
if(option == 4){
Color randColor4 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor4);
g2d.draw(new Ellipse2D.Double(50, 25, 100, 50));
}
}
public static void main(String[] args) {
ShapeStamper application = new ShapeStamper();
application.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
You should not be overriding paint of a top level container and then trying to painting over the top of the components you have already added.
The basic problem you will encounter is, the paint system is clever enough that it may not ever call paint of the frame, but simply update the child components directly instead.
Instead, create yourself a custom component, extending from something like JPanel and override it's paintComponent method and perform your custom painting there. Then add this component to your frame.
You will also find the the paint updates are cleaner and won't flicker when updated.
You should also make sure you are calling repaint on this custom component when ever you change one it's options to ensure that changes are painted back to the component
Take a look at Performing Custom Painting for more details.
Also, just to be clear, you should not be calling super.paintComponents from paint (or in fact anywhere except for when you override paintComponents...which there really should be a need to do...)
How can I paint multiple rectangles to a JPanel?
This code here only allows me paint one rectangle at a time. It deletes the previously made rectangle once I start a new one. I need to write a program that paints more than 1 rectangle so it would probably look like a collage of rectangles of different colors.
public class Rectangles extends JFrame implements ActionListener {
int x1, y1, x2, y2;
JPanel main;
JPanel right;
JButton color1;
JButton color2;
JButton color3;
JButton color4;
JButton color5;
JButton color6;
JButton color7;
JButton color8;
JButton color9;
JButton color10;
Canvas left;
public Rectangles() {
main = new JPanel(new BorderLayout(5, 5));
main.setBorder(new EmptyBorder(20, 20, 20, 20));
main.setBackground(new Color(0, 168, 165));
right = new JPanel(new GridLayout(5, 2, 3, 3));
right.setPreferredSize(new Dimension(150, 250));
right.setBackground(new Color(0, 168, 165));
color1 = new JButton();
color1.setBackground(Color.LIGHT_GRAY);
color1.addActionListener(this);
color1.setBorder(new LineBorder(Color.BLACK, 5, false));
color2 = new JButton();
color2.setBackground(Color.BLUE);
color2.addActionListener(this);
color2.setBorder(new LineBorder(Color.BLACK, 5, false));
color3 = new JButton();
color3.setBackground(Color.CYAN);
color3.addActionListener(this);
color3.setBorder(new LineBorder(Color.BLACK, 5, false));
color4 = new JButton();
color4.setBackground(Color.DARK_GRAY);
color4.addActionListener(this);
color4.setBorder(new LineBorder(Color.BLACK, 5, false));
color5 = new JButton();
color5.setBackground(Color.GRAY);
color5.addActionListener(this);
color5.setBorder(new LineBorder(Color.BLACK, 5, false));
color6 = new JButton();
color6.setBackground(Color.GREEN);
color6.addActionListener(this);
color6.setBorder(new LineBorder(Color.BLACK, 5, false));
color7 = new JButton();
color7.setBackground(Color.YELLOW);
color7.addActionListener(this);
color7.setBorder(new LineBorder(Color.BLACK, 5, false));
color8 = new JButton();
color8.setBackground(Color.MAGENTA);
color8.addActionListener(this);
color8.setBorder(new LineBorder(Color.BLACK, 5, false));
color9 = new JButton();
color9.setBackground(Color.PINK);
color9.addActionListener(this);
color9.setBorder(new LineBorder(Color.BLACK, 5, false));
color10 = new JButton();
color10.setBackground(Color.RED);
color10.addActionListener(this);
color10.setBorder(new LineBorder(Color.BLACK, 5, false));
right.add(color1);
right.add(color2);
right.add(color3);
right.add(color4);
right.add(color5);
right.add(color6);
right.add(color7);
right.add(color8);
right.add(color9);
right.add(color10);
left = new Canvas();
left.setPreferredSize(new Dimension(500, 250));
left.setBackground(Color.WHITE);
left.setColor(Color.WHITE);
left.setBorder(new LineBorder(Color.BLACK, 5, false));
main.add(left, BorderLayout.CENTER);
main.add(right, BorderLayout.EAST);
this.add(main);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocation(450,75);
this.setTitle("MARQUEZ Rectangles");
this.setResizable(false);
this.setVisible(true);
}
public static void main(String[] args) {
Rectangles r = new Rectangles();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == color1) {
left.setColor(Color.LIGHT_GRAY);
}
else if(e.getSource() == color2) {
left.setColor(Color.BLUE);
}
else if(e.getSource() == color3) {
left.setColor(Color.CYAN);
}
else if(e.getSource() == color4) {
left.setColor(Color.BLACK);
}
else if(e.getSource() == color5) {
left.setColor(Color.GRAY);
}
else if(e.getSource() == color6) {
left.setColor(Color.GREEN);
}
else if(e.getSource() == color7) {
left.setColor(Color.YELLOW);
}
else if(e.getSource() == color8) {
left.setColor(Color.MAGENTA);
}
else if(e.getSource() == color9) {
left.setColor(Color.PINK);
}
else {
left.setColor(Color.RED);
}
}
}
This class paints the rectangle.
class Canvas extends JPanel implements MouseListener,MouseMotionListener {
private int x,y,x1,y1;
Color color;
public Canvas() {
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void setColor(Color color) {
this.color = color;
}
public void mouseEntered(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
public void mouseDragged(MouseEvent e) {
x1 = e.getX();
y1 = e.getY();
revalidate();
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(x, y, Math.abs(x-x1), Math.abs(y-y1));
}
}
The paint operations we do are 'transient' and will be destroyed the next time the component is painted. To get around that, there are two common techniques.
Store a list of shapes (images, gradients and other painting operations), add the current drawing to the list, and when requested, paint them all.
Draw to a BufferedImage that is painted when requested/needed. See this answer for an example.
Your canvas only paints the most recent rectangle, swing painting works like that, once a paint is requested the previous buffer is cleared. What you need is a List<Rectangle>, every time you select a rectangle with the mouse, add it to the list and in the canvas draw every rectangle in the list. You will also need to save the color of the previous rectangles, either by making a a wrapper class for the rectangle that has color as a field or save that in a list too.
I have two JPanels. The first one contains JButtons and in the second simply we can draw on with the Mouse. The problem is when I click on the JButton and start drawing the JButton also draw in on the JPanel. Please do provide me, with some direction, as to where I am not looking at ?
main class
public class LabelDemo extends JFrame {
JPanel p1 = new JPanel();
painter p2 = new painter();
JButton red = new JButton("red");
JButton blue = new JButton(" blue ");
JLabel lbl = new JLabel("Label");
ImageIcon icon = new ImageIcon("image/YouTube.png");
public LabelDemo() {
setLayout(new BorderLayout());
p1.setBorder(new LineBorder(Color.gray));
//jbt1.setIcon(icon);
p1.add(red);
p1.add(blue);
lbl.setOpaque(true);
lbl.setBackground(Color.yellow);
p1.add(lbl);
p1.setBounds(20, 30, 40, 78);
add(p1,BorderLayout.EAST);
add(p2,BorderLayout.CENTER);
}
public static void main(String[] args){
LabelDemo frame = new LabelDemo();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 400);
frame.setLocationRelativeTo(null);
}
}
innr class
class painter extends JPanel {
int x , y;
boolean isPresed = false;
public void setPainter(int x , int y) {
this.x = x;
this.y = y;
}
public painter() {
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
isPresed = true;
setPainter(e.getX(),e.getY());
repaint();
}
});
}
protected void paintComponent(Graphics g){
Color randomColor = Color.getHSBColor( (float)Math.random(), 1.0F, 1.0F );
if(isPresed){
g.setColor(randomColor);
g.fillOval(x-5, y-5, 10, 10);
}
}
}//end of painter
Ok, as I understood you want to get rid of panel on east (p1 panel) when clicking red or blue button:
package stack;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class LabelDemo extends JFrame {
JPanel p1 = new JPanel();
Painter p2 = new Painter();
JButton red = new JButton("red");
JButton blue = new JButton(" blue ");
JLabel lbl = new JLabel("Label");
ImageIcon icon = new ImageIcon("image/YouTube.png");
public LabelDemo() {
setLayout(new BorderLayout());
p1.setBorder(new LineBorder(Color.gray));
// jbt1.setIcon(icon);
p2.setPreferredSize(new Dimension(600,400));
p1.add(red);
p1.add(blue);
lbl.setOpaque(true);
lbl.setBackground(Color.yellow);
p1.add(lbl);
p1.setBounds(20, 30, 40, 78);
add(p1,BorderLayout.EAST);
add(p2,BorderLayout.CENTER);
red.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
remove(p1);
repaint();
revalidate();
}
});
blue.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
remove(p1);
repaint();
revalidate();
}
});
}
public static void main(String[] args){
LabelDemo frame = new LabelDemo();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class Painter extends JPanel {
int x , y;
boolean isPresed = false;
public void setPainter(int x , int y) {
this.x = x;
this.y = y;
}
public Painter() {
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
isPresed = true;
setPainter(e.getX(),e.getY());
repaint();
}
});
}
protected void paintComponent(Graphics g){
Color randomColor = Color.getHSBColor( (float)Math.random(), 1.0F, 1.0F );
if(isPresed){
g.setColor(randomColor);
g.fillOval(x-5, y-5, 10, 10);
}
}
}//end of painter
Also don't call setSize() method call pack() and setPreferredSize(), I was personaly criticized a few times because of that. Just an annotation.
In your painter pane's paintComponent method, you really should call super.paintComponent first.
Swing reuses the Graphics, so its possible to get old content still in its buffer. If you call super.paintComponent, this will clean it up for
protected void paintComponent(Graphics g){
// Must call super.paintComponent() so the Graphics is updated correctly...
super.paintComponent();
Color randomColor = Color.getHSBColor( (float)Math.random(), 1.0F, 1.0F );
if(isPresed){
g.setColor(randomColor);
g.fillOval(x-5, y-5, 10, 10);
}
}