I just had a problem with artifacts at a JPanel which contains transparent parts.
My JPanel overrides the paintComponent() method:
protected void paintComponent(Graphics g) {
g2d = (Graphics2D) g;
drawMyAplhaImage(g2d);
}
As you can see, the Image drawn on the JPanel is a bit smaller than the JPanel itself.
The solution is to redraw the Parent component.
To save ressources I just repaint the area of the JPanel.
The new paintComponent() method:
protected void paintComponent(Graphics g) {
g2d = (Graphics2D) g;
getParent().repaint(getX(), getY(), getWidth(), getHeight());
drawMyAplhaImage(g2d);
}
Related
can someone help me to know why the whole jtextfield is not visible when adding it to a jpanel that has a painted image icon? here is my code for the sample. thanks :)
without typing anything on it, only part of it is visible.
import java.awt.*;
import javax.swing.*;
public class GraphicsMain extends JFrame{
Panel panel = new Panel();
JTextField tf = new JTextField(10);
public GraphicsMain() {
tf.setBackground(Color.red);
panel.setLayout(new FlowLayout());
panel.add(tf);
this.add(panel);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
}
public static void main(String[] args) {
new GraphicsMain();
}
}
class Panel extends JPanel{
int pixel;
Image image;
public Panel() {
//#1 create icon
image = new ImageIcon("sample.png").getImage();
this.setPreferredSize(new Dimension(250,250));
}
//#2 paint
public void paint(Graphics g){
Graphics g2d = (Graphics2D)g;
g2d.drawImage(image, 0, 0, null);
}
}
You've broken the paint chain (responsibility).
Take a look at:
Performing Custom Painting
Painting in AWT and Swing
to get a better understand of how painting works and how you're suppose to use.
You "could" try and fix it by doing something like...
#Override
public void paint(Graphics g){
super.paint(g);
Graphics g2d = (Graphics2D)g;
g2d.drawImage(image, 0, 0, this);
}
but this is just painting the image over the top of what was previously paint.
You "could" try and fix it by doing something like...
#Override
public void paint(Graphics g){
Graphics g2d = (Graphics2D)g;
g2d.drawImage(image, 0, 0, this);
super.paint(g);
}
But now the image isn't getting painted (because part of the paint workflow is to fill the component with the background color of the component)
Instead, you need to inject your code into a different point in the paint process.
You should be using paintComponent, as it's primary responsibility is to "paint the component", this is called before the children are painted, so it's a great place for painting the background, for example...
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics g2d = (Graphics2D)g;
g2d.drawImage(image, 0, 0, this);
}
How can I draw a circle that is resizable when the window is maximized or minimized? The code I have isn't really even draw the circle like I would like it to either. Any help with this would be greatly appreciated as I have never worked with graphics in Java before and the Oracle site is only helping me so much. Thanks.
public class GUI extends JFrame {
public GUI() {
JPanel p1 = new JPanel();
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawOval(0, 0, 50, 50);
}
public static void main(String[] args) {
GUI frame = new GUI();
frame.setTitle("Circle Generator");
frame.setSize(400, 300);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
To make the painting dynamic you need to get the current width/height of the panel.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//g2d.drawOval(0, 0, 50, 50);
g2d.drawOval(0, 0, getWidth(), getHeight());
}
You also need the super.paintComponent(g) to clear the background of the panel.
Edit:
Actually, I took a closer look at your code and it does nothing. A JFrame does not have a paintComponent() method so your code will never be executed. Also, you create a panel but then don't do anything with it.
Start by reading the section from the Swing tutorial on Custom Painting for more information and working examples.
Then you can modify the example from the tutorial to draw your oval, using the suggestion give above.
I use Eclipse, and I want make a graphic line into JFrame by following code:
public void Makeline () {
Graphics g=new Graphics(); // has error
Graphics2D g2 = (Graphics2D) g;
g2.draw(new Line2D.Double(0, 0, 20, 20));
}
but give followin error:
Cannot instantiate the type Graphics
Graphics is an abstract class, defining the requirements of the overall API.
Painting in Swing is done within the context of the paint chain. This is typically performed within the paintComponent method of components that extend from JComponent
Take a look at Perfoming Custom Painting for more details
You can also use a BufferdImage to generate a Graphics context, but you still need somewhere to draw the image, so it comes down what your are trying to achieve.
The solution is to overwrite the paintComponent method, but the JFrame isn't a JComponent, so instead of JFrame, use JPanel and then add the JPanel to the JFrame.
paintComponent(Graphics g) {
super.paintComponent(g)
//here goes your code
Graphics2D g2 = (Graphics2D) g;
...
}
Graphics is an abstract class. You can't instantiate following way.
Graphics g=new Graphics();
To access Graphics2D, first you need to override paint(Graphics) method.
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
}
I have not used Swing/G2D much, so please be patient.
I have the following class which is a component on my GUI (meant to be a kind of Canvas to draw on):
import javax.swing.*;
import java.awt.*;
public class DrawPanel extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.black);
g2.fillRect(0, 0, getWidth(), getHeight());
BrushStroke bs = new BrushStroke();
add(bs);
}
}
I have been trying to add the following to the above JComponent:
import javax.swing.*;
import java.awt.*;
public class BrushStroke extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.red);
g2.fillOval(0, 0, 10, 10);
}
}
The BrushStroke does not show on the DrawPanel.
I have been searching forever for an answer, and each example I look at seems to be contradictory.
If anybody has attempted what I am, then help would be greatly appreciated. Also, if I am taking the completely wrong approach, please do say.
You should never add a component to a panel in any painting method. The painting methods are invoked whenever Swing determines a component needs to be painted. Therefore you would be adding the component to the panel multiple times.
When you do custom painting you are responsible for overriding the getPreferredSize() method to give the size of the component. This way the layout managers can position the components properly. If you don't do this then the preferred size is 0, so there is nothing to paint.
Read the section from the Swing tutorial on Custom Painting for more information and examples.
On the JComponent.add method, the documentation says:
Note: If a component has been added to a container that has been
displayed, validate must be called on that container to display the
new component. If multiple components are being added, you can improve
efficiency by calling validate only once, after all the components
have been added.
You should refresh your DrawPanel after adding an element to it. Watch out not to do it in the painComponent method, you will end up in an infinite recursion.
Do the following instead:
DrawPanel drawPanel = new DrawPanel();
drawPanel.add(new BrushStroke());
drawPanel.repaint();
EDIT
Here is a fully working solution (extending JPanels instead of JComponent)
public static void main(String[] args){
JFrame frame = new JFrame();
DrawPanel drawPanel = new DrawPanel();
drawPanel.add(new BrushStroke());
frame.getContentPane().add(drawPanel);
frame.pack();
frame.setVisible(true);
}
class DrawPanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.black);
g2.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public Dimension getPreferredSize(){
return new Dimension(100, 100);
}
}
class BrushStroke extends JPanel{
public void paintComponent(Graphics g){
this.setOpaque(false);
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.red);
g2.fillOval(0, 0, 10, 10);
}
#Override
public Dimension getPreferredSize(){
return new Dimension(10, 10);
}
}
The output gives the following:
How to adding new colors to our gradient panel in java?
extend your panel from JPanel and override it's paintComponent like this.
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Creates a two-stops gradient
GradientPaint p;
p = new GradientPaint(0, 0, new Color(0xFFFFFF),
0, getHeight(), new Color(0xC8D2DE));
// Saves the state
Paint oldPaint = g2.getPaint();
// Paints the background
g2.setPaint(p);
g2.fillRect(0, 0, getWidth(), getHeight());
// Restores the state
g2.setPaint(oldPaint);
// Paints borders, text...
super.paintComponent(g);
}
}
and you see the color object you can change existing color...
and i advise you to read
Filthy Rich Clients
and get this book from somewhere.it has more usefull information which you can may use of learn.