Text quality in processing - java

Why does the text quality in Processing not look as good as Flash? In general it looks slightly grainy, and hard to read.

I had this problem as well. I found that if you continually overwrite the text (in the draw loop for example) without 'wiping' the underlying surface (by calling background in the draw loop for example) the text becomes jagged.
I think this is because the semi-transparent corners on the letters due to antialiasing get written over and over until they become fully opaque.
Take a look at this example, (you will have to create a font 'ArialMT-20')
PFont fontA;
void setup() {
size(300, 100);
fill(0);
fontA = loadFont("ArialMT-20.vlw");
textFont(fontA, 20);
// Background drawn once here
background(255);
}
void draw() {
// When mouse is held down, the background is wiped
if (mousePressed) {
background(255);
}
text("Hi there", 20, 50);
}

try to put the smooth() command inside the setup() method and be sure you are loading a font that exist in your system or inside your data folder.
IMHO the font rendering quality in processing is quite good :)

Related

How do I control individual pixels outside of a frame in Java?

I need a way to control individual pixels on a monitor that are not inside a frame. Is there any way I can directly change a pixel at a certain x,y to a certain colour?
Try using Java's "Full-Screen Exclusive Mode" API:
http://docs.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html
In this example:
http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/extra/fullscreen/examples/CapabilitiesTest.java
You see a Java application acquiring the "ContentPane" container from the graphics device, then it creates a JPanel and adds it to content pane. Once you do that, you're free to override the paintComponent of the JPanel with something like this:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(50, 50, 50, 50);
}
You can of course set whatever you draw to any color, and you can draw something other than a rectangle too.
The drawback is, you don't get transparency, in case you're looking to draw ONLY that pixel and leave the rest of the screen preserved. This StackOverflow question investigates this issue further: java fullscreen window with transparency

Drawing images onto AWT and initialising Graphics

I'll start off by telling you what Im trying to do if thats OK, as Im not certain the route Im struggling with is even the best way of achieving my ends.
I have a JFrame containing two JPanels. One contains a number of buttons (buttonPanel), the other is, initially, blank (displayPane). When buttons are pressed the stuff shown in displayPanel changes. The way this is working is each press of a button creates a new object that extends JPanel and then adds that to displayPane
So all the above is working fine and dandy (although I freely admit it may not be the best way of doing it) except for one particular case.
In this particular case I need to create a JLayeredPanel and then draw a clipped image on it. JLayeredPanel because I want to draw some stuff on top of it, clipped because I only want to show part of the area (which exact part is passed to the constructor).
Now, the problem Im having is this. The only way I know to draw a clipped image is through g=thingie.getGraphics(), g.setClip(Shape shape), g.drawImage(various). However, all of that relies on being able to get graphics. But because I am assembling the object first there is no graphics object associated with the JLayeredPane (because its not displayed) so getGraphics is returning null and g.setClip() is throwing a Null Pointer Exception.
Obviously I am doing this wrong somehow and somewhere. Any help would be appreciated, sorry if the question is confusing. I tried to include as much detail as possible and now I am a little concerned I've muddied the issue. I'll keep an eye on this and clarify if required.
Warning!: Wrong answer, see below the line
Why don't you just create a new Graphics object, paint on it and then use it with the update() method?
Graphics g = new Graphics();
g.drawStuff();
thingie.update(g);
This showd be correct
As stated on the comments the previous solution was wrong but it can be done with an Double buffer, create a buffered image and draw on it, then override the paint method of the jLayeredPane pane to draw the image.
private void addStuff() {
BufferedImage bi =
new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
Graphics bufferedGraphics = bi.getGraphics();
//Paint stuff
bufferedGraphics.drawLine(0, 0, 50, 50);
javax.swing.JLayeredPane layered;
layered = new JLayeredPane() {
#Override
public void paint(Graphics g) {
g.drawImage(bi, 0, 0, null);
}
};
this.add(layered);
this.validate();
this.repaint();
}

Add image over another image?

Im trying to make a turn-based game, progressing OK so far, however now I came to the part where I want to be able to move units around. I use images to determine different types of terrain, and another image to display a unit, but I can't get the unit to come out OVER the terrain, it only pops up under the terrain. Seems like I'm the first one ever to bump into this problem, so am I going at it the wrong way?
The tile with a terrain-image:
protected void paintComponent(Graphics paintIt) //paints this sexy-hex
{
super.paintComponent(paintIt); //not sure if we need this? lol
paintIt.setColor(is); //sets the color (later not even used, we need pics and shit)
//paintIt.fillPolygon(hex); //fills the hexagon with the desired color, will not be used later on either
if(isExplored)
paintIt.drawImage(image, 0, 0, null);
else
paintIt.fillPolygon(hex); // I want to paint it black
if (hoover) //are we pointing at this cell?
{
paintIt.setColor(Color.WHITE); //we want the nice line around the cell to be white
Graphics2D g2 = (Graphics2D) paintIt;
g2.setStroke(new BasicStroke(3)); //and 3 pixels wide (we are allowed to change it, supposedly in proportion to "rad"
g2.drawPolygon(hex); //draws the line around the hexagon
}
}
The unit:
protected void paintComponent(Graphics paintIt)
{
if(!selected)
{
paintIt.drawImage(image, 0, 0, null);
paintIt.drawImage(image2,0,0,null);
/*
super.paintComponent(paintIt);
paintIt.setColor(Color.BLACK);
paintIt.drawPolygon(shape); */
}
else
{
super.paintComponent(paintIt);
paintIt.setColor(Color.RED);
paintIt.drawPolygon(shape);
}
}
Sorry for the comments, and sorry for some code that's not even used, just think it's best to have it until the project's finished if we need to get back to somewhere.
The unit image is smaller than the terrain, so it fits. I've tested without painting out the terrain so I know the unit is painted under it.
If there's still code you would need to get an idea what I'm doing, tell me, just thought this was the relevant parts.
EDIT #2
The tile is a class created from another class which extends JFrame. The unit-class is created from that JFrame class but is beeing stored in the tile. Both tile and unit are JComponents.
Fix'd, I had to draw the units image within the terrain-class to make it come out on top. Since I already stored the unit in the class I don't know why I didn't do it this way from the beginning.
Thanks anyhoo <3

