I want to draw an inscribed circle. A circle that is empty with no fill but making it have a full stroke. My code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package simon;
import java.awt.*;
import java.awt.event.*; //This allows us to detect user input
import java.awt.image.BufferedImage;
import javax.swing.*; //This allows us to use graphical elements, colors, etc.
/**
*
* #author User
*/
public class SimonA {
//First, we create all the elements of our program
//Here are the variables...
public static int score = 0;
public static int color = 0; //0 = yellow, 1 = red, 2 = blue, 3 = green
public static Boolean flash = false; //This is used to make the panel blink
public static Boolean running = false;
//Here are the widgets (objects)....
public static JFrame frame = new JFrame();
public static JPanel buttons = new JPanel();
public static JPanel buttons1 = new JPanel();//These buttons will all be square (the default). Different packages can be used to change the shape
public static JPanel controls = new JPanel();
public static JButton red = new JButton();
public static JButton yellow = new JButton();
public static JButton green = new JButton();
public static JButton blue = new JButton();
public static JButton toggle = new JButton("Start"); //Click this button to see a sample flash
public static JLabel scoreTxt = new JLabel("Score: " + score, SwingConstants.CENTER); //This object (a label element) displays the score variable's value
public static Timer blink = new Timer(600,new Ticker()); //This is used to time the duration of the flash
public static BufferedImage img = new BufferedImage(400, 400, BufferedImage.TYPE_INT_ARGB);
public static Graphics2D g = img.createGraphics();
public static JLabel space = new JLabel();
JPanel panelBgImg = new JPanel() {
public void paintComponent(Graphics g){
g.setStroke(new BasicStroke(8));
g.fillOval(0, 0, 400, 400);
}
};
/*Timers are important for any program in which something "moves" at set durations. In this case, every tenth of
a second, the timer will generate an event. In this case, we are using it to determine that the active tile
will flash for 600ms, or 6/10 of a second. Obvously, then, 1000 makes the timer generate an event once-per-second. */
public static void main (String[] args)
{
frame.setBackground(Color.gray);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //This means that when we close the window with [x] the program ends
frame.setSize(new Dimension(400,400));
frame.setForeground(Color.black);
frame.setTitle("Simon");
frame.setLayout(new BorderLayout()); //Remember this from the LayoutManager test?
buttons.setLayout(new GridLayout(1,2));
buttons1.setLayout(new GridLayout(1,2));//The buttons are placed in this panel, which is set as a 2x2 grid
yellow.setBackground(Color.yellow);
yellow.addActionListener(new YellowPressed()); //This triggers the "procedure" that runs when the yellow button is pressed
yellow.setPreferredSize(new Dimension(200,200));
//Note, the other buttons will take their cue for size from the above statement, since they are all in the same grid
//We do not need to specify dimensions again
red.setBackground(Color.red);
red.addActionListener(new RedPressed());
red.setPreferredSize(new Dimension(200,200));
blue.setBackground(Color.blue);
blue.addActionListener(new BluePressed());
green.setBackground(Color.green);
green.addActionListener(new GreenPressed());
green.setPreferredSize(new Dimension(200,200));
//Adding the four buttons to the panel called "buttons"
buttons1.add(yellow);
buttons.add(red);
buttons.add(green);
buttons1.add(blue);
//The control panel on the bottom is a gride of one row and two columns
controls.setLayout(new GridLayout(2,1));
controls.add(scoreTxt);
controls.add(toggle);
toggle.addActionListener(new ToggleOn());
//We now add the panels to the frame according to the border layout
frame.add(buttons,BorderLayout.NORTH);
frame.add(controls,BorderLayout.CENTER);
frame.add(buttons1,BorderLayout.SOUTH);
//This .pack() method removes any excess whitespace around your elements
//Sometimes it results in a better look, and sometimes not.
frame.pack();
frame.setVisible(true);
}
public static class ToggleOn implements ActionListener {
public void actionPerformed(ActionEvent event)
{
//This toggles the main button between Start and Stop
//If it's running, stop it from running
//If it's not running, start it running
running = !running;
if (running)
{
toggle.setText("Stop");
//To demonstrate how the code might work, a sample flash
color = 3; //Change the color to "active"
blink.start(); //Starts the 6/10 second timer
score += 10;
scoreTxt.setText("Score: " + score);
}
else
{
toggle.setText("Start");
}
}
}
public static class YellowPressed implements ActionListener {
public void actionPerformed(ActionEvent event)
{
//Right now, the buttons just print to the screen
//The "real" program would implement other instructions here
System.out.println("Yellow");
}
}
public static class RedPressed implements ActionListener {
public void actionPerformed(ActionEvent event)
{
System.out.println("Red");
}
}
public static class BluePressed implements ActionListener {
public void actionPerformed(ActionEvent event)
{
System.out.println("Blue");
}
}
public static class GreenPressed implements ActionListener {
public void actionPerformed(ActionEvent event)
{
System.out.println("Green");
}
}
public static class Ticker implements ActionListener {
public void actionPerformed(ActionEvent event)
{
//When the timer triggers, if a button is active,
//set it back to its original color 6/10 of a second later
flash = !flash;
if (flash) //If the button is to be lit, turn it white
{
if (color == 0)
yellow.setBackground(Color.white);
else if (color == 1)
red.setBackground(Color.white);
else if (color == 2)
blue.setBackground(Color.white);
else if (color == 3)
green.setBackground(Color.white);
}
else //Otherwise, change it back to its original color
{
if (color == 0)
yellow.setBackground(Color.yellow);
else if (color == 1)
red.setBackground(Color.red);
else if (color == 2)
blue.setBackground(Color.blue);
else if (color == 3)
green.setBackground(Color.green);
blink.stop();
}
}
}
}
Here is what I am using to create the circle, for some reason it does not create the circle:
JPanel panelBgImg = new JPanel() {
public void paintComponent(Graphics g){
g.setStroke(new BasicStroke(8));
g.fillOval(0, 0, 400, 400);
}
};
First of all, you're never (in the code provided) adding the panelBgImg to any component, so nothing is going to show it (you have to add it to a frame or another panel somewhere).
You should also change your paintComponent method though...
JPanel panelBgImg = new JPanel() {
public void paintComponent(Graphics g){
//Call super method to draw background
super.paintComponent(g);
//Cast to Graphics2D to use setStroke
Graphics2D g2d = (Graphics2D) g;
//Set the color of the circle you want to draw
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(8));
//g2d.fillOval(0, 0, 400, 400);
//Use drawOval instead of fillOval (otherwise it will be filled with the color)
g2d.drawOval(0, 0, 400, 400);
}
};
Related
I am trying to build a bounce game in Java. My project has three classes ie the Main class which creates a new window(frame) where the game buttons and bounce objects are drawn.
The GameInterface class which represents the properties of the frame being drawn and the RightPanel class which I created so that I could override the paint(Graphics) method to draw my bounce object. So far this is what I have managed to draw with the code.
You can see that I have two JPanels, one that holds my buttons and the other one that accepts the drawing of a round ball on it ie RightPanel
I need help with the Button Event listeners to move the ball up and down and when user holds the button down, it needs to keep moving down until reaches the down order, sam for the up button.
The code am using is provided below.
GameInterface class
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class GameInterface extends JFrame {
//we need this panel declaration in the class level for reference from other methods
RightPanel rightpanel;
//define the physical properties of the window
public GameInterface(){
setSize(new Dimension(600, 600));
setResizable(false);
setTitle("Bounce Game");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.black);
//define a new JSplitPane and use it to add two JPanels
JPanel leftpanel= new JPanel();
//add buttons to the left panel programatically
JButton up= new JButton("Move up");
//set the event listeners for the buttons
up.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//move my ball up
//clear and redraw the ball while in a new position, use a timer or
something
}
});
JButton down = new JButton("Move down");
down.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//move my ball down
// rightpanel.getGraphics.fillColor(Color.RED);
}
});
leftpanel.add(up);
leftpanel.add(down);
//add a new RightPanel with a drawn red object
rightpanel= new RightPanel();
JSplitPane splitpane= new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftpanel,rightpanel);
this.add(splitpane);
setVisible(true);
}
}
RightPanel class
import javax.swing.*;
import java.awt.*;
public class RightPanel extends JPanel {
//define the position where the circle will be drawn
private int positionX=150;
private int positionY=150;
//I had an idea where we need a timer and then on delay we
//decrement positionX by 3 for move down but can't figure out how to clear RightPanel
private int radius=100;//as the shape is a circle
//override the paint method to draw the bounce ball on the second panel
#Override
public void paint(Graphics g) {
g.setColor(Color.RED);
g.fillOval(positionX,positionY,radius,radius);
}
}
Main class
public class Main
{
public static void main(String args[]){
new GameInterface();
}
}
How do I add logic to my code to make it move the circle up an down, Thank You.
I tried using a timer object to clear the panel and then redraw the ball in the new position of the ball but it draws a vertical bar, not clearing the original ball drawn.
Never call getGraphics() on a component.
Override paintComponent not paint
Call the super.paintComponent(g) in your override.
Give the RightPanel class setter methods that allow you to change the positionX and positionY locations for drawing,
In the button listener, call an appropriate setter method, and then call repaint() on on the RightPanel instance after changing the positions.
For example:
The key code below is here in the ActionListener where you update the position values and call repaint:
moveRightBtn.addActionListener(e -> {
// get and update the x position
int x = drawOval.getPositionX();
x += DELTA;
// call the setter method
drawOval.setPositionX(x);
// request that Java repaint the JPanel
drawOval.repaint();
});
and in the drawing JPanel's paintComponent method where you call the super's method and draw the oval:
#Override
protected void paintComponent(Graphics g) {
// this is needed to do house-keeping painting, to clear "dirty" pixels
super.paintComponent(g);
// this is needed to draw smooth graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(OVAL_COLOR);
g2.fillOval(positionX, positionY, RADIUS, RADIUS);
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
#SuppressWarnings("serial")
public class MoveCircle extends JPanel {
private static final int DELTA = 5;
private DrawOval drawOval = new DrawOval();
public MoveCircle() {
JButton moveRightBtn = new JButton("Move Right");
moveRightBtn.addActionListener(e -> {
// get and update the x position
int x = drawOval.getPositionX();
x += DELTA;
// call the setter method
drawOval.setPositionX(x);
// request that Java repaint the JPanel
drawOval.repaint();
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(moveRightBtn);
setLayout(new BorderLayout());
add(drawOval);
add(buttonPanel, BorderLayout.LINE_START);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MoveCircle mainPanel = new MoveCircle();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
#SuppressWarnings("serial")
class DrawOval extends JPanel {
private static final int RADIUS = 100;
private static final int PANEL_WIDTH = 600;
private static final int PANEL_HEIGHT = 450;
private static final Color OVAL_COLOR = Color.RED;
private int positionX = 0;
private int positionY = 0;
public DrawOval() {
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
}
public int getPositionX() {
return positionX;
}
public void setPositionX(int positionX) {
this.positionX = positionX;
}
public int getPositionY() {
return positionY;
}
public void setPositionY(int positionY) {
this.positionY = positionY;
}
#Override
protected void paintComponent(Graphics g) {
// this is needed to do house-keeping painting, to clear "dirty" pixels
super.paintComponent(g);
// this is needed to draw smooth graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(OVAL_COLOR);
g2.fillOval(positionX, positionY, RADIUS, RADIUS);
}
}
From my textbook:
"Write an application that extends JFrame and that displays a phrase upside down when the user click a button. The phrase is displayed normally when the user clicks the button again."
Currently I have a String that is drawn using the paint() method and a Graphic object. The String is visible in the JUpsideDown frame and it's upside down and positioned in about the middle of the panel. I've added my button and a actionListener but I think the code in my actionPerformed method is wrong because I'm trying to make the negative font size a positive by multiplying by -1 but it doesn't seem to take effect when I repaint. The String positioned is moved to x = 100 ad y = 100 but the String is still upside down.
Any kind of guidance is appreciated.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
#SuppressWarnings("serial")
public class JUpsideDown extends JFrame implements ActionListener
{
int x = 350;
int y = 100;
int fontSize = -26;
Font font = new Font("Serif", Font.PLAIN, fontSize);
JButton press = new JButton("Flip Text");
String label = "Look at this text, it will flip!";
public JUpsideDown()
{
setTitle("JUpsideDown");
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(press);
press.addActionListener(this);
}
public void paint(Graphics g)
{
super.paint(g);
g.setFont(font);
g.drawString(label, x, y);
}
public void actionPerformed(ActionEvent e)
{
fontSize = fontSize * -1;
x = 100;
y = 100;
repaint();
}
public static void main(String[] args)
{
JUpsideDown frame = new JUpsideDown();
frame.setSize(450, 200);
frame.setVisible(true);
}
}
Your logic is right, although you need to instantiate again a new Font object which will encapsulate the new fontsize. This should be performed after the button is clicked inside actionPerformed() method. In this way the behavior of the application will be the expected.
Below you may find a possible solution:
public void actionPerformed(ActionEvent e)
{
fontSize = fontSize * -1;
x = 100;
y = 100;
font = new Font("Serif", Font.PLAIN, fontSize); //added line
repaint();
}
I need to make a java applet that allows the user to paint with the mouse. When the applet is launched, a second window opens that allows the user to select one of 6 different colors to paint with.
First, I wrote code to construct a toolbar window which contains a getcurrentcolor method. I can't seem to link the button press with the color change.
If I launch the applet, the toolbarwindow opens successfully and I'm able to paint in black, so my only problem is selecting a color on the toolbar window and painting in that color.
toolbar code:https://gist.github.com/anonymous/3c053c69112f46d17440
painting applet code: https://gist.github.com/anonymous/aca7929dbcfc08008f30
I gave an approach here for 3 buttons, you can add the rest. The idea is that you keep a currently selected color field and update it each time a button is selected via the ActionListener. A map from the button to the color it represents is not necessary, but makes the code more manageable.
public class ToolBarWindow extends JFrame {
private static Map<JRadioButton, Color> colors = new HashMap<>();
private static Color currentColor = Color.BLACK;
public static void main(String[] args) {
ToolBarWindow frame = new ToolBarWindow();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Colors");
frame.setVisible(true);
}
public ToolBarWindow() {
JPanel jpRadioButtons = new JPanel();
jpRadioButtons.setLayout(new GridLayout(3, 1));
// put the other colors
JRadioButton red = new JRadioButton("red");
JRadioButton black = new JRadioButton("black");
JRadioButton magenta = new JRadioButton("magenta");
red.addActionListener(new MyActionListener());
black.addActionListener(new MyActionListener());
magenta.addActionListener(new MyActionListener());
jpRadioButtons.add(red);
jpRadioButtons.add(black);
jpRadioButtons.add(magenta);
colors.put(red, Color.RED);
colors.put(black, Color.BLACK);
colors.put(magenta, Color.MAGENTA);
add(jpRadioButtons, BorderLayout.WEST);
ButtonGroup bg = new ButtonGroup();
bg.add(red);
bg.add(black);
bg.add(magenta);
}
Color getCurrentColor() {
return currentColor;
}
private class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
currentColor = colors.get(e.getSource());
}
}
}
I get the feeling your professor wants you to make your own. Here is an example I threw together in 10 minutes or so. its very rough and lacking good coding style but if you need to know what is involved, it should be useful. The example code prints out the color whenever you have selected it.
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
public class MyColorChooser extends Component
{
private Color[] colors;
private Color selectedColor;
public MyColorChooser(Color ... colors)
{
this.colors = colors;
this.selectedColor = colors[0];
this.addMouseListener
(
new MouseAdapter()
{
#Override public void mouseClicked(MouseEvent e)
{
int tileWidth = MyColorChooser.this.getWidth();
tileWidth /= MyColorChooser.this.colors.length;
int index = e.getX()/(tileWidth);
MyColorChooser.this.selectedColor = MyColorChooser.this.colors[index];
}
}
);
}
#Override public void paint(Graphics renderer)
{
int width = this.getWidth()/this.colors.length;
int height = this.getHeight();
for(int i = 0; i < this.colors.length; i++)
{
renderer.setColor(this.colors[i]);
renderer.fillRect(width*i,0,width,height);
}
}
public Color getSelectedColor()
{
return this.selectedColor;
}
public static void main(String ... args) throws Throwable
{
JFrame f = new JFrame();
f.setSize(200,100);
f.getContentPane().setLayout(null);
MyColorChooser chooser = new MyColorChooser
(
Color.RED,
Color.GREEN,
Color.BLUE,
Color.YELLOW,
Color.WHITE,
Color.BLACK
);
f.getContentPane().add(chooser);
chooser.setBounds(0,0,200,50);
f.setVisible(true);
Color lastColor = chooser.getSelectedColor();
for(;;)
{
if(!chooser.getSelectedColor().equals(lastColor))
{
lastColor = chooser.getSelectedColor();
System.out.printf("Selected Color:%s\n",lastColor.toString());
}
Thread.sleep(100);
}
}
}
I have 2 buttons, a reset button and a calculate button.
The only purpose of the reset button is to repaint a JPanel called p1.
The purpose of the calculate button is to make a calculation and update a JLabel.
The issue is that when the reset button is pressed, followed by the calculate button, the JPanel is repainted and it should not be (see code below where the repaint method is not present in the ActionListener() for calculateButton).
I am wondering why this is happening, and what I can do to stop the JPanel from being repainted when this button is pressed (the reset button's functions exactly as expected, by repainting the panel).
public class DrawCircles extends JFrame {
//the following are x and y locations of the centers of the circles
int center1X;
int center1Y;
int center2X;
int center2Y;
int center3X;
int center3Y;
public DrawCircles(){
final CircleDraw c = new CircleDraw(); //create a circledraw object to get the area of the triangle between them
final JPanel p1 = new JPanel(); //first panel to hold all other panels making the layout
JPanel buttonPanel = new JPanel();
p1.setLayout(new BorderLayout()); //set the layout of the panel to a border layout
JButton areaTriangle = new JButton("Calculate area of triangle");
JButton perimeterTriangle = new JButton("Calculate perimeter of triangle");
JButton reset = new JButton("Reset");
buttonPanel.setLayout(new BoxLayout(buttonPanel,0));
buttonPanel.add(areaTriangle);
buttonPanel.add(Box.createRigidArea(new Dimension(15,0)));
buttonPanel.add(perimeterTriangle);
buttonPanel.add(Box.createRigidArea(new Dimension(15,0)));
buttonPanel.add(reset); //add a button that says reset
reset.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
p1.repaint(); //redraw the circles and triangle
areaLabel.setText(""); //clear the label
}
});
calculateButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
areaLabel.setText("Area is "+ String.valueOf(2.0*c.getArea()));
}
});
resetButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
areaLabel.setText("");
}
});
add(p1);
}
public class CircleDraw extends JPanel {
int radius;
double s;
double area;
public CircleDraw(){
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Random rand = new Random(System.currentTimeMillis());
center1X=rand.nextInt(507);
center1Y=rand.nextInt(320);
center2X=rand.nextInt(507);
center2Y=rand.nextInt(320);
center3X=rand.nextInt(507);
center3Y=rand.nextInt(320);
//draw the 3 circles
g.drawOval(center1X, center1Y, 100,100);
g.drawOval(center2X, center2Y,100,100);
g.drawOval(center3X, center3Y, 100, 100);
//connect the centers of the circles with lines
g.drawLine(center1X+50, center1Y+50, center2X+50, center2Y+50);
g.drawLine(center2X+50, center2Y+50, center3X+50, center3Y+50);
g.drawLine(center3X+50, center3Y+50, center1X+50, center1Y+50);
}
}
public static void main(String[] args) {
DrawCircles frame = new DrawCircles();
frame.setSize(700,500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
You state:
The issue is that when the reset button is pressed, followed by the calculate button the panel is repainted and it should not be. (See code below where the repaint method is not present in the ActionListener() for calculateButton). I am wondering why this is happening, and what I can do to stop the panel from being repainted when this button is pressed. (The reset button functions exactly as expected, by repainting the panel).
It is impossible to guess what could be wrong based on the code you've posted so far. I urge you to consider creating and posting a minimal example program that allows us to see your problem for ourselves.
But having said that, I will add that you never have full control over when a component is painted or not, since many paintings are driven by the JVM responding to the operating system. This is one reason that program logic should never reside within a paint(Graphics g) or paintComponent(Graphics g) method override.
So your problem is really an XY Problem in disguise. You ask how to control the repainting of a component when you should instead be asking how to get your program logic out of one of the painting methods, and in fact this is my guess at the solution to your problem -- make sure that your painting method is used solely for painting and nothing else.
Edit
Yep, you have program logic within the paintComponent method, specifically this code:
Random rand = new Random(System.currentTimeMillis());
center1X=rand.nextInt(507);
center1Y=rand.nextInt(320);
center2X=rand.nextInt(507);
center2Y=rand.nextInt(320);
center3X=rand.nextInt(507);
center3Y=rand.nextInt(320);
Get it out of paintComponent and in its own method that will allow you to control when it is called.
Edit 2
For example, you could do this:
public class CircleDraw extends JPanel {
private int radius;
private double s;
private double area;
private Random rand = new Random(); // make this a field
// call this when you want to change the random images
public void randomizeDrawing() {
center1X = rand.nextInt(507);
center1Y = rand.nextInt(320);
center2X = rand.nextInt(507);
center2Y = rand.nextInt(320);
center3X = rand.nextInt(507);
center3Y = rand.nextInt(320);
repaint();
}
// and only do painting in paintComponent
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// draw the 3 circles
g.drawOval(center1X, center1Y, 100, 100);
g.drawOval(center2X, center2Y, 100, 100);
g.drawOval(center3X, center3Y, 100, 100);
// connect the centers of the circles with lines
g.drawLine(center1X + 50, center1Y + 50, center2X + 50, center2Y + 50);
g.drawLine(center2X + 50, center2Y + 50, center3X + 50, center3Y + 50);
g.drawLine(center3X + 50, center3Y + 50, center1X + 50, center1Y + 50);
}
Ok so I have my main class which got some buttons one for a triangle and the other for an
oval and boxes.
And i got a button for ColorChooser I want to click on it and ColorChooser show up. I have
the class for the oval and triangles and ColorChooser and i set each one of them to a mode
in my main program.
So this is my main program with only the boxes and ColorChooser:
As you can see im using modes for each button and i set mode 4 for ColorChooser
If you want me to add the box class or the ColorChooser class i will if it is not making
sense. I just dont want it to be any longer.
This is my main program:
import java.awt.*;
import java.util.ArrayList;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
public class Kaleidescope extends JFrame implements MouseListener, ActionListener,
MouseMotionListener
{
Box b;
ArrayList<Box> boxes; // list of boxes
ColorChooser oo;
ColorChooser[] colors;
int colorCount;
// Buttons
JButton boxButton;
JButton ColorButton;
int x1, y1; // mousePressed
int w1, z1; // mouseEntered
int mode =1; // 1 = line, 2= boxes, 3 = oval, 4= text, 5 = SG, twoLines = 7.
public static void main( String[] args )
{
System.out.println("hi there.");
new Kaleidescope();
}
public Kaleidescope()
{
setDefaultCloseOperation( EXIT_ON_CLOSE );
addMouseListener(this);
addMouseMotionListener(this);
boxes = new ArrayList<Box>();
colors = new ColorChooser[20];
colorCount = 0;
setLayout( new FlowLayout() );
boxButton = new JButton("Boxes");
add(boxButton);
boxButton.addActionListener( this );
ColorButton = new JButton("Color Chooser");
add(ColorButton);
ColorButton.addActionListener( this);
setSize( new Dimension(500,500) );
setVisible(true);
}
// returns a random color
public Color randomColor()
{
int red = (int)(Math.random()*255);
int green = (int)(Math.random()*255);
int blue = (int)(Math.random()*255);
return new Color(red,green,blue);
}
public void mouseClicked( MouseEvent e )
{
// box
if ( mode == 2)
{
boxes.add(new Box(e.getX(), e.getY(), randomColor()));
}
repaint();
}
//action performed
public void actionPerformed( ActionEvent e )
{
if ( e.getSource()==TriangleButton ) { mode = 1;}
else if ( e.getSource()==boxButton ) { mode = 2;}
else if ( e.getSource()==ovalButton) { mode = 3;}
else if ( e.getSource()==ColorButton) { mode = 4;}
//clear all
else if (e.getSource() == clearButton)
{
boxes.clear();
triangles.clear();
ovals.clear();
}
repaint();
}
public void mouseEntered( MouseEvent e ) { }
public void mousePressed( MouseEvent e ) { }
public void mouseExited( MouseEvent e ) { }
public void mouseReleased( MouseEvent e ) {}
public void mouseMoved( MouseEvent e ) {}
public void mouseDragged( MouseEvent e ){ }
}
public void paint( Graphics g )
{
//draw/paint box triangle and oval
super.paint(g);
for (Box box : boxes)
{
box.drawMe(g);
}
}
}
here is my colorChooser class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.colorchooser.*;
public class ColorChooser extends JPanel implements ChangeListener
{
public static final long serialVersionUID = 1L;
public JColorChooser tcc;
public JLabel banner;
public ColorChooser()
{
super(new BorderLayout());
banner = new JLabel("",JLabel.CENTER);
banner.setOpaque(true);
banner.setPreferredSize(new Dimension(100, 65));
JPanel bannerPanel = new JPanel(new BorderLayout());
bannerPanel.add(banner, BorderLayout.CENTER);
bannerPanel.setBorder(BorderFactory.createTitledBorder("Banner"));
//Set up color chooser for setting text color
tcc = new JColorChooser(banner.getForeground());
tcc.getSelectionModel().addChangeListener(this);
tcc.setBorder(BorderFactory.createTitledBorder("Choose Text Color"));
add(bannerPanel, BorderLayout.CENTER);
add(tcc, BorderLayout.PAGE_END);
}
public void stateChanged(ChangeEvent e)
{
Color newColor = tcc.getColor();
banner.setForeground(newColor);
}
private static void createAndShowGUI()
{
//Create and set up the window.
JFrame frame = new JFrame("ColorChooserDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new ColorChooser();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Start by taking a look at How to Write an Action Listener and How to Use Color Choosers
Basically, attach a ActionListener to the JButton you want to activate the JColorChooser and when the actionPerformed method is called, use inbuilt functionality to show the default chooser window, for example (from the linked tutorial)...
Color newColor = JColorChooser.showDialog(
ColorChooserDemo2.this,
"Choose Background Color",
banner.getBackground());
Updated
Start by adding a Color instance variable to Kaleidescope, this will allow you to maintain a reference to the last chossen color
private Color currentPaintColor = Color.BLACK;
Next, when the ColorButton is pressed, you will want to create some kind of dialog to show the chooser in, this will allow you to wait until the user chooses a color and get the resulting color...
} else if (e.getSource() == ColorButton) {
ColorChooser chooser = new ColorChooser();
int result = JOptionPane.showConfirmDialog(this, chooser, "Color Chooser", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
currentPaintColor = chooser.getChoosenColor();
}
} //clear all
You'll also want to change the stateChanged method in ColorChooser to make it more meaningful...
public void stateChanged(ChangeEvent e) {
Color newColor = tcc.getColor();
banner.setBackground(newColor);
}
Now, the question is, what do you want to do with this new color? Do you want to apply it to all the current shapes you are painting? If so you need to set the color before painting the shapes...
public void paint(Graphics g) {
//draw/paint box triangle and oval
super.paint(g);
g.setColor(currentPaintColor);
for (Box box : boxes)
{
box.drawMe(g);
}
}
Or do you only want to apply the color to new objects added after the change?
You should avoid overriding paint of top level containers, lots of reason, they aren't double buffered, which will cause flickering when they are updated and you will be painting over the top of everything else on the frame and you can potentially paint under the frame borders...
Instead you should use something JPanel and override it's paintComponent method, take a look at Performing Custom Painting for more details
You need to clarify just what you expect a mode = 4 will do with your program. I can understand using JButton presses to set shape modes (object state) that will alter the behavior of your MouseListener, but I don't see how a color chooser will fit into this model, and in fact believe that it likely won't. I don't have the rest of your code, nor do I have the specifics of your assignment, but I'm going to make some recommendations based on guesses, and thus these will necessarily be weak recommendations.
I'm guessing that you want to have a JColorChooser dialog displayed when the color button is pressed.
And that the user then can select a Color that will be the color of the drawn shapes.
If so, then likely you shouldn't have the color chooser button (which should be named colorChooserButton) set a numeric node. Rather, it should open your color choosing dialog, and after the user has selected a color, then you should set a Color field in your drawing class, not the mode value.
Rather the modes should only be used to select an appropriate shape that the MouseListener will use to determine what shape to draw.
Myself, I wouldn't use numeric modes but rather an enum to define this state, but that is probably something you'll learn later in your programming education.
If my assumptions are incorrect, then please clarify them.
As an aside, note that you should not draw in a paint(Graphics g) method, and should not draw directly in the JFrame. Rather you should draw in the paintComponent(Graphics g) method override of a JPanel or JComponent.
Here's a runnable example of how JColorChooser can be used to set the color for different tasks. Feel free to ask questions if you are unclear about anything.
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 javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ColorChooserPaintExample {
private Color color = Color.BLUE;
private ColorPanel colorPanel = new ColorPanel();
public ColorChooserPaintExample() {
final JFrame frame = new JFrame("My Color Chooser Demo");
JButton chooseColor = new JButton("Change Color of Panel");
chooseColor.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
color = JColorChooser.showDialog(frame, "Choose a Color for Panel", color);
colorPanel.repaint();
}
});
frame.add(colorPanel);
frame.add(chooseColor, BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private class ColorPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ColorChooserPaintExample();
}
});
}
}