In Java, I need to draw a simple line with the paintComponent. Here is my attempt, but nothing was shown when I executed the program. Please show me the correct way of doing this.
import javax.swing.*;
import java.awt.*;
public class DrawLine extends JPanel {
public Illusion(Color backColor){
setBackground(backColor);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.black);
g.drawLine(100, 100, 300, 100);
}
}
Your painting a black line on a black background, so I'd say its working just fine. Try changing the color of the line
g.setColor(Color.Red);
g.drawLine(100, 100, 300, 100);
Your also not taking into account the actual size of the panel, I'd do something more along the lines of
g.drawLine(0, 0, getWidth(), getHeight());
As a test
You might like to have a read through
Creating a GUI With JFC/Swing
Graphics2D
Painting in AWT and Swing
Related
I can't figure out how to get "g.setStroke(new BasicStroke(5));" to be set to all my created shapes (in this case ovals).
My code:
import java.awt.*;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.BasicStroke;
public class Rings
{
public static void main(String[] args)
{
DrawingPanel panel = new DrawingPanel(300, 300);
Graphics2D g = panel.getGraphics();
g.setStroke(new BasicStroke(5)); // Sets Outer Line Width of Shapes
g.setColor(new Color(255, 0, 0));
g.fillOval(50, 50, 200, 200); // Large Oval
g.setColor(new Color(200, 0, 0));
g.fillOval(100, 100, 100, 100); // Medium Oval
g.setColor(new Color(150, 0, 0));
g.fillOval(125, 125, 50, 50); // Small Oval
g.setColor(new Color(100, 0, 0));
g.fillOval(137, 137, 25, 25); // Tiny Oval
}
}
My output:
Correct output:
The stroke doesn't matter so much when you call fillOval but moreso when you call drawOval. So I recommend:
Call fillOval as you're doing
After each fillOval, then change Color to Color.BLACK (or whatever outline color you desire), and call drawOval.
See what happens to your drawing if you minimize the GUI and then restore it.
It is for this reason, and to avoid NullPointerException errors, that we don't recommend that you use a Graphics object obtained via a getGraphics() call on a Swing component. Such a Graphics object is short-lived. Instead do as the tutorials and most other similar questions will tell you: within a proper paintComponent override inside a class that extends JPanel or JComponent.
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.
Helo guys,
my problem is that sometimes if my Rectangle2D gets a big width or height its bottom,left border splits and no longer makes a continous border and if I even make it wider the border goes smaller and smaller, like if there were a limitation of how long a rectangles border can be... It is really confusing and so far I have not found the solution :S I put there a link to a picture so you can see for yourself.
new Rectangle2D.Double(mojrectangle.getUpperleftPointmojRectangle().getX(), mojrectangle.getUpperleftPointmojRectangle().getY(),1000,1000)
repaint();
thanks for your help..
BTW I have the same problem with Arc2D if it gets really big
UPDATE: I removed from the function the setStroke command and now it draws it correctly, but in the future I will need to set the Rectangles stroke so it leaves me sad.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
//g2.setStroke(stroke);
g2.draw(rectangle);
}
Here I put an example code of my project, please try it with g2.setStroke(selectedstroke)- it wont work, and without it...I hope I explained myself clear .
package com.awtgraphicsdemo;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.JComboBox;
public class AWTgraphicsdemo extends Frame {
final float dash[] = {10.0f};
final float solid[] = {1000.0f}; // these must be in an Array
float lineWidth[]={2.0f,4.0f,6.0f,8.0f,10.0f}; // width of the drawing line
String[] lineWidthString={"2.0","4.0","6.0","8.0","10.0"};
JComboBox strokecombobox=new JComboBox(lineWidthString);
BasicStroke selectedStroke = new BasicStroke(lineWidth[0],BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER, 10.0f, solid, 0.0f);
public AWTgraphicsdemo(){
super("Java AWT Examples");
prepareGUI();
}
public static void main(String[] args){
AWTgraphicsdemo awtGraphicsDemo = new AWTgraphicsdemo();
awtGraphicsDemo.setVisible(true);
}
private void prepareGUI(){
setSize(400,400);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(selectedStroke);
g2.draw (new Rectangle2D.Double(10, 10, 1000, 900));
Font font = new Font("Serif", Font.PLAIN, 24);
g2.setFont(font);
g.drawString("Welcome to TutorialsPoint", 50, 70);
g2.drawString("Rectangle2D.Rectangle", 100, 120);
}
}
Helo again,
I figured out my problem, it was in the properties of stroke,so after some lenght of the compoment the stroke got activated which made changed to the drawn shape.By modifying the strokes solid array I was able the get the result I wanted.
Thank you for your help and suggestions :)
Take Care
Better to:
Not override paint(...) in top level windows (as MadProgrammer states) since this also changes painting of borders and child components -- a dangerous thing to do.
Instead override paintComponent(...) of a JPanel (again as MadProgrammer states) and place that JPanel into your top level window.
Don't set the Stroke of the Graphics object passed into your painting method, but rather a copy of the Graphics object so not to have side effects down the road.
e.g.,
public class MyPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(....);
// do drawing with g2 here
g2.dispose();
}
}
I was given small assignment as below . Can you please throw some light on how to implement this
Write a simple structured program and simple oo program that implements display shape function. Your program should simply print out (to console ) the number if shapes and then ask each shape to display itself which will also cause a line of output to be generated to the console , one for each shape . It is perfectly OK for your main program to create a collection of shapes before on to sorting that collection and displaying the shapes. Your program should support circles , triangles and squares but should use polymorphism so that the main program doesn't know the type of shape it is dealing with but instead treats shapes uniformly
I had created a program to create shapes like below but i'm not sure on how to create the shapes as mentioned and store them in collection and iterate to display these shapes on console. I was told not to use the database for storing shapes
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JApplet;
public class DrawShapes extends JApplet {
public void paint(Graphics g) {
g.setColor(Color.RED);
// drawing string
g.drawString("Hello World!", 100, 100);
// drawing rectangle
g.draw3DRect(120, 120, 120, 120, true);
g.setColor(Color.blue);
g.fill3DRect(120, 120, 120, 120, true);
// drawing circle
g.drawOval(240, 240, 120, 120);
g.setColor(Color.CYAN);
g.fillOval(240, 240, 120, 120);
// drawing square
g.drawRect(350, 350, 250, 100);
g.setColor(Color.magenta);
g.fillRect(350, 350, 250, 100);
// drawing trinale
}
}
Just an idea how to do it. Notice, that the drawing is hidden from the shapes collection.
interface Drawable {
public void draw(Graphics g);
}
class DrawableSquare implements Drawable{
public DrawableSquare(int x, int y, int width) { ... }
public void draw(Graphics g)
{
g.fillRect(x, y, width, width);
}
}
class Screen {
Collection<Drawable> drawables;
public void paint(Graphics g) {
for (Drawable dr: drawables) {
dr.draw(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: