Every image in my Java Swing Programs will appear in low quality as shown below:
As you can see from the image, it is not just images I am having problem with, it's graphics in general displaying like this. In the right portion you can see the problem reflected to a JFreeChart Graphic. Has anyone else had this problem, is it related to the graphics card or maybe windows DPI? The same programs will render perfectly fine in other machines so I am pretty sure it is not related to the code.
If you are using g2d, try enabling antialiasing.
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
(more info: Java2D Graphics anti-aliased)
In JFreeChart try the following code:
chart.setRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
(source: http://www.jfree.org/forum/viewtopic.php?t=7958)
The problem in my case was that I had scaling turned on at 125% on Windows and images and frames had to be zoomed in order to fit the size they were given. All you have to do is go to Display Settings and at section Scale and layout set zoom to 100%.
If you don't fancy turning down scaling you could add this parameter to the VM on your IDE by adding this parameter:
-Dsun.java2d.dpiaware=false
Alternatively, try this if the first one doesn't work.
-Dsun.java2d.uiScale=1.0
This only works for Swing
even if you are not using g2d, just add g2d instance to make it work.
(i had similar problem, i tried JVM options, nothing worked. and then this worked even though i draw image using just graphics(not graphics2D). isn't it weired(notice last line of code which is using g instead of g2)
its in paintComponent(graphics g) method.
Graphics2D g2 = (Graphics2D) g;
//g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawImage(scaled, x, y, null);
Related
Because I cannot see small letters I set windows display to 150%. All things on my monitor are resized without losing quality. But unfortunately, it doesn't happen with Java Swing interface. Indeed, the Swing interface is scaled, but it has a wrong quality.
Can somebody help me to solve it?
Depending on what exactly you mean by "quality", but you can set rendering hints with several options, e.g. anti-aliasing:
public void paint (graphics g){
Graphics2D g2 = (Graphics2D)g;
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setRenderingHints(rh);
...
}
There are several of these hints, you can find a list here.
It is possible to draw from one Graphics2D to another Graphics2D?
Let me explain.
I have printing issues, when i display a JTextArea or JTextPanel in screen, internaly its used sun.java2d.SunGraphics2D, but when im printing its used sun.print.PeekGraphics and sun.awt.windows.WPathGraphics.
The problem is with some kind of Fonts, like Arial. In some sizes lines are cut.
I have tryed a lot of ways to render the text in printing, Graphics2D.drawString, SwingUtilities2.drawString, TextLayout.drawString, but in some cases lines are still cut, or lines are not cut but some kind of justification makes disapear white spaces.
So my idea is try to render components with sun.java2d.SunGraphics2D and "copy" the surface to the printer via sun.print.PeekGraphics or sun.awt.windows.WPathGraphics.
Thanks in advance.
Yes its possible, thats how double buffering is achieved in a lot of Java Games. What you need is the Graphics2D's drawImage() method which takes in another Graphics2D object to draw in. E.g. from a small game of mine:
private Main(){
...
/* Create the backbuffer as a BufferedImage object */
this.doubleBuffer = new BufferedImage(this.WIDTH, this.HEIGHT, BufferedImage.TYPE_INT_RGB);
/* create a Graphics 2D object to draw INTO this backbuffer */
this.doubleBufferG2D = (Graphics2D) doubleBuffer.createGraphics();
...
}
Somewhere else:
/*Now lets draw the backbuffer INTO the screen */
g2d.drawImage(doubleBuffer, null , 0, 0);
Edit: heh I realized its not exactly as above...lemme think on it.
Edit2: Alright the above can still be used a sample, but the sequence of steps to draw from one Graphics2D to another should be as such:
1. From a Graphics2D object to an Image/BufferedImage object using drawGraphics().
2. From the Image/BufferedImage above, extract its member Graphics2D object by using itscreateGraphics().
Looks like you can do one of two things:
create a Graphics2D on an image, do your rendering, then draw the image into another Graphics2D
or create Graphics2D from original Graphics2D using Graphics.create() methods and then do you rendering.
I'm working with a JEditorPane, and (of course) the text looks so much nicer when I paint the component using antialiasing and fractional widths. In other words:
JEditorPane pane = new JEditorPane() {
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
super.paint(g);
}
}
If I do this with static, non-selectable text, it paints beautifully. However, as soon as I start dragging a selection over it, I get some weird jiggling between frames, and artifacts. Is there any way to paint with the fractional metrics and avoid that weirdness? I tried setting the attribute on the Caret as well with no luck.
This question seems to be answered long ago by the author and StanislavL in the comments:
If you set the "i18n" to TRUE the effect isn't visible. Just wrote a
small test case. Alternatively you can use the
java-sl.com/Scale_In_JEditorPane_GlyphPainter.html to add your own
fractional based painter.
I need to do font smoothing for a AWT application on Windows System.
On doing googling I came to know that I can set following VM argument in Eclipse.
-Dawt.useSystemAAFontSettings=gasp
But this is not yielding any positive results.
If anyone is having a better idea on how to achieve Font Smoothing, then kindly let me know.
EDIT After Answer By Andrew
I added the following snippet of code in paint method
public class BottomSubmitButtons extends Canvas {
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g2.setRenderingHints(rh);
}
}
This seems to have improved the smoothing in one of the sub panel.
But doing the same in other panel is not yielding any smoothing. Also the TextField boxes are going invisible by default, though they becomes visible once I click in that area
Play with the values for RenderingHints.KEY_TEXT_LCD_CONTRAST. When you find something that works, use that as the command line value.
in the a swing app i'm rendering text with a custom JComponent, using Graphics.drawString(). here is a sample:
aa text http://img525.imageshack.us/img525/4928/drawstringsample.jpg
in that same app, i'm rendering text using a JTextPane. here is a sample:
alt text http://img28.imageshack.us/img28/1134/jtextpanesample.jpg
can you notice how the lower sample is a little 'smudged'? well, i can't figure out how to make it look like the upper sample.
thanks, asaf :-)
update:
System.setProperty("awt.useSystemAAFontSettings","false") and "lcd" too aren't working.
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) in paint() isn't working
putClientProperty(sun.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY, Boolean.TRUE) gives java.lang.ClassCastException: java.lang.Boolean cannot be cast to sun.swing.SwingUtilities2$AATextInfo
This will result in an antialiased font in a JLabel. Make sure you call super.paintComponent(g); after setting the RenderingHints.
JLabel lblFont = new JLabel(){
#Override
public void paintComponent(Graphics g) {
Graphics2D graphics2d = (Graphics2D) g;
graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g);
}
};
putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, null);
If you want your result to look like the the upper sample, then you want to disable anti-aliasing.
The first sample in your question has anti-aliasing disabled and the second sample has it enabled.
According to http://mindprod.com/jgloss/antialiasing.html the following code should help:
jtextArea.putClientProperty(com.sun.java.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY, Boolean.TRUE);
Notice that the reference to com.sun.java.* will make your application non-portable to non-Sun JVMs (and possibly to different versions of Sun JVMs).