I'd like to draw pixels on a window with mouse input - java

I've done days of searching for a way to draw pixels to a window in java with mouse capture. I'm looking for some framework I can just plug in. It seems like it would be so simple... Any help will be greatly appreciated.
(EDIT)
Here is some non-working code.
public class Base extends JPanel implements MouseMotionListener {
public static void main(String[] args) {
new Base();
}
final static int width = 800;
final static int height = 600;
BufferedImage img;
Base() {
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
JFrame frame = new JFrame();
frame.addMouseMotionListener(this);
frame.add(this);
frame.setSize(width, height);
frame.setEnabled(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
Graphics g = img.getGraphics();
g.drawRect(1, 1, width - 2, height - 2);
g.dispose();
repaint();
}
#Override
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}

See comments in the code.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class Base extends JPanel implements MouseMotionListener {
public static void main(String[] args) {
new Base();
}
final static int width = 400;
final static int height = 300;
BufferedImage img;
Base() {
img = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB_PRE);
// do in preference to setting the frame size..
setPreferredSize(new Dimension(width, height));
JFrame frame = new JFrame();
this.addMouseMotionListener(this); // INSTEAD OF THE FRAME
frame.add(this);
//frame.setSize(width, height); DO INSTEAD...
frame.pack();
//frame.setEnabled(true); REDUNDANT
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // good call!
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
Graphics g = img.getGraphics();
g.setColor(Color.RED); // SET A COLOR
g.drawRect(1, 1, width - 2, height - 2);
// DO SOMETHING UGLY
g.setColor(Color.blue);
Point p = e.getPoint();
g.fillOval(p.x,p.y,5,5);
g.dispose();
repaint();
}
#Override
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}

Use a local BufferedImage on which you want to draw. Add a MouseMotionListener and implement the mouseDragged(MouseMotionEvent evt) method. In that method draw onto the BufferedImage by doing something like this:
// Assume img is your BufferedImage
Graphics g = img.getGraphics();
g.drawRect(evt.getX()-1, evt.getY()-1, 3, 3);
g.dispose();
// repaint your swing component
repaint();
And in your overrided paintComponent(Graphics g) method, draw like this:
g.drawImage(img, 0, 0, null);
Initialize your BufferedImage like this:
img = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
// Assuming `this` is your swing component

Related

How do you create a gradient for JPanel? Also, how do you call a class within a class in Java?

I am making a Java GUI and I have searched the internet for 2 hours on how make a gradient for a JPanel. The code below is that I have, but when run the gradient does not show. What is wrong?
I've tried many other posts from similar questions on this throughout the Internet but they don't work. I've tried numerous versions, but I also don't exactly know how to run a class within a class. Can someone help me please?
class TestPanel extends JPanel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int w = getWidth();
int h = getHeight();
Color color1 = Color.BLUE;
Color color2 = Color.GREEN;
GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
}
} //this is nested within the main class
//some code
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CreateGUI cg = new CreateGUI();
cg.create(); //previous method (not mentioned here)
CreateGUI.TestPanel tp = cg.new TestPanel(); //problem
JPanel panel = new JPanel();
f.add(panel);
f.setSize(800, 600);
f.setLocationRelativeTo(null);
f.getContentPane().setLayout(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
I expect there to be a gradient but there is none; the background of the JPanel is still white
The instance of TestPanel is never added to anything
null layouts will prevent the component from been sized and positioned, so you won't see anything even if your did the previous step
You should, unless you're adding child components to it, provide a sizing hint, so that the layout managers have something to work with.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class TestPanel extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int w = getWidth();
int h = getHeight();
Color color1 = Color.BLUE;
Color color2 = Color.GREEN;
GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
g2d.dispose();
}
}
}

Animations and SwingUtilities.invokeLater

