I want to make smooth rounded corners for my swing application, but I can\'t get my desired result...
here\'s the screenshots:
1.setShape()
for JFra
The only chance you have is working with regions. You will need to hardcode a bit and play with subtract, but eventually it will look fine. You can take a look at how it's done in mylyn's notification class: http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/3.6/org.eclipse.mylyn.commons/ui/3.4.0/org/eclipse/mylyn/internal/provisional/commons/ui/AbstractNotificationPopup.java
Hope it helps, best of luck!
Edit: Just remembered this little tutorial which might help: http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/SWTShellcreateanonrectangularwindow.htm
Sorry, not an answer, but hopefully at least one step towards an acceptable answer: From my analysis so far, it might be that this is simply a bug somewhere deep (deeeep!) inside the rendering pipeline.
The following MVCE shows two (undecorated) frames, each containing a button. They are equal, except for the background of the frames. For one frame, the color is transparent, and for the other one, it is opaque.
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class TextRenderBug extends JFrame {
public static void main(String[] args)
{
setLookAndFeel();
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI(new Color(0,0,0 ), 400);
createAndShowGUI(new Color(0,0,0,0), 600);
}
});
}
private static void setLookAndFeel()
{
try
{
for (UIManager.LookAndFeelInfo info :
UIManager.getInstalledLookAndFeels())
{
if ("Nimbus".equals(info.getName()))
{
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void createAndShowGUI(Color background, int x)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(background);
JButton b = new JButton("Text");
b.setFont(new Font("Tahoma", 0, 15));
f.getContentPane().add(b);
f.setBounds(x, 400, 200, 50);
f.setVisible(true);
}
}
It clearly shows that the text is rendered differently, solely depending on the background being transparent - and of course, this should not be the case.
(This is not Nimbus-specific, by the way: It also applies to other LookAndFeels. Just remove the line where the LaF is set).
What I found out so far:
drawString
method of the sun.swing.SwingUtilities2
classJButton
and JLabel
, but not on a normal JComponent
Font.BOLD
. (OK, some of you might already have known the latter).
Here is an example that shows the last observations, maybe it can serve as a starting point for further research of others:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.lang.reflect.Method;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TextRenderBugTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI(new Color(0,0,0 ), 400);
createAndShowGUI(new Color(0,0,0,0), 600);
}
});
}
private static void createAndShowGUI(Color background, int x)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(background);
JButton b = new JButton("Text");
b.setFont(new Font("Tahoma", 0, 15));
JComponent c = new ExampleComponent();
c.setFont(new Font("Tahoma", 0, 15));
f.getContentPane().setLayout(new GridLayout(0,1));
f.getContentPane().add(b);
f.getContentPane().add(c);
f.setBounds(x, 400, 200, 100);
f.setVisible(true);
}
static class ExampleComponent
//extends JComponent
extends JButton
{
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(getForeground());
g.drawString("Text", 10, 20);
drawStringWithSwingUtilities(g, 60, 20);
}
private void drawStringWithSwingUtilities(Graphics g, int x, int y)
{
try
{
Class<?> c = Class.forName("sun.swing.SwingUtilities2");
Method m = c.getMethod("drawString", JComponent.class,
Graphics.class, String.class, int.class, int.class);
m.invoke(null, this, g, "Text", x, y);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
I already tried to analyze this further, and played around with RenderingHints
like KEY_TEXT_ANTIALIASING
and KEY_TEXT_LCD_CONTRAST
and other settings that are changed in the painting pipeline while it is heading towards the pixels that are finally placed on the screen, but no further insights until now.
(If you want to, you can add this information to your original question, then I'll delete this (not-)answer)