How to keep some drawings and not others? - java

I couldn't find any other questions like this, but if someone finds a question like it, feel free to mark it as a duplicate.
I am wondering how to keep only some of the drawings that are on screen. As some preface, I am trying to make a small paint like program (I am making this with the Leap Motion). I want it so that if the Z if less than -80 then draw a line that stays on the screen (As if you were clicking the mouse) and if not, then don't draw a line, just show a 'cursor' (A little white dot). The method I am using to draw things to the screen is as follows:
protected void render() {
BufferStrategy bStrategy = getBufferStrategy();
if (bStrategy == null) {
createBufferStrategy(3);
return;
}
Graphics graphics = bStrategy.getDrawGraphics();
{
Drawing.getInstance(graphics).drawBackground(Color.BLACK, getWidth(), getHeight());
{
List<Coordinate> list = Drawing.getInstance(graphics).drawColorBox(3, 25, 25, 0, 50, Color.DARK_GRAY, Color.BLUE);
List<Coordinate> listII = Drawing.getInstance(graphics).drawColorBox(3, 25, 25, 0, 25, Color.DARK_GRAY, Color.RED);
Drawing.getInstance(graphics).drawDot(loc.getX(), loc.getY(), 5, 5, currentColor);
getCollision(list, Color.BLUE, graphics);
getCollision(listII, Color.RED, graphics);
}
}
graphics.dispose();
bStrategy.show();
}
Drawing is another class that just deals with the drawing of items to the screen. If you need the class just ask.
Summary:
I want to draw some lines to the screen, but not others and want to be able to control which ones to draw and not to draw.
If this doesn't make sense just say and I will try and reword it. Any help is appreciated.
~Ryan

I would recommend making a Line class with an isVisible instance variable. Keep track of all the lines in an ArrayList<Line>, and then toggle them on or off with the isVisible variable.

Related

How do I make my JButton count and change my display?

So I'm working on a somewhat interactive painting of a chess game. Basically, for now, there are only 2 buttons: next move and previous move. The next move button adds 1 to the int variable moveNum, and the previous move button subtracts 1 from the int variable moveNum. Basically like this:
int moveNum = 0;
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Next Move"))
{
moveNum++;
Display.instance.repaint();
}
else if(e.getActionCommand().equals("Previous Move"))
{
moveNum--;
Display.instance.repaint();
}
}
I then just have a ton of graphics, one for each value of moveNum. It looks somewhat like this:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.BLACK);
if (moveNum == 0)
{
g2d.fill(new Rectangle2D.Double(0, 0, 10, 10));//just for simplicity
}
else if (moveNum == 1)
{
g2d.fill(new Rectangle2D.Double(0, 0, 10, 10));
g2d.fill(new Rectangle2D.Double(0, 0, 20, 10)); //again for simplicity
}
else if (moveNum ==2)
{
g2d.fill(new Rectangle2D.Double(0, 0, 10, 10));
g2d.fill(new Rectangle2D.Double(0, 0, 20, 10));
g2d.fill(new Rectangle2D.Double(0, 0, 30, 10)); //simplicity
}
...
}
But the graphics are not changing when I press the buttons. What could I be missing?
Update: I have tried to call Display.instance.repaint() after the moveNum stuff, but now I get no graphics at all. What could be the problem?
Update #2: The paint component is being executed because when I put System.out.println("Test"); to the method, it is being printed. I also now see the infinite recursion problem (not sure how I did not see it before). But even after fixing it, I still don't get the graphics I want. I realized that I can get some graphics when I go full-screen for some reason. But the buttons still don't change the graphics. Using the System.out.println("Test"); method, I found that "Test" is printed once when I run the program, two more times when I go full screen and get graphics, and 12 more times when I press the next button. I'm not really sure what's going on there, are my buttons set up incorrectly?
Final update: I do not have a MRE/SSCE, but I have figured out my problem. I have realized I'm one of the biggest idiots in the universe and my problem was capitalization. My buttons were not working because I capitalized the wrong thing in both of them in the segment e.getActionCommand().equals("Next Move")). Anyways, thanks a ton for your help. I don't think I would have found the infinite recursion problem, so special thanks for helping with that.
Try adding component.repaint() after moveNum++; and after moveNum--;.
When component is the component that you want to update.
Also, remove the repaint() inside paintComponent(Graphics g)

My Java polygon is not drawing, despite having seemingly valid vertex coordinates

