TabbedPaneUI paint selected tab - java

i would like to paint the selected tab in a different way than other tab, it works the first time but then the repaint doesn't work.
Here is the code i did inside paintTabBackground :
Graphics2D g2d = (Graphics2D) g.create();
if (isSelected) {
BufferedImage background = tabSelected;
Insets insets = getTabInsets(tabPlacement, tabIndex);
Rectangle tabBound = getTabBounds(tabPane, tabIndex);
tileStretchPaint(g2d, tabBound, background, insets);
} else {
g2d.setColor(new Color(0, 0, 0, 0));
super.paintTabBackground(g2d, tabPlacement, tabIndex, x, y, w, h, isSelected);
}
g2d.dispose();
Thanks for help.

Just cast the graphics
Graphics2D g2d = (Graphics2D) g;
and don't dispose it

Related

How to remove this blur at the edge of JTextField?

I'm Rounding my JTextField but after the field gets rounded the edges are blurry and don't look professional.
This is the code I'm using to round the JTextField. I'm extending the JTextFiled and changing the paintComponent values.
//Rouding the field
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 15, 15);
super.paintComponent(g);
}
protected void paintBorder(Graphics g) {
g.setColor(getForeground());
g.drawRoundRect(0, 0, getWidth()-1, getHeight()-1, 15, 15);
}
public boolean contains(int x, int y) {
if (shape == null || !shape.getBounds().equals(getBounds())) {
shape = new RoundRectangle2D.Float(0, 0, getWidth()-1, getHeight()-1, 15, 15);
}
return shape.contains(x, y);
}
In your painting methods you can try using antialiasing for the Graphics.
You would set the painting properties on a separate Graphics object:
Graphics2D g2d = (Graphics2D)g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// add painting logic
g2d.dispose();

How to resize drawing area dynamically via Java?