I would like to use the method SwingUtilities.invokeLater so that all the Swing components of my program are updated by the event dispatch thread, since it is a good practice.
But if I wrap all the code of the main method in SwingUtilities.invokeLater(new Runnable { public void run() { /* code */ }}); the window freezes (which is normal since my code has an animation loop that takes a few seconds to complete). Where should I put that SwingUtilities.invokeLater method?
Program code (without the SwingUtilities.invokeLater method)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.Rectangle2D;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
int width = 854;
int height = 480;
String title = "Test";
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
JFrame frame = new JFrame();
JPanel panel = new JPanel() {
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.drawImage(bufferedImage, 0, 0, null);
}
};
frame.add(panel);
frame.getContentPane().setPreferredSize(new Dimension(width, height));
frame.pack();
frame.setTitle(title);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
int size = height/3;
int x = -size;
while (x <= width) {
Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
graphics2D.setColor(Color.RED);
graphics2D.fill(new Rectangle2D.Double(x, 0, size, size));
graphics2D.setColor(Color.GREEN);
graphics2D.fill(new Rectangle2D.Double(x, size, size, size));
graphics2D.setColor(Color.BLUE);
graphics2D.fill(new Rectangle2D.Double(x, 2 * size, size, size));
graphics2D.dispose();
panel.repaint();
++x;
try {
Thread.sleep(10);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
frame.dispose();
}
}
Program screenshot
This is an animation in which the three coloured strips are gradually stretching to the right edge of the window.
Here is that self-contained code (good call on posting that, BTW) updated to use a Timer as suggested by #MadProgrammer. In order to access the x variable, it was moved into the action listener defined for the timer. In order to access the Timer from within the action listener, it was moved to being a class attribute. The latter meant it was easier to move the bulk of the code into a constructor for an instance of the object.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class Test {
Timer timer;
Test() {
int width = 854;
int height = 480;
String title = "Test";
BufferedImage bufferedImage = new BufferedImage(
width, height, BufferedImage.TYPE_INT_RGB);
JFrame frame = new JFrame();
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D graphics2D = (Graphics2D) graphics;
// when you have an ImageObserver, may as well use it
//graphics2D.drawImage(bufferedImage, 0, 0, null);
graphics2D.drawImage(bufferedImage, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width,height);
}
};
frame.add(panel);
frame.pack();
frame.setTitle(title);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
int size = height / 3;
ActionListener animationListener = new ActionListener() {
int x = -size;
#Override
public void actionPerformed(ActionEvent e) {
if (x <= width) {
Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
graphics2D.setColor(Color.RED);
graphics2D.fill(new Rectangle2D.Double(x, 0, size, size));
graphics2D.setColor(Color.GREEN);
graphics2D.fill(new Rectangle2D.Double(x, size, size, size));
graphics2D.setColor(Color.BLUE);
graphics2D.fill(new Rectangle2D.Double(x, 2 * size, size, size));
graphics2D.dispose();
panel.repaint();
++x;
} else {
timer.stop();
frame.dispose();
}
}
};
timer = new Timer(10, animationListener);
timer.start();
}
public static void main(String[] args) {
Runnable r = () -> {
new Test();
};
SwingUtilities.invokeLater(r);
}
}

Java window doesn't repaint properly until I resize the window manually

I am using a quite basic setup with a class extending JPanel, which I add to a JFrame.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
public class PinTestMCVE extends JPanel implements ActionListener{
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
new PinTestMCVE();
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
jf.getContentPane().add(this, BorderLayout.CENTER);
jf.setSize(1250, 950);
jf.setVisible(true);
}
public void paintComponent(Graphics g) {
g.drawImage(loadedImage, 0, 0, this);
}
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
int x = 5;
int y = 7;
GradientPaint redtowhite = new GradientPaint(x, y, Color.red, 200, y, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(x, y, 200, 200, 10, 10));
return image;
}
}
What happens is that INITIALLY the window is painted properly, but once paintComponent is called, a strip of the old image (with the same height as the toolbar panel) is visible below the newly painted images - similar to playing card sticking out from a deck. But then, if I manually resize the window by for instance dragging the border, the background is grayed out as it should.
What is going on and how do I fix this?
As outlined here, you need to pack() the frame before calling setVisible(). You can override getPreferredSize() to specify a suitable initial Dimension. Also consider using a Border. See also Initial Threads.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
public class PinTestMCVE extends JPanel implements ActionListener{
private static final int SIZE = 200;
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PinTestMCVE();
}
});
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(toolbarPanel, BorderLayout.NORTH);
jf.add(this, BorderLayout.CENTER);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(loadedImage, 0, 0, this);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
GradientPaint redtowhite = new GradientPaint(5, 5, Color.red, SIZE, 5, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(5, 5, SIZE - 10, SIZE - 10, 10, 10));
return image;
}
}

