I create an object called "City"
City city = new City (name, rec, g);
The object's constructor looks like this:
public City (String name, Rectangle r, Graphics g){
this.name = name;
this.r = r;
this.g = g;
}
By creating this object i also draw an oval on an uploaded picture, and set it's colour to BLUE. Here's how I draw the object:
g = (Graphics2D) window.lblNewLabel.getGraphics();
g.setColor(Color.BLUE);
g.fillOval(mouseX, mouseY, 15, 15);
I would like to be able to change that colour later, after clicking on the oval itself.
I try to call this function, but it doesn't work:
public void isClicked(){
clicked = true;
this.color = Color.RED;
this.g.setColor(Color.PINK);
}
How to change a colour of an existing object?
Using getGraphics() on a component causes a transient graphics Object to be used on the component itself. Any subsequent calls to repaint will erase the painting done using that object.
Change the color by overriding the paintComponent method. Save the Color variable as a class member variable and use it to determine the oval color in the method.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(savedColor);
g.fillOval(mouseX, mouseY, 15, 15);
}
Don't use getGraphics() to do painting, that painting is only temporary and will be lost the next time Swing determines a components needs to be repainted.
Check out Playing With Shapes for other ideas on doing painting.
You could use a ShapeIcon which allows you to change the color of the icon. The icon could be painted in the paintComponent() method of your label.
Or you could use ShapeComponent which uses a ShapeIcon. Then you can just add the component to the label like any other component.
I would like to be able to change that colour later, after clicking on the oval itself
The ShapeIcon would be added to a JLabel. Then you can just add a MouseListener to the label of the ShapeComponent to change the color of the icon.
When you have drawn objects with a Graphics object, they are then rendered on the screen. You can't change the color of them directly, instead you will have to repaint your graphics any time when you want to change them. If you want to keep track of the colors for the objects, you will have to store the data in some kind of variable and use it when drawing.
Related
I'm making a space game that renders objects onto a JPanel.
These objects' render method is called in my Space class.
I have 2 objects, alienShip and myShip with respective classes. Each class has a render method. I can't get both ships to render onto my JPanel simultaneously, it's either one or the other. I only see the object that calls the .render(g2) method first.
SPACE CLASS:
spaceImage=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
foregroundImage=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//create the space Image background and instantiate ships (myShip, alienShip)
//Below render() method is called in my Game class using a standard game loop with
update method and rendor method.
public void render(Graphics2D g) {
Graphics2D g2=(Graphics2D) foregroundImage.getGraphics();
g2.drawImage(spaceImage, 0, 0, null);
myShip.render(g2); <---alienShip does not appear, only myShip.
alienShip.render(g2); <---If I swap these 2 commands, then alienShip appears,
and myShip does not
g.drawImage(foregroundImage, x, x, null);
}
ALIENSHIP AND MYSHIP CLASS:
public void render(Graphics2D g) {
g.drawImage(shipImage, x, y, null);
g.dispose();
}
I've tried to create a Drawable interface, and loop through all drawable objects calling DrawableObject.render(g2), but doesn't fix it. Furthermore, I have bullets that DO rendor simultaneously with myShip.
myShip and alienShip does extend an abstract class called Ship as well. Hope this makes sense.
You're .dispose()ing the graphics object after drawing one item, then trying to draw another item with it.
I'm writting my first game and i want to add the name of the user to the high score chart. What is the best way to get the input from the user? except using JOption.
Needless to specify that i am drawing my game continuously. Maybe i can use JTextField?
Assuming you are rendering your game onto a JComponent, yes you can just add a JTextField onto your renderer component. Or you can render your own text field if you want to customize the look of everything.
To do a custom renderer:
Somewhere in your code, store the location of the text input box.
Rectangle r = new Rectangle(200,200,250,30);
String text = "";
In your rendering code:
public void paintComponent(Graphics g){
g.setColor(Color.blue);
g.fillRect(r.x, r.y, r.width, r.height);
g.setColor(Color.black);
// You can play with this code to center the text
g.drawString(text, r.x, r.y+r.height);
}
Then you just need to add a keylistener somewhere in your constructor.
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
text+=e.getKeyChar();
//you might not need this is you are rendering constantly
repaint();
}
});
Here is my paint method.
public void paint(Graphics pane)
{
pane.setColor(Color.black);
pane.drawRect(x, y-HEIGHT, WIDTH, HEIGHT);
if(name!=null)
pane.drawString(getName(), x, y-50);
}
}
I would like for the string returned from getName() method to be bounded within the rectangle I have created, rather than just starting where the rectangle starts then writing over the edge.
You can use the Graphics setClip() method to set the clipping pane so the text will be within the rectangle, however, any excess will simply be clipped off. In order to get it to fit perfectly you will have to calculate the best font size. Check out the FontMetrics class to help you with the calculations.
Ok dear folks, i've got this question and i don't really know a certain way to solve it.
I'm doing like a "Paint application" in java, i know everything is ready, but I need to paint the shapes with Computer Graphics Algorithms.
So, the thing is, once the shape is painted in the container how could I convert it like sort of an "Object" to be able to select the shape and move it around (I have to move it with another algorithm) I just want to know how could I know that some random point clicked in the screen belongs to an object, knowing that, I would be able to fill it(with algorithm).
I was thinking that having a Point class, and a shape class, if i click on the screen, get the coordinates and look within all the shapes and their points, but this may not be very efficient.
Any ideas guys ?
Thanks for the help.
Here is some of my code:
public class Windows extends JFrame{
private JPanel panel;
private JLabel etiqueta,etiqueta2;
public Windows() {
initcomp();
}
public void initcomp()
{
panel = new JPanel();
panel.setBounds(50, 50, 300, 300);
etiqueta = new JLabel("Circulo Trigonometrico");
etiqueta.setBounds(20, 40, 200, 30);
etiqueta2 = new JLabel("Circulo Bresenham");
etiqueta2.setBounds(150, 110, 200, 30);
panel.setLayout(null);
panel.add(etiqueta);
panel.add(etiqueta2);
panel.setBackground(Color.gray);
this.add(panel);
this.setLayout(null);
this.setVisible(true);
this.setSize(400,400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.red);
g2d.setStroke(new BasicStroke(2));
dibujarCirculo_bresenham(g2d, 50, 260, 260);
dibujarCirculo_trigonometrico(g2d, 50, 130, 200);
}
/*This functions paints a Circle*/
public void dibujarCirculo_trigonometrico(Graphics g,int R,int xc,int yc)
{
int x,y;
for (int i = 0; i < 180; i++) {
double angulo = Math.toRadians(i);
x = (int) (Math.cos(angulo)*R);
y = (int) (Math.sin(angulo)*R);
g.drawLine(x+xc, y+yc, x+xc, y+yc);
g.drawLine((-x+xc), (-y+yc), (-x+xc), (-y+yc));
}
}
I assume that any image is a valid (isn't constrained to a particular set of shapes). To get an contiguous area with similar properties, try using a flood fill.
To colour in or move a particular shape around, you can use flood fill to determine the set of pixels and manipulate the set accordingly. You can set a tolerance for similar hue, etc so that it's not as rigid as in Paint, and becomes more like the magic selection tool in Photoshop.
There are a couple of approaches to take here depending on what precisely you want.
1) is to have objects, one for each drawn thing on screen, with classes like Circle and Rectangle and Polygon so on. They would define methods like paint (how to draw them on screen), isCLickInsideOf (is a click at this point on screen contained by this shape, given size/position/etc?) and so on. Then, to redraw the screen draw each object, and to test if an object is being clicked on ask each object what it thinks.
2) is, if objects have the property of being uniform in colour, you can grab all pixels that make up a shape when the user clicks on one of the pixels by using a floodfill algorithm. Then you can load these into some kind of data structure, move them around as the user moves the mouse around, etc. Also, if every object is guaranteed to have a unique colour, you can test which object is being clicked on by just looking at colour. (Libraries like OpenGL use a trick like this sometimes to determine what object you have clicked on - drawing each object as a flat colour on a hidden frame and testing what pixel colour under the mouse pointer is)
Hello dear fellow stackoverflow users,
I got a simple hack where I get my long wanted round corners on a JTextField.
I found that I could subclass JTextField and override paintComponent(Graphics g)
In that regard I could edit the following:
change the border from standard border to BorderFactory.createEmptyBorder().
change the look on the textfield from rectangular to roundrectangular.
change the offset for the text so it wasn't near the round border. (override getInsets())
Now I'm battling with the following issues:
Changing the selection size
When USER change the plaf to e.g. Nimbus then the look on the subclassed JTextField is ruined, by that I mean Nimbus painting routines is preferred over mine. So I get a mix of Nimbus and my round borderpainting.
So in very short, does any of you know how I dissect the JTextField with the various issues, written above?
Written is my sample code for making rounded borders in a custom class JTextField within the constructor setBorder(BorderFactory.createEmptyBorder()) and setOpaque(false);:
#Override
public Insets getInsets()
{
Insets insets = super.getInsets();
insets.left += 10;
return insets;
}
#Override
public Insets getInsets(Insets insets)
{
return insets;
}
#Override
public void paintComponent(Graphics g)
{
Graphics2D g2 = Graphics2D)g.create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.6f));
RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0,0,getWidth(),getHeight(),10,10);
Paint backgroundBrush = new GradientPaint(0,0,new Color(0x383838),0,getHeight(),new Color(0xCECECE).darker());
Shape oldClip = g2.getClip();
g2.setPaint(backgroundBrush);
g2.clip(r2d);
g2.fillRect(0,0,getWidth()-1,getHeight()-1);
g2.setClip(oldClip);
g2.setColor(Color.black);
g2.drawRoundRect(0,0,getWidth()-1,getHeight()-1,10,10);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_PURE);
g2.dispose();
super.paintComponent(g);
}
I would think you should be creating a custom Border for this. Then you can control the insets and do the painting in the Border, instead of the paintComponent() method of the text field.
I was having the same issue, and found that calling
setBackground(new Color(0,0,0,0))
on the text field class cleared it up. I think that it is not making the background non opaque even if you declare the widget non opaque.