I working on a project in which I have to simulate a memory manager and show some memory snapshots. I have created a draw class via examples I have found here in which I override the paintComponet(). Everything draws fine.
I would like to be able to draw a rectangle to represent a memory partition and then overlay another rectangle over top to represent an incoming job (ie Job1 is in this partition3). What seems to occur is that I add the partition first (which will always be the case) and then when I add the job it will sit behind the partition block. Is there a way other than drawing the Job first to shift these after the job is created?
Here is the paint override
#Override public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
// set up rendering to allow anti-aliasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// create the rectangle to represent the memory partition block
// x = address position h = amount of memory (y & w are predefined for the display block)
Rectangle2D rect = new Rectangle2D.Double(x, y, w, h); // create the rectangle
g2d.setPaint(partColor); // set it's color
g2d.fill(rect); // fill it in
// create the transparency for the text
Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .4f);
g2d.setComposite(comp);
// draw the text with color, type and size and center the text in the block created above
g2d.setPaint(Color.black);
g2d.setFont(new Font("Tahoma", Font.PLAIN, 12));
g2d.drawString(text, (int)((w / 2) - (text.length()/2)), (int)h/2);
}
The call to draw is in my window class (this will place the partition in front of the job) but I need to order to be reversed without changing the order of the calls.
// Draw both Text and Block with transparency
DrawPartition part1 = new DrawPartition(Color.blue, 0, 0, 110, 100, "part1");
part1.setBounds(5, 5, 110, 100);
snapPanel.add(part1);
DrawJob job1 = new DrawJob(Color.green, 0, 0, 110, 100, "Job 1");
job1.setBounds(5, 15, 110, 100);
snapPanel.add(job1);
Is there some reason you can't do this?
// Draw both Text and Block with transparency
DrawPartition part1 = new DrawPartition(Color.blue, 0, 0, 110, 100, "part1");
part1.setBounds(5, 5, 110, 100);
DrawJob job1 = new DrawJob(Color.green, 0, 0, 110, 100, "Job 1");
job1.setBounds(5, 15, 110, 100);
snapPanel.add(job1);
snapPanel.add(part1);
A more general answer would be to add a z component to each of your rectangles. Then you can loop through your rectangles in the paintComponent method, drawing them in z order.
Related
How do I get Java graphic location information? do I get the location information of the 2D object that I created? I created the object as follows. I need the location information of these objects.
public void paint(Graphics g) {
//backGround
g.setColor(Color.darkGray);
g.fillRect(1, 1, 400, 400);
//left object
g.setColor(Color.green);
g.fillRect(Pxi, Pyi, 20, 20);
//right object
g.setColor(Color.yellow);
g.fillRect(Pxs, Pys, 20, 20);
g.dispose();
}
g.fillRect (Pxs, Pys, 20, 20) I need the location information of these objects.
If you use g.fillRect(x, y, 20, 20) you draw colored rectangle into your screen (I mean Canvas or JPanel) at x and y position. In your case Pxs and Pys coordinates of drawing in user space.I think you should read this to understand more about Java2D API: https://docs.oracle.com/javase/tutorial/2d/overview/coordinate.html
I am somewhat new to java, and I'm trying to make a game that has large "pixels" that are actually 5*5 pixels large. I have tried to turn the graphics into an image and then resize the image, but it always returns a huge amount of errors. I am implementing ActionListener and using timer to create a game loop, if that means anything important.
I have the variable screen set as a createVolatileImage(160, 160);
public void actionPerformed(ActionEvent e) {
timer.start();
Graphics draw = screen.getGraphics();
draw.setColor(new Color(50, 100, 50));
draw.fillRect(0, 0, 100, 100);
draw.setColor(Color.black);
draw.drawString("Text",10,10);
draw = getGraphics();
draw.drawImage(screen, 0, 0, 800, 800, 0, 0, 160, 160, null);
draw.dispose();
}
So I have this class inside a class which is an implementation of JPanel.
private static class Line extends JComponent {
private static final long serialVersionUID = 1L;
#Override
public void paintComponent(Graphics g) {
System.out.println("Pozvan paintComponent()");
g.setColor(Color.YELLOW);
g.drawLine(20, 20, 100, 20);
super.paintComponent(g);
}
}
This is a snippet of code which creates a single instance of Line:
Line line = new Line();
line.setOpaque(true);
add(line);
I really don't know what I am doing wrong here. When I draw a rectangle, everything is nicely drawn.
when I set the height to remotely big number it works.
The default size of a Swing component is (0, 0). Since the size is 0, there is nothing to paint.
g.drawLine(20, 20, 100, 20);
Using the above information this means your component needs a size of (120, 40). That is, width = 20 + 100 and height = 20 + 20, in order for the component to be painted.
I added line.setBounds(20, 20, 80, 50);
Only part of your line will be painted, since you set the width to 80, not 120.
Read the section from the Swing tutorial on Custom Painting for more information and examples.
Why does this code output two lines that are the same size?
import java.awt.*;
import javax.swing.*;
public class G2Scale extends JPanel{
public static void main(String args[]) {
G2Scale g = new G2Scale();
g.setPreferredSize(new Dimension(200, 200));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(g);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLUE);
g2.scale(0.5, 1.0);
g2.drawLine(5, 50, 100, 50);
g2.setColor(Color.GREEN);
g2.scale(1.0, 1.0);
g2.drawLine(5, 100, 100, 100);
}
}
I would expect these lines to be different sizes because they are scaled differently. From what I am seeing I am thinking that the scale is based off of the previous scale. Am I right about this?
If this is true, how would I get the second line to be scaled to what I thought it should be?
Thanks
All methods you call on a Graphics object that don't output something but instead change a property of it (like setColor, setFont, and so on), are stored in the context of the graphics object. Actually, you should think of a Graphics instance as a graphics context that contains and abstract all the information you need to draw into the screen.
So basically, yes, your second scale is based on the first, since the first one changes the graphics context and the second one acts on top of it.
There're two ways to change this behavior:
Reset the state your Graphics instance by aplying the opposite of your first change (in this case, the inverse scalling).
Make a copy of the Graphics object before applying any context change.
I'm more inclined to the second option, but here're some examples of both:
Graphics2D g2 = (Graphics2D) g;
// resetting the context state
g2.scale(0.5, 1.0);
g2.drawLine(5, 50, 100, 50);
g2.scale(2, 1.0);
// using a copy of the context
// note: casting is mandatory since 'create' returns a Graphics object
Graphics2D g2copy = (Graphics2D)g2.create();
g2copy.scale(1.0, 1.0);
g2copy.drawLine(5, 100, 100, 100);
// this one doesn't have any scale applied
g2.drawLine(5, 150, 100, 150);
I'm drawing a tab in a user interface. I have the outline as I want it. How do I fill the area?
This is the code that draws the border of the tab:
val g2 = g.asInstanceOf[Graphics2D]
g2.translate(x, y)
val q = new CubicCurve2D.Float
q.setCurve(0, h, 8, h, 6, 0, 16, 0)
g2.setColor(Color.RED)
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON)
g2.draw(q)
val end = w - 8
g2.drawLine(17, 0, end, 0)
q.setCurve(end, 0, end+10, 0, w, h, w + 8, h)
g2.draw(q)
and this is the line it draws (the red one): image
I would like to be able to fill the inside of the red line.
I don't know Scala, but in Java 2D, the Graphics2D object can fill or draw the outline of any Shape object. For some arbitrary shape you would define it with GeneralPath object, such as:
GeneralPath path = new GeneralPath();
path.lineTo(10, 10);
path.lineTo(0, 10);
path.lineTo(0, 0);
graphics.setColor(Color.RED);
graphics.fill(path);
The GeneralPath object also has methods for drawing bezier curves and quads, so you would draw the path and then choose to fill or draw the outline of it.
Added new link to GeneralPath