Problem with Thread.sleep(x) in a for loop - Java

I'm making a frame which contains a round rectangle. This rectangle is constantly (re)painting
itself with smaller values.
The plan is, First the rectangle decreases in width(x), after that the rectangle decreases in height(y).
But for now I just want to get the width decreasing done with. But I'm having troubles here already.
Please note, i'm only drawing the rectangle's borders, so I don't want to fill it.
I made a for loop as follows:
for (rectWidth = 470; rectWidth >= 0; --rectWidth) {
try {
//simply made to represent rectWidth's value, not really relevant
System.out.println("rectWidth is: " + rectWidth);
//draw the rectangle with it's new width, ignore the "rectHeight" for now.
g.drawRoundRect(5, 5, rectWidth, rectHeight, 10, 10);
//this Thread.sleep is messing up my frame which has an instance of this class added
//to it also, my program is uninterruptable when adding this Thread.sleep
Thread.sleep(500);
} catch (Exception ex) {
//rectangle's value will be returned here when interrupted.
}
}
My question is, how can I add a 'sleep' in my for loop in order to make the drawing not go all too fast,
withouth messing my frame. This thread.sleep is messing my frame up in a way that I don't even see
the rectangle anymore.
I want to achieve a smooth (re)painting of the rectangle. (And yes I know as this piece of code is now
it isn't repainting the rectangle but constantly painting a slightly smaller rectangle in the frame.)
The reason that the rectangle isn't getting displayed is that the display is updated on the EventDispatchThread which is probably the same one your loop is on. That is it can't paint the rectangle because it's too busy sleeping.
The solution is to use a Swing Timer which will run and happily sleep sending tasks to the EventDispatchThread when updating.
Also you can start drawing thread
#Override
public void run(){
while(shouldDraw())
this.wait(500);
yourCalculations(); // maybe setting fields in runnable object
SwingUtilities.invokeAndWait(yourRunnableObject); // or invokeLater if you prefer non blocking version
}
This code shows only conception (I've skipped synchronization and exception handling). SwingTimer looks more elegant but I've never used it.

Can we tilt a JPanel at an angle?

I have image inside the JPanel. I would like to rotate the image. Is it possible to rotate the JPanel using Graphics, Image is rotatable, Just out of curiosity is it possible to rotate JPanel ?
Yes! This is possible and fairly straightforward too. I haven't done rotations but I have done other affine transformations (scaling the entire GUI up and down) very successfully on a project. I cannot see why rotations should be any different.
Instead of trying to scale each component use the fact that you can set a transformation on the Graphics object. Since this is shared between all components being rendered you get all things transformed at once "for free". It is important to realize that the transformation is only a rendering-process-step ... i.e. all components still believe they have the bounds (locations+sizes) which you gave them in the untransformed world. This leaves us with the challenge to deal with mouse-events correctly. To do this you simply add a glass-pane in front of your main-panel. This pane collects all mouse-events and apply a reverse of the transform on the event and then sends the event onward towards all other components.
Conceptually very simple! Still, I remember it took some tweaking to get it all crisp though. Especially the fact that rendered texts (fonts) in java are not correctly linearly scaled (it scales in discrete steps corresponding to font-sizes) imposed a final challenge in my scale-affine-transformation-case. Maybe you don't have to worry about that if you only rotate.
I got my inspiration from JXTransformer: http://www.java.net/blog/alexfromsun/archive/2006/07/jxtransformer_t.html
As far as I know you can't rotate a JPanel itself but you might be able to rotate the image inside the JPanel using Java2D. Here's an article that might help.
Edit:
There might actually be a way to rotate JComponents (such as JPanel) if you override their paintXxx methods and use AffineTransform.
It's not possible to rotate JPanel itself, but it's certainly possible to rotate any image inside. There are quite a few ways to do that, you can - for example - override JPanel's public void paint(Graphics g) and then cast Graphics to Graphics2D. It's very useful class, does rotation and much more ;) Check api docs for more info about this one.
Yes, it is possible. But you won't rotate the panel, but the image:
public void paintComponent(Graphics gg)
{
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTI_ALIAS, RenderingHints.VALUE_ANTI_ALIAS_ON);
AfflineTransform matrix = g.getTransform(); // Backup
float angle = Math.PI / 4.0f; // 45°
g.rotate(angle);
/* Begin */
g.drawImage(yourImage, [your coordinates], null);
/* End */
g.setTranform(matrix); // Restore
}
Everything between /* Begin */ and /* End */ will be drawn rotated.
(I didn't test the code, so, they may be some syntax errors...)

Categories