My teacher is having us write code to draw a logo on the screen using awt, swing, and the graphics class. I decided to draw the google drive symbol, but I am getting stuck on the yellow third.
public class DriveLogo extends JApplet
{
public void init()
{
JRootPane rootPane = this.getRootPane();
rootPane.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
}
public void paint(Graphics g)
{
int num_rect_points = 4;
g.setColor(Color.black);
g.fillRect(0,0,getSize().width, getSize().height);
/*************************************Yellow 1/3**********************************/
//Order of vertices: Left, right, lower-right, lower-left
int p1x1 = 150, p1x2 = 250, p1x3 = 350, p1x4 = 300;
int p1y1 = 25, p1y2 = 25, p1y3 = 280, p1y4 = 280;
int[] poly_1_x = {
p1x1, p1x2, p1x3, p1x4
};
int[] poly_1_y = {
p1y1, p1y2, p1y3, p1y4
};
Polygon yellow = new Polygon(poly_1_x, poly_1_y, num_rect_points);
/*************************************Draw**********************************/
g.setColor(Color.yellow);
g.fillPolygon(yellow);
}
}
This produces the following result:
There should be a yellow rhombus/rectangle slanted to the left. I asked my teacher, and she reviewed my code, but could not isolate the problem, and told me it "should" be working. Should doesn't mean it is however, and this is a rather large grade. Spent most of two class periods and downloaded the project to my home computer to debug, but I just can't seem to figure out what the problem is.
Things I know; the polygon coordinates must be in order, so to draw a rectangle, I cannot list them top-left, bottom-right, bottom-left, top-right, but I can list them top-left, top-right, bottom-right, bottom-left.
Okay, I solved this by experimenting around. For whatever reason, the call to g.fillPolygon(Polygon p) was not working, but when I called g.fillPolygon(poly_1_x, poly_1_y, num_recto_points); it worked properly.

how to draw a black rectangle over Image icon?

in my application I have a cross road picture in the background and I want to draw traffic lights on the top of it (black rectangle with 3 circles)
The problem is, I cannot see the rectangle at all, as if it was under the image or something. And if I switch the order in which the items are painted, I get all black image.
Do you have any idea how this can be solved?I am new to graphics and searched similar questions, but none helped me.
Thank you.
public MainFrame() throws HeadlessException {
super("semafor");
crossroad = new ImageIcon("cross.png");
initFrame();
initComponents();
sem1 = new Semafor(true, 100, 100);
add(sem1);
repaint();
setVisible(true);
}
//here I paint the image
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(crossroad.getImage(), 0, 45, this);
}
//and in class Semafor i paint the actual traffic lights
#Override
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.darkGray);
//and then the circles
}
The first thing I'm noticing is that you are calling <unknown>.getWidth() and <unknown>.getHeight() for the rectangle size. If it's covering the entire image, this suggests that it is getting that width and height from the panel it is being drawn on.
A simple stack trace,
(new Exception).printStackTrace();
or
Thread.dumpStack();
will tell you as much. You could also query the width and height with a System.out call to verify that you're getting the values you're expecting, or, if this really gets out of control, learn to use JUnit and the assert statement. Honestly, though, it looks like you're just accidentally calling the wrong method.

Transparency overlapping in Java

So I'm making a simple pause function in my game, and I want to have a grey transparent background, the problem is, the rectangle keeps overlapping and is just causing a fade out look. I've tried g2.dispose, and it works, but I can't draw anything else over that.
I have my render method, which is being called 60 times a second. (I issume the rectangle is being drawn 60 times a second)
public void render(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(0, 0, 0, 50));
g2.fillRect(0, 0, RPG.getWidth(), RPG.getHeight());
g2.drawImage(paused, 0, 0, null);
}
Thanks!
Edit: I feel like an idiot... I just had to draw my ingame screen underneath that!
If I understand correctly what you mean by "causing a fade out look" (although I'm not sure I do), you want to fill a background with a transparent color without blending the new transparent color with pixels that are already present. You can do this by setting the composite mode to "source":
g2.setComposite(AlphaComposite.Src);
You can set it back to the default "source over destination" rule to return to normal drawing afterwards by doing:
g2.setComposite(AlphaComposite.SrcOver);
Edit: Or perhaps you do want to blend the transparent color, but with the rest of the game graphics and not with itself? In that case, just make sure that you're redrawing the game background each time you draw the transparency over the top, although I'd suggest pausing the 60fps refresh during game pause if nothing on the screen is changing, just to avoid wasting CPU/battery.
Consider trying to create a copy of the Graphics context first and then disposing of it when your finished...
public void render(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(new Color(0, 0, 0, 50));
g2.fillRect(0, 0, RPG.getWidth(), RPG.getHeight());
g2.drawImage(paused, 0, 0, null);
g2.dispose();
}
This way, the changes to the Graphics state remain isolated between the create and dispose calls and don't affect anything else painted after it
Also, remember, unless you are clearing what was previously painted to the Graphics context, it will accumulate on repeated calls.

How to treat a shape painted with an algorithm like an object?

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)

Categories

Resources