How to do Font Smoothing for AWT/Swing Application? - java

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.

Related

How to scale size of interface without losing quality?

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.

Java Swing, all images appear pixelated

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);

JFrame + custom LayoutManeger + work with Graphisc2D (rotation)

I'm working on project, which uses custom Layout Manager. My goal is rotate all components by 180°.
I have some screen which consists of JFrame. I also have some LayoutHandler, which defines some layers of layout. Each layer is instance of LayerLayout which implements LayerManager2 from java.awt
The flow works probably like this:
I have JFrame, which represents the display. This JFrame has some default contentpane. The application set to this contentpane Layout which is represented by LayerHandler:
graphicalDisplayJFrame.getContentPane().setLayout(new LayerLayout(layerHandler));//graphicalDisplayJFrame is JFrame which represents the display
The layerHandler just somehow manage the layers which are LayerLayouts which implemetns LayerLayout2 from java.awt. So it looks like layout of layouts or whatever it is. I'm not much experienced with creating custom layouts.
There I have a situation which shows creating of JFrame.
graphicalDisplayJPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.rotate(Math.PI, anchorx, anchory); //rotation 180°
}
#Override
public void paintChildren(Graphics g) {
super.paintChildren(g);
Graphics2D g2d2 = (Graphics2D) g;
g2d2.rotate(Math.PI, anchorx, anchory);
}
};
graphicalDisplayJFrame = new JFrame(); //creation of JFrame
graphicalDisplayJFrame.setContentPane(graphicalDisplayJPanel); //setting JFrame to apply rotation
The first part should make the rotation 180°, but it does not, even when i call repaint on graphicalDisplayJFrame. BUT when I add this:
JLabel hwLabel = new JLabel("Hello world.");
hwLabel.setVisible(true);
graphicalDisplayJFrame.add(hwLabel);
I cause strange thing. The JFrame and all of the components on it is accidentaly rotated by 180°. But its only static behaviour, because there are some text components on display and when there is changed the text on them its again rendered in non rotated way.
So the question is why this could happens?
If i divide it in two parts:
a) Why the Graphics2D on JFrame does not affect the children components on its content pane. Why it only works when I add the JLabel which has no sense here but it was just experiment which caused what I wanted (= repaint with right rotation).
b) I should probably somehow apply the rotation => something like overriding the paint method on each components which are added on the contentPane of JFrame. But how should can I do it? Becouse upper described layout handler just manage a bunch of layouts (layers which are probably custom layouts implementig LayoutManager2 from java.awt) and it is just feeding the components which are put on the layouts and put them on content pane. So the question should probably be where could be the place where I want to implement my custom paining which means apply the rotation (which is this part of code g2d.rotate(Math.PI, anchorx, anchory); //rotation 180°).
I hope it understandable, I made pretty bit effort to understand where could be problem and trying find out the solution, but its behave really strange. So I hope someone with more experience with this could help me out off this struggling and show me the way.
You are applying the rotation at very strange points. Graphics2D.rotate() applies only to things painted after the rotate call, but your paint-overides rotate after calling super.
As for why adding a label causes rotation, hard to tell without seeing the entire code. Probably an effect of partial repaint.
You should not modify essentials like the graphics translation or rotation of the graphics passed to your paint methods. It has the potential to affect the parent components drawing in unexpected way and the effect can easily change depending on JRE version. Instead create a new graphics to pass down to your child components:
#Override
public void paintChildren(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
try {
g2d.rotate(Math.PI, anchorx, anchory);
super.paintChildren(g2d);
} finally {
g2d.dispose();
}
}
This method leaves the original Graphics untouched, at least allowing the parent component to render normally. Rotating the graphics is still tricky and will probably have unintended side effects in the rendering process, but at least these effects are now carefully limited to the children of the rotating component.

Painting editable JTextComponents with fractional widths?

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.

how to make JTextPane paint anti-aliased font?

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).

Categories