How to disable java.awt.Graphics.fillRect(int x, int y, int width, int height)'s effect?

It's the original image:
I use java.awt.Graphics.fillRect(int x, int y, int width, int height) to add a coloured rectangle on the image.
Graphics imageGraphics = image.createGraphics();
Color color = new Color(0,0,0,100);
imageGraphics.setColor(color);
imageGraphics.fillRect(0, 0, 800, 600);
So the image has been inverted and looks like this:
After that,I want to clear the black transparent rectangle partly and show the original image.
imageGraphics.clearRect(100,100,100,100);
But the effect is like this:
What my requirement is:
I want to know why it doesn't work and is there any other way to realize it?
Remember, painting is destructive. It might be possible to use AlphaComposite to achieve this result, but a simpler solution might be to simple constructive a compound shape and paint that instead.
The following example creates two Rectangles, one been the area we want to fill and one been the area we want to show, the second is then subtracted from the first (to create the window) and then the result is painted on top of the image
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShowArea {
public static void main(String[] args) {
new ShowArea();
}
public ShowArea() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
public TestPane() {
try {
img = ImageIO.read(new File("sample.png"));
Rectangle bounds = new Rectangle(0, 0, img.getWidth(), img.getHeight());
Rectangle clip = new Rectangle(150, 10, 100, 100);
Area area = new Area(bounds);
area.subtract(new Area(clip));
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.BLACK);
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fill(area);
g2d.dispose();
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
g2d.drawImage(img, x, y, this);
g2d.dispose();
}
}
}
If I were doing some kind of paint program, I would do this all within the paintComponent method or in some way that it didn't effect the original image, otherwise you've basic destroyed the image until you re-load it
Another solution might be to take a copy of the original area you want to keep and repaint it back on top after, for example...
img = ImageIO.read(new File("sample.png"));
// This is the portion of the image we want to save...
BufferedImage cutout = img.getSubimage(150, 10, 100, 100);
// This is the area we want to paint over...
Rectangle bounds = new Rectangle(0, 0, img.getWidth(), img.getHeight());
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.BLACK);
// Save the current Composite so we can reset it...
Composite comp = g2d.getComposite();
// Apply the composite and fill the area...
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fill(area);
// Reset the composite
g2d.setComposite(comp);
// Draw the part of the image we saved previously...
g2d.drawImage(cutout, 150, 10, this);
g2d.dispose();
You cant do that the way you're trying to.
It can be done by creating a BufferedImage filled with Color(0,0,0,200), then in that image draw rectangle with color Color(0,0,0,200) and then apply it on image.
Remember, that drawing filledRectange is not a "undo operation"- it is written on pixels and it can't be undone.
EDIT
Icon imageIcon = new javax.swing.ImageIcon("image.jpg");
BufferedImage mask = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
BufferedImage image = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
imageIcon.paintIcon(null, image.getGraphics(), 0, 0);
Graphics maskGraphics = mask.getGraphics();
//drawing grey background
maskGraphics.setColor(new Color(0, 0, 0, 120));
maskGraphics.fillRect(0, 0, mask.getWidth(), mask.getHeight());
//drawing black frame
maskGraphics.setColor(new Color(0, 0, 0, 255));
maskGraphics.drawRect(99, 99, 301, 301);
//drawing original image window
maskGraphics.drawImage(image, 100, 100, 400, 400, 100, 100, 400, 400, null);
//apply mask on image
new ImageIcon(mask).paintIcon(null, image.getGraphics(), 0, 0);
//result presentation
label.setIcon(new ImageIcon(image));
Yes this is easily doable. The problem is that any draw operation is destructive, what you see is what you get, the information that was painted upon is lost.
Something like this where you store a subimage, do your paint operation then draw the subimage back on top.
public class Q23709070 {
public static void main(String[] args) {
JFrame frame = new JFrame();
Panel p = new Panel();
frame.getContentPane().add(p);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class Panel extends JPanel {
int w = 400;
int h = 400;
int x = 100;
int y = 100;
BufferedImage img;
BufferedImage subImg;
BufferedImage save;
public Panel() {
try {
img = ImageIO.read(getClass().getResourceAsStream("0qzCf.jpg"));
} catch (IOException e) {
}
subImg = img.getSubimage(x, y, w, h);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Color g2dColor = g2d.getColor();
Color fillColor = new Color(0, 0, 0, 100);
g2d.drawImage(img, 0, 0, null);
g2d.setColor(fillColor);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
g2d.drawImage(subImg, x, y, null);
g2d.setColor(g2dColor);
if (save == null) {
save = new BufferedImage(img.getWidth(), img.getHeight(),
img.getType());
this.paint(save.getGraphics());
try {
ImageIO.write(save, "jpg", new File("save.jpg"));
} catch (IOException e) {
}
}
}
#Override
#Transient
public Dimension getPreferredSize() {
return new Dimension(img.getWidth(), img.getHeight());
}
}
}
Rendering

Errors with setFrame, JSlider

So I am testing out a JSlider for a bigger project and can't get it to work. The slider is supposed to adjust the size of a circle, and it's not working. I thought I might have an issue with the creation of the circle, and I am trying to use setFrame, and it's giving an error saying it's "undefined." Can anyone see why? Since it should take in either float or double as parameters. Or if you can see why it's not adjusting the size of the shape that would help a lot too... Here's what I have:
public class DrawShape extends JPanel{
private float width = 300;
private Shape circle = new Ellipse2D.Float(100, 20, width, 300);
public DrawShape() {
}
public DrawShape(float width) {
this.width = width;
}
public void setWidth(int w) {
this.width = w;
circle.setFrame(100, 20, width, 300);//This is where the error is
}
public void paintComponent (Graphics g) {
super.paintComponents(g);
Graphics2D graphics = (Graphics2D)g;
graphics.setColor(Color.black);
graphics.fill(circle);
}//end paintComponent
}//end class
Class with main:
public class SliderTest extends JFrame{
private static DrawShape circle = new DrawShape();
JSlider slider;
JLabel label;
public SliderTest() {
setLayout(new FlowLayout());
slider = new JSlider(JSlider.HORIZONTAL, 150, 450, 300);//orientation, min val, max value, starting val
slider.setMajorTickSpacing(50);//every 5 integers will be a new tick position
slider.setPaintTicks(true);
add(slider);
label = new JLabel("Current value 300");
add(label);
event e = new event();
slider.addChangeListener(e);;
}//end cons
public class event implements ChangeListener{
public void stateChanged(ChangeEvent e) {
JSlider slider = (JSlider)e.getSource();
int value = slider.getValue();
label.setText("Current Value " + value);
circle.setWidth(value);
repaint();
}//end stateChanged
}//end class event
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("Circle");
frame.add(circle);
frame.setSize(500,400);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JFrame frame1 = new SliderTest ();
frame1.setTitle("Toolbar");
frame1.setSize(300,200);
frame1.setLocation(200,100);
frame1.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame1.setVisible(true);
}
}
Shape does not have a setFrame method. RectangularShape does...
Instead of
private Shape circle = new Ellipse2D.Float(100, 20, width, 300);
You might try using...
private Ellipse2D circle = new Ellipse2D.Float(100, 20, width, 300);
instead...
Your public DrawShape(float width) { constructor is also wrong, as it does not actually do anything.
You should also consider overriding the getPreferredSize method so it can return the width of the shape as a part of the preferred size.
I'm not sure you actually need to maintain the width reference as you can ascertain this from the circle directly...IMHO
For Example
I've not tested this...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
public class DrawShape extends JPanel {
private final Ellipse2D circle = new Ellipse2D.Float(100, 20, 300, 300);
public DrawShape() {
}
public DrawShape(float width) {
circle.setFrame(100, 20, width, 300);
}
public void setWidth(int w) {
circle.setFrame(100, 20, w, 300);
revalidate();
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width = circle.getBounds().width;
return size;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D graphics = (Graphics2D) g;
graphics.setColor(Color.black);
graphics.fill(circle);
}//end paintComponent
}//end class

Categories