How can I draw an object without a class (which extends JFrame)? I found getGraphics method but it doesnt draw the object.
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(600, 400);
JPanel panel = new JPanel();
frame.add(panel);
Graphics g = panel.getGraphics();
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
}
If you want to change the way your component is being drawn (you are adding rectangles), you need to redefine paintComponent() in that component. In your code, you are using getGraphics().
You shouldn't call getGraphics() on a component. Any painting you do (to the Graphics returned) will be temporary and will be lost the next time Swing determines a component needs to be repainted.
Instead, you should override the paintComponent(Graphics) method (of the JComponent or JPanel), and do the painting in this method, using the Graphics object received as argument.
Check this link for further reading.
Below is your code, corrected.
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(600, 400);
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
};
frame.add(panel);
// Graphics g = panel.getGraphics();
// g.setColor(Color.BLUE);
// g.fillRect(0, 0, 100, 100);
frame.validate(); // because you added panel after setVisible was called
frame.repaint(); // because you added panel after setVisible was called
}
}
Another version, does the exact same thing, but may be clearer to you:
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(600, 400);
JPanel panel = new MyRectangleJPanel(); // changed this line
frame.add(panel);
// Graphics g = panel.getGraphics();
// g.setColor(Color.BLUE);
// g.fillRect(0, 0, 100, 100);
frame.validate(); // because you added panel after setVisible was called
frame.repaint(); // because you added panel after setVisible was called
}
}
/* A JPanel that overrides the paintComponent() method and draws a rectangle */
class MyRectangleJPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
}
You have to override paintComponent method in JPanel class. So you should create a class which extends JPanel and override paintComponent method in subclass
java.awt.image.BufferedImage
Why not just use an instance of java.awt.image.BufferedImage? e.g.
BufferedImage output = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = output.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, output.getWidth(), output.getHeight());
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, 100, 100);
JOptionPane.showMessageDialog(null, new ImageIcon(output));
Related
I am using the same numbers to set the size of my frame as I am to paint the rectangle, yet the graphics are larger than my JFrame. Why is this?
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] arguments) {
Test test = new Test();
JFrame frame = new JFrame();
DrawPane contentPane = test.new DrawPane();
frame.setContentPane(contentPane);
frame.setSize(300, 400);
frame.setVisible(true);
}
private class DrawPane extends JPanel {
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.YELLOW);
g.fillRect(0, 0, 300, 400);
}
}
}
It's because of border. And it's a good example why you shouldn't explicitly determine size for your JFrame. Instead calling setSize override getPreferredSize method from your JPanel:
private class DrawPane extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.YELLOW);
g.fillRect(0, 0, 300, 400);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 400);
}
}
Then call pack for your JFrame instead setSize and your JFrame will adjust it's size according to its content.
I have a frame with image inside and I want to choose part of that image with my own component (extending JComponent). Now it looks like that:
But I want it to look something like that:
How can I achieve this?
It really depends on how you are drawing your component. If you are using a Graphics, you can cast it to a Graphics2D and then you can either setPaint, or setComposite to get a transparency effect.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
/**
* Created by odinsbane on 8/3/15.
*/
public class TransparentOverlay {
public static void main(String[] args){
JFrame frame = new JFrame("painting example");
JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(Color.WHITE);
g2d.fill(new Rectangle(0, 0, 600, 600));
g2d.setPaint(Color.BLACK);
g2d.fillOval(0, 0, 600, 600);
g2d.setPaint(new Color(0f, 0f, 0.7f, 0.5f));
g2d.fillRect(400, 400, 200, 200);
g2d.setPaint(Color.GREEN);
g2d.setComposite(
AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.8f
)
);
g2d.fillRect(0,0,200, 200);
g2d.setPaint(Color.RED);
g2d.fillRect(400, 0, 200, 200);
}
};
frame.setContentPane(panel);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
With a set composite, all of your drawing afterwards will have the same composite, until you change it again.
I want to draw a rectangle in Java on a Swing application, but I don't know how. I have looked at similar questions, none containing the answer I need. I have tried the following:
private void paintComponent(Graphics graphics, Rectangle rect, Color color) {
contentPane.paintComponents(graphics);
Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.setColor(color);
graphics2D.draw(rect);
}
I call it like:
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
paintComponent(contentPane.getGraphics(), new Rectangle(0, 0, 50, 50), Color.WHITE);
But it throws a NullPointerException on this line:
graphics2D.setColor(color);
I suspect it is the graphics2D being null. How can I fix this?
You're not even overriding the method correctly. paintComponent only takes a Graphics object as an argument, so you can't add your own.
import javax.swing.*;
import java.awt.*;
public class Test extends JPanel {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new Test());
frame.setVisible(true);
frame.pack();
}
});
}
public Dimension getPreferrdSize() {
return new Dimension(200, 200);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(10, 10, 150, 40);
}
}
I am a beginner to JAVA and I'm breaking my head on the following problem:
Why does this code not draw
import ...
public class tekening extends JFrame{
private JPanel p;
private Graphics g;
tekening(){
setLayout(new FlowLayout());
p = new JPanel();
p.setPreferredSize(new Dimension(350, 350));
p.setBackground(Color.WHITE);
add(p);
setLocationByPlatform(true);
setSize(400, 400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
g = p.getGraphics();
g.setColor(Color.BLACK);
g.drawRect(30, 30, 80, 40);
g.drawLine(10, 10, 40, 50);
}
}
And why does this code draw
import ...
public class tekenclasse extends JFrame implements ActionListener{
private JPanel p;
private Graphics g;
private JButton button1;
tekenclasse(){
setLayout(new FlowLayout());
button1 = new JButton("Knop 1");
button1.addActionListener(this);
add(button1);
p = new JPanel();
p.setPreferredSize(new Dimension(350, 350));
p.setBackground(Color.WHITE);
add(p);
setLocationByPlatform(true);
setSize(400, 400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e){
g = p.getGraphics();
g.setColor(Color.BLACK);
g.drawRect(30, 30, 80, 40);
g.drawLine(10, 10, 40, 50);
}
}
For me this is completely strange. Why can't I use the Graphics inside the constructor. And why can I use it after an event. This is stupid I want to draw on immediately and I don't want to press a button.
Never use getGraphics() to paint.
Don't try and paint on top level containers like JFrame
Instead (as shown in Performing Custom Painting - MUST READ), use a JPanel (or JComponent) and override its protected void paintComponent(Graphics g) method. Use that graphics context to do your painting. All your painting should be done within that graphics context provides, whether directly writing code in the paintComponent method, or calling a method in which you pass the Graphics object to as an argument.
Override public Dimension getPreferredSize() in the JPanel/JComponent to give you painting surface a preferred size. Ad the pabel to the frame, then pack() your frame.
public class DrawPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.draw... // do all your drawing here
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
Important: You MUST read the link about custom painting before posting another question about painting, or you will get a spanking :-)
I am trying to add a JPanel (well, several) to a JLayeredPane. However, when I do so, the paint component method of the JPanel seems to have no effect. An example is included below:
import javax.swing.*;
import java.awt.*;
public class Example {
public static void main(String[] args) {
// This Works as expected
JFrame usingPanel = new JFrame();
JPanel p = new JPanel();
p.add(new BluePanel());
usingPanel.setContentPane(p);
usingPanel.pack();
usingPanel.setVisible(true);
// This makes the frame but does not paint the BluePanel
JFrame usingLayer = new JFrame();
JLayeredPane l = new JLayeredPane();
l.setPreferredSize(new Dimension(200,200));
l.add(new BluePanel(), JLayeredPane.DEFAULT_LAYER);
JPanel p2 = new JPanel();
p2.add(l);
usingLayer.setContentPane(p2);
usingLayer.pack();
usingLayer.setVisible(true);
}
static class BluePanel extends JPanel{
public BluePanel(){
setPreferredSize(new Dimension(200,200));
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 200, 200);
}
}
}
Why is this? and what are the possible solutions?
JLayeredPane does not have a LayoutManager, so you need to set the location and size of your panels yourself.
See the tutorial
you hardcoded the size on the screen and have to change from
g.fillRect(0, 0, 200, 200);
to
g.fillRect(0, 0, getWidth(), getHeight());
(a minor change) add the method
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
and then remove of code line setPreferredSize(new Dimension(200,200));