I'm trying to resize my BufferedImage (my drawing area) without losing drawn figures on image and resume to draw after resizing.(Like in Paint.NET) I'm doing this with JSplitPane from edges and it's happening but when I want to resume to draw, the cursor (the pen) has been about 3 cm away from the drawn figure(shape) because the figures grow with image. It just gets better when I remove the whole picture. and
I looked at the answers in Google and StackoverFlow, but it did not work with me.How can I get rid of this issue?
I tried like this so far:
Class UI
jSplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, (PropertyChangeEvent evt) -> {
double imageHeight = jSplitPane.getDividerLocation();
double imageWidth = imageHeight * 1.6;
top.setDividerLocation((int) imageWidth);
drawGround.changeImageSizeDynmcally((int) imageWidth, (int) imageHeight);
drawGround.repaint();
});
Class DrawGround
BufferedImage masterImage = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
//image is master image drawing at first time.
public void changeImageSizeDynmcally(int w, int h) {
AREA_WIDTH = w;
AREA_HEIGHT = h;
repaint();
BufferedImage scaledImage = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2D = scaledImage.createGraphics();
g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2D.drawImage(masterImage, 0, 0, null);
g2D.dispose();
}
After this method I have
`#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (masterImage != null) {
g2D = (Graphics2D) masterImage.getGraphics();
g2D.setComposite(AlphaComposite.Src);
bla,bla,bla`
I solved it with creating new method to set the image :
public void changeImageSizeDynmcally(int x, int y) {
AREA_WIDTH = x;
AREA_HEIGHT = y;
repaint();
scaledImage = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2D = scaledImage.createGraphics();
g2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2D.drawImage(image,0,0, null);
g2D.dispose();
setImage(scaledImage); //this is a new method!
}`
The new method is :
public void setImage(BufferedImage img) {
if (img != null) {
g2D = (Graphics2D) img.getGraphics();
g2D.setComposite(AlphaComposite.Src);
g2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
masterImage = img;
repaint();
}
}
It's working like assigning the new image to old image.

Incorrect display of the menu item

When I add to my JMenuItem new Icon or ImageIcon, then the text becomes the same color as the icon.
My code:
JMenuButton red = new JMenuItem("Red", getIcon(Color.RED));
private Icon getIcon(Color color){
return new Icon() {
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D)g;
g2.translate(x,y);
g2.setPaint(color);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.fillOval( 0, 2, 10, 10 );
g2.translate(-x,-y);
}
#Override
public int getIconWidth() {
return 14;
}
#Override
public int getIconHeight() {
return 14;
}
};
}
Graphics2D g2 = (Graphics2D)g;
Don't just cast the Graphics object to a Graphics2D.
Any changes you make to the Graphics2D object will be retained by the Graphics object.
Instead create a separate Graphics object that you can temporarily customize:
Graphpics2D g2 = (Graphics2D)g.create();
// do custom painting
g2.dispose();
Now the changes will only apply to the custom painting code.

drawString in BufferedImage disappears

I hope you can help me concerning a problem in my drawString.
I do some drawing within a Factory class and return a BufferedImage with a String on it.
public class Factory {
public BufferedImage create() {
TempPanel tempPanel = new TempPanel(new Dimension(100, 100));
return tempPanel.createImage();
}
private class TempPanel extends JPanel {
public TempPanel(Dimension d) {
this.setVisible(true);
this.setSize(d);
}
public BufferedImage createImage() {
BufferedImage bi = new BufferedImage(this.getSize().getWidth(), this.getSize().getHeight(), BufferedImage.TRANSLUCENT);
this.paintComponent(bi.createGraphics());
return bi;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
// General setup
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Transparent Background
g2.setComposite(AlphaComposite.Clear);
g2.fillRect(0, 0, graphicalObject.width, graphicalObject.height);
g2.setComposite(AlphaComposite.Src);
// Different settings for a certain graphical object
g2.setFont(new Font("TimesRoman", Font.PLAIN, 12);
// Actual drawing
g2.drawString("Test", 0, 0);
}
}
}
And then I also have a JPanel in which this image should be drawn:
public class Label extends JPanel {
// ...
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Factory factory = new Factory();
BufferedImage img = factory.create();
g2.drawImage(img, 0, 0, null);
}
}
The problem ist that the text only appears if i minimize and restore the window, but as soon as I start moving the mouse within the window, the text disappears again.
When I call drawRect() instead of drawString(), everything works fine?!
Can someone tell me why?
Thanks!
There are a number of things that "weird" me out...
Firstly, you're creating a new Graphics context, but you're not disposing of it. This could be leaving resources open and may actually prevent the contents from been rendered on some OSs...
So instead of...
BufferedImage bi = new BufferedImage(this.getSize().getWidth(), this.getSize().getHeight(), BufferedImage.TRANSLUCENT);
this.paintComponent(bi.createGraphics());
You should be doing something more like...
BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TRANSLUCENT);
Graphics2D g2d = bi.createGraphics();
this.paintComponent(g2d);
g2d.dispose();
Secondly, text is not render the same way that most other elements are, that is, it doesn't start at x/y and render down/right, in most cases it starts at x/y and renders, slightly, up/right. The actual coordinate is based on the Fonts FontMetrics getAscent value...
So, instead of...
g2.setFont(new Font("TimesRoman", Font.PLAIN, 12));
// Actual drawing
g2.drawString("Test", 0, 0);
You should be doing something more like...
g2.setFont(new Font("TimesRoman", Font.PLAIN, 12));
FontMetrics fm = g2.getFontMetrics();
// Actual drawing
g2.drawString("Test", 0, fm.getAscent());
See Working with Text APIs or more details...
Thirdly, JComponent and by extension, anything that extends from it, is an ImageObsever, this is important, as not everything that is painted is ready for display immediately, sometimes it needs further processing, rather than having to deal with this annoyance yourself, you can delegate the responsibility, so instead of...
g2.drawImage(img, 0, 0, null);
You should be doing something more like...
g2.drawImage(img, 0, 0, this);
This allows the component to listen to the underlying image and respond to any changes that might happen to the image data and update itself.
Forthly...
private class TempPanel extends JPanel {
public TempPanel(Dimension d) {
this.setVisible(true);
this.setSize(d);
}
public BufferedImage createImage() {
BufferedImage bi = new BufferedImage(this.getSize().getWidth(), this.getSize().getHeight(), BufferedImage.TRANSLUCENT);
this.paintComponent(bi.createGraphics());
return bi;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
// General setup
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Transparent Background
g2.setComposite(AlphaComposite.Clear);
g2.fillRect(0, 0, graphicalObject.width, graphicalObject.height);
g2.setComposite(AlphaComposite.Src);
// Different settings for a certain graphical object
g2.setFont(new Font("TimesRoman", Font.PLAIN, 12);
// Actual drawing
g2.drawString("Test", 0, 0);
}
}
Is freaking me out...Swing components are meant to be attached to a native peer onto which they are rendered, they are also optimised not to paint when they aren't displayable, this could be throwing off your rendering...
Infact, you could achieve the same thing using something like...
public static class Factory {
private static Renderer renderer;
public BufferedImage create() {
if (renderer == null) {
renderer = new Renderer(new Dimension(100, 100));
}
return renderer.createImage();
}
private class Renderer {
private Dimension size;
public Renderer(Dimension size) {
this.size = size;
}
public BufferedImage createImage() {
BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TRANSLUCENT);
Graphics2D g2 = bi.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Transparent Background
g2.setComposite(AlphaComposite.Clear);
g2.fillRect(0, 0, graphicalObject.width, graphicalObject.height);
g2.setComposite(AlphaComposite.Src);
// Different settings for a certain graphical object
g2.setFont(new Font("TimesRoman", Font.PLAIN, 12));
FontMetrics fm = g2.getFontMetrics();
// Actual drawing
g2.drawString("Test", 0, fm.getAscent());
g2.dispose();
return bi;
}
}
}
Which would divorce the actual painting from anything else and provide you with control over it...

Why i can't see shadow generated with this ShadowRenderer?

I'm trying to use the ShadowRenderer from swingx to create a shadow for a panel. Here is what i did so far:
Creating the shadow renderer one time in the panel constructor.
public CustomPanel() {
super();
renderer = new ShadowRenderer(20, 0.5f, Color.RED);
}
Each time the panel is resized, i recalculate the new shadow.
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
shadow = renderer.createShadow(GraphicsUtilities.createCompatibleTranslucentImage(width, height));
}
And then i override the paintComponent method of my panel to draw the generated image:
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.drawImage(shadow, 0, 0, null);
//super.paintComponent(g);
}
But the shadow image is never shown. Why? I read this and i except my code to draw a kind of "shadowed" image generated by the shadow renderer.
Here's a shortened example of DropShadowDemo
JXPanel panel = new JXPanel() {
int shadowSize = 40;
ShadowRenderer renderer = new ShadowRenderer(shadowSize/ 2, 0.5f, Color.RED);
BufferedImage imageA =
XTestUtils.loadDefaultImage("moon.jpg");
BufferedImage shadow;
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
// not really needed here - the base image size is fixed
shadow = renderer.createShadow(imageA);
}
#Override
protected void paintComponent(Graphics g) {
int x = (getWidth() - imageA.getWidth()) / 2;
int y = (getHeight() - imageA.getHeight()) / 2;
Graphics2D g2 = (Graphics2D) g;
Composite c = g2.getComposite();
g2.setComposite(AlphaComposite.SrcOver.derive(renderer.getOpacity()));
g.drawImage(shadow, x - shadowSize / 2, y - shadowSize / 2, null);
g2.setComposite(c);
g.drawImage(imageA, x, y, null);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageA.getWidth() + shadowSize, imageA.getHeight()+ shadowSize);
}
};
panel.setOpaque(false);

Categories

Resources