I have the following simple code in a JFrame constructor
super(name);
setBounds(0,0,1100,750);
setLayout(null);
setVisible(true);
g = this.getGraphics();
int[] x =new int[]{65, 122, 77, 20, };
int[] y =new int[]{226, 258, 341, 310};
g.setColor(Color.RED);
g.drawPolygon (x, y, x.length);
System.out.println(g);
I get the output on console as:
sun.java2d.SunGraphics2D[font=java.awt.Font[family=Dialog,name=Dialog,style=plain,size=12],color=java.awt.Color[r=255,g=0,b=0]]
But no red polygon drawn on JFrame but just the blank JFrame.
Why ??
Dont overridepaint(..) in JFrame
Rather add custom JPanel with overridden paintComponent(Graphics g) to JFrame
Dont use Null/AbsoluteLayout use an appropriate LayoutManager
Dont call setBounds(..) on JFrame instance (not that its not allowed but cant see it being relevant in this application)
Dont forget to use EDT for creating and changing GUI components:
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Test test = new Test();
}
});
you would then do something like this:
public class Test {
/**
* Default constructor for Test.class
*/
public Test() {
initComponents();
}
public static void main(String[] args) {
/**
* Create GUI and components on Event-Dispatch-Thread
*/
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Test test = new Test();
}
});
}
/**
* Initialize GUI and components (including ActionListeners etc)
*/
private void initComponents() {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.add(new MyPanel());
//pack frame (size JFrame to match preferred sizes of added components and set visible
jFrame.pack();
jFrame.setVisible(true);
}
}
class MyPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int[] x = new int[]{65, 122, 77, 20};
int[] y = new int[]{226, 258, 341, 310};
g.setColor(Color.RED);
g.drawPolygon(x, y, x.length);
}
//so our panel is the corerct size when pack() is called on Jframe
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
which produces:
You should better override paint(Graphics g) or paintComponent(Graphics g) than the approach you are trying. Add the lines below and remove the lines after setVisible in your code.
public void paint(Graphics g) {
int[] x =new int[]{65, 122, 77, 20};
int[] y =new int[]{226, 258, 341, 310};
g.setColor(Color.RED);
g.drawPolygon (x, y, x.length);
}
Related
Here is a minimal code to see the bug:
import javax.swing.*;
import java.awt.*;
public class Main1 extends JFrame {
static Main1 main;
public Main1() {
super("app");
}
public static void main(String[] args) {
main = new Main1();
main.setBounds(300, 300, 800, 500);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
Graphics g = main.getGraphics();
for(int i = 0; i < 100; i++){
g.setColor(new Color(255, 0, 0));
g.fillRect(0, 0, 800, 500);
}
}
}
If i use 100 in the "for" cycle, the frame appears not to be colored, but 200 loops is enough to color it.
I want to make an application where frames change rarely, but this feature ruins the quality of code because I have to make a number of dummy frames.
public static void main(String[] args) {
main = new Main1();
main.setBounds(300, 300, 800, 500);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
Graphics g = main.getGraphics();
for(int i = 0; i < 100; i++){
g.setColor(new Color(255, 0, 0));
g.fillRect(0, 0, 800, 500);
}
}
This is not how you do Swing graphics. Getting a Graphics object by calling .getGraphics() on a component gives you a short-lived unstable and sometimes null object. For instance, it takes some time for the created JFrame to render, and if you call getGraphics() and try to use it prior to rendering, the object may be null, and certainly won't wokr.
Instead paint within a JPanel's paintComponent method using the Graphics object given by the JVM as per the tutorials:
public class MainPanel extends JPanel {
public MainPanel {
setPreferredSize(new Dimension(800, 500)));
setBackground(new Color(255, 0, 0)); // if you just want to set background
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// use g here do do your drawing
}
}
and then use it like so:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
Tutorial: Lesson: Performing Custom Painting
And yes, if you want to drive a simple animation, use a Swing Timer to help drive it like so:
public class MainPanel extends JPanel {
private int x = 0;
private int y = 0;
public MainPanel {
setPreferredSize(new Dimension(800, 500)));
setBackground(new Color(255, 0, 0)); // if you just want to set background
// timer code:
int timerDelay = 15;
new Timer(timerDelay, ()-> {
x += 4;
y += 4;
repaint();
}).start();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// use g here do do your drawing
g.setColor(Color.BLUE);
g.drawRect(x, y, 20, 20);
}
}
How to change the color of rectangle ? I want change it to yellow color. I added g.setColor(Color.YELLOW); inside rectDraw, but the color of the rectangle still remain the same. Can someone tell me what wrong I did please?
public class SelectSeat {
static JFrame frame;
public JPanel createContentPane() throws IOException
{
JPanel totalGUI = new JPanel();
RectDraw rect= new RectDraw();
rect.setPreferredSize(new Dimension(330,35)); //for size
totalGUI.setLayout(null);
totalGUI.setBackground(Color.WHITE);
totalGUI.add(rect);
Dimension d = rect.getPreferredSize();
rect.setBounds(100, 20, d.width, d.height); // for location
return totalGUI;
}
void setVisible(boolean b) {
// TODO Auto-generated method stub
}
static void createAndShowGUI() throws IOException
{
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame("Seat Selection");
//Create and set up the content pane.
SelectSeat demo = new SelectSeat();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(535, 520);
frame.setLocation(500,220);
frame.setVisible(true);
}
private static class RectDraw extends JPanel
{
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawString("Movie Sceen", 130, 20);
}
}
}
How to change the color of rectangle ? I want change it to yellow color.
You need to set the color to yellow, followed by filling a rectangle the size of the component.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.YELLOW);
g.fillRect(0,0,getWidth(), getHeight());
g.setColor(Color.BLUE);
g.drawString("Movie Sceen", 130, 20);
}
And for what its worth:
totalGUI.setLayout(null);
I would recommend against using null Layouts. Use a LayoutManager appropriate to the task, and remember that you can nest layouts within the Component hierarchy.
How to do it? I mean, I can do it for Ellipse, but not sure about triangle.
You can use a Polygon.
int[] xPoints = {0, 0, 30};
int[] yPoints = {0, 30, 30};
Shape s = new Polygon(xPoints, yPoints, 3);
g2d.fill(s);
This doesn't answer your current question.
It demonstrates why you should NOT use panel.getGraphics() to do your painting. Painting done with the getGraphics() method is not permanent.
Try minimizing or maximizing the frame and see what happens to the painting:
import java.awt.*;
import javax.swing.*;
public class SSCCE2
{
private static void createAndShowGUI()
{
final JPanel panel = new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillOval(0, 0, 50, 50);
}
};
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setLocationByPlatform( true );
frame.setSize(300, 300);
frame.setVisible( true );
Graphics g = panel.getGraphics();
g.setColor(Color.RED);
g.fillOval(100, 100, 50, 50);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Graphics g = panel.getGraphics();
g.setColor(Color.RED);
g.fillOval(100, 100, 50, 50);
}
});
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
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);
}
}
can someone take a look at my code below and tell me why, when I change the following two statements, I do not see a change on the rectangle that is painted. So if I change:
g.setColor(Color.black);
g.fillRect(l, w, 100, 100);
The program still prints a black rectangle with the same dimensions and in the same position that I first started with even though I change color to yellow or try to change the dimensions or location. I am BlueJ. The following is my full code:
import java.awt.*;
import javax.swing.*;
public class SwingPaintDemo2 extends JComponent {
public static boolean isWall = true;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
//System.out.println("Created GUI on EDT? "+
//SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
JPanel MyPanel = new JPanel();
MyPanel.setBorder(BorderFactory.createEmptyBorder(1000, 1000, 1000, 1000));
MyPanel.setPreferredSize(new Dimension(250, 200));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int l = 10;
int w = 10;
g.setColor(Color.black);
g.fillRect(l, w, 100, 100);
}
}
Any advice would be appreciated.
Your SSCCE doesnt compile where is MyPanel class or did you mean new SwingPaintDemo2()?
On the assumption you meant new SwingPaintDemo2():
The code does work just fine but the JFrame is sized very small:
because you dont give it any size and none of its components have a size as they do not have any components added to them, thus we must make the JComponent return a correct size so when we call pack() our JFrame is sized correctly
Solution
override getPreferredSize() of JComponent to return a width and height which fits all drawings.
Some suggestions though:
Dont extend JComponent rather extend JPanel
Here is an example (your code with above fixes implemented):
import java.awt.*;
import javax.swing.*;
public class SwingPaintDemo2 extends JPanel {
public static boolean isWall = true;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
//System.out.println("Created GUI on EDT? "+
//SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
JPanel MyPanel = new JPanel();
MyPanel.setBorder(BorderFactory.createEmptyBorder(1000, 1000, 1000, 1000));
MyPanel.setPreferredSize(new Dimension(250, 200));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new SwingPaintDemo2());
f.pack();
f.setVisible(true);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int l = 10;
int w = 10;
g.setColor(Color.black);
g.fillRect(l, w, 100, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
}