Paint method java - Rectangle with outline - java

I want to create a wall with a blue line outline and black filling. I have only a blue wall now and I tried a couple of the Graphics methods but wasn't working.
public void paint(Graphics g) {
g.setColor(Color.blue);
g.fillRect(x, y, size, size);
}

Use Graphics#drawRect to draw the outline: -
g.setColor(Color.black);
g.fillRect(x, y, size, size);
g.setColor(Color.blue);
g.drawRect(x, y, size, size);

First, override paintComponent, not paint. Second, there's no need to re-invent the wheel like that. Instead, use an existing Swing component (e.g. JPanel),
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(getWallComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private static JPanel getWallComponent()
{
JPanel panel = new JPanel();
panel.setBackground(Color.black);
panel.setBorder(BorderFactory.createLineBorder(Color.blue, 5));
panel.setPreferredSize(new Dimension(200, 200)); // for demo purposes only
return panel;
}
}

Just paint another rectangle over the blue one, smaller than the blue one, like below
public void paint(Graphics g) {
g.setColor(Color.blue);
g.fillRect(x, y, size, size);
g.setColor(Color.black);
g.fillRect(x-width/2,y-width/x,size-width,size-with);
}

package painting;
import java.awt.*;
import javax.swing.*;
public class RectangleOutline extends JPanel {
int x = 100;
int y = 200;
public void paintComponent(Graphics g) {
super.paintComponent(g);
outline(g);
}
public void outline(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(255, 0, 0));
g2.fillRect(x, y, 30, 30);
g2.setStroke(new BasicStroke(5));
g2.setColor(new Color(0, 0, 0));
g2.drawRect(x, y, 30, 30);
}
public static void main(String[] args){
JFrame f = new JFrame();
RectangleOutline graphics = new RectangleOutline();
f.add(graphics);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setSize(400, 400);
}
}

Related

How do you create a gradient for JPanel? Also, how do you call a class within a class in Java?

I am making a Java GUI and I have searched the internet for 2 hours on how make a gradient for a JPanel. The code below is that I have, but when run the gradient does not show. What is wrong?
I've tried many other posts from similar questions on this throughout the Internet but they don't work. I've tried numerous versions, but I also don't exactly know how to run a class within a class. Can someone help me please?
class TestPanel extends JPanel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int w = getWidth();
int h = getHeight();
Color color1 = Color.BLUE;
Color color2 = Color.GREEN;
GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
}
} //this is nested within the main class
//some code
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CreateGUI cg = new CreateGUI();
cg.create(); //previous method (not mentioned here)
CreateGUI.TestPanel tp = cg.new TestPanel(); //problem
JPanel panel = new JPanel();
f.add(panel);
f.setSize(800, 600);
f.setLocationRelativeTo(null);
f.getContentPane().setLayout(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
I expect there to be a gradient but there is none; the background of the JPanel is still white
The instance of TestPanel is never added to anything
null layouts will prevent the component from been sized and positioned, so you won't see anything even if your did the previous step
You should, unless you're adding child components to it, provide a sizing hint, so that the layout managers have something to work with.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class TestPanel extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int w = getWidth();
int h = getHeight();
Color color1 = Color.BLUE;
Color color2 = Color.GREEN;
GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
g2d.dispose();
}
}
}

Why are Graphics2D rectangles not displayed?

I need to be able to display filled rectangles for the program i am creating, however the following code produces the following GUI with only the black text 'test' after calling start then change, could anyone explayin why please?
package core;
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class GUI extends JFrame{
private Graphics2D g;
private int[][][] clickable;
public void start(){
this.setSize(500, 500);
this.setTitle("Placeholder");
this.setVisible(true);
g = (Graphics2D) this.getGraphics();
}
public void change(String[] fields, int type[], boolean forwards){
g.setColor(new Color(28,35,57));
g.drawRect(0, 0, 100, 100);
g.drawRect(50, 50, 150, 150);
g.fillRect(0, 0, 100, 100);
g.drawString("test", 300, 300);
}
}
And here is what it looks like ..
Drawing on Swing components (like JFrame) works only in onPaint event.
The event can be fired using repaint() method.
This event fires automatically when frame needs to be painted.
To implement this event behavior override paint() method.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
public class GUI extends JFrame{
private Graphics2D g;
public void start(){
this.setSize(500, 500);
this.setTitle("Placeholder");
this.setVisible(true);
}
public void change(){
g.setColor(new Color(28,35,57));
g.drawRect(0, 0, 100, 100);
g.drawRect(50, 50, 150, 150);
g.fillRect(0, 0, 100, 100);
g.drawString("test", 300, 300);
}
public void paint(Graphics g2d){
g = (Graphics2D) g2d;
change();
}
public static void main(String[] args){
GUI frame = new GUI();
frame.start();
}
}

Setting the origin on a canvas

I am trying to create a simple graphing program, and I want/need the origin to be at the bottom left corner, so I am using the following custom canvas:
public class GraphingCanvas extends Canvas {
public GraphingCanvas() {
}
public void paint(Graphics g) {
((Graphics2D) g).translate(this.getWidth(), this.getHeight());
g.translate(10, 10);
g.setColor(Color.BLACK);
g.drawLine(0, 0, 10, 10);
}
}
However, when I use this canvas, like so:
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
GraphingCanvas canvas = new GraphingCanvas();
canvas.setBackground(Color.WHITE);
canvas.setBounds(10, 10, 414, 241);
frame.getContentPane().add(canvas);
}
The origin appears to remain at the default. Am I doing something wrong?
This may or may not do what you want, but basically I used scale(1, -1) to flip the orientation through the y-axis (and translated the context)
The magic basically happens in the paintComponent method using...
g2d.scale(1, -1);
g2d.translate(0, -getHeight());
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Rectangle box = new Rectangle(10, 10, 20, 20);
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
draw(g2d, Color.RED, Color.MAGENTA);
g2d.dispose();
g2d = (Graphics2D) g.create();
g2d.scale(1, -1);
g2d.translate(0, -getHeight());
draw(g2d, Color.BLUE, Color.GREEN);
g2d.dispose();
}
protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {
g2d.setColor(boxColor);
g2d.fill(box);
g2d.setColor(lineColor);
g2d.drawLine(0, 0, getWidth(), getHeight());
}
}
}
Just to be sure, I created a simple method...
protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {
g2d.setColor(boxColor);
g2d.fill(box);
g2d.setColor(lineColor);
g2d.drawLine(0, 0, getWidth(), getHeight());
}
which is called with the "normal" orientation and then called again with the transformed orientation, so it's the same code been used to paint the output, the only thing that's changed is the orientation

How to fill the whole window in awt

I'm using java awt to render a simple rectangle. I also have a rectangle to be used as the background of the window. The thing is, even though the background rectangle is set to the window's width and height, it still doesn't fit the whole thing. I've tried to Google this, but found results irrelevant to my needs. What's causing this?
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferStrategy;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game implements Runnable{
final int WIDTH = 640;
final int HEIGHT = 480;
JFrame frame;
Canvas canvas;
BufferStrategy bufferStrategy;
boolean running = false;
public Game(){
frame = new JFrame("Prototyping");
JPanel panel = (JPanel) frame.getContentPane();
panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
panel.setLayout(null);
canvas = new Canvas();
canvas.setBounds(0, 0, WIDTH, HEIGHT);
canvas.setIgnoreRepaint(true);
panel.add(canvas);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
canvas.createBufferStrategy(2);
bufferStrategy = canvas.getBufferStrategy();
canvas.requestFocus();
}
public void run(){
running = true;
while(running)
render();
}
private void render() {
Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
g.clearRect(0, 0, WIDTH, HEIGHT);
render(g);
g.dispose();
bufferStrategy.show();
}
protected void update(){
}
protected void render(Graphics2D g){
g.setColor(Color.GRAY);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLUE);
g.fillRect(100, 0, 200, 200);
}
public static void main(String [] args){
Game game = new Game();
new Thread(game).start();
}
}
This works flawlessly here. Go through it carefully for differences, since I've forgotten what is changed.
import java.awt.*;
import java.awt.image.BufferStrategy;
import javax.swing.*;
public class Game implements Runnable{
final int WIDTH = 640;
final int HEIGHT = 480;
JFrame frame;
Canvas canvas;
BufferStrategy bufferStrategy;
boolean running = false;
public Game(){
frame = new JFrame("Prototyping");
JPanel panel = (JPanel) frame.getContentPane();
panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
panel.setLayout(new GridLayout());
canvas = new Canvas();
//canvas.setBounds(0, 0, WIDTH, HEIGHT);
canvas.setIgnoreRepaint(true);
panel.add(canvas);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
canvas.createBufferStrategy(2);
bufferStrategy = canvas.getBufferStrategy();
canvas.requestFocus();
}
public void run(){
running = true;
while(running)
render();
}
private void render() {
Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
g.clearRect(0, 0, WIDTH, HEIGHT);
render(g);
g.dispose();
bufferStrategy.show();
}
protected void render(Graphics2D g){
g.setColor(Color.GRAY);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLUE);
g.fillRect(100, 0, 200, 200);
}
public static void main(String [] args){
Game game = new Game();
new Thread(game).start();
}
}

Java window doesn't repaint properly until I resize the window manually

I am using a quite basic setup with a class extending JPanel, which I add to a JFrame.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
public class PinTestMCVE extends JPanel implements ActionListener{
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
new PinTestMCVE();
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
jf.getContentPane().add(this, BorderLayout.CENTER);
jf.setSize(1250, 950);
jf.setVisible(true);
}
public void paintComponent(Graphics g) {
g.drawImage(loadedImage, 0, 0, this);
}
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
int x = 5;
int y = 7;
GradientPaint redtowhite = new GradientPaint(x, y, Color.red, 200, y, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(x, y, 200, 200, 10, 10));
return image;
}
}
What happens is that INITIALLY the window is painted properly, but once paintComponent is called, a strip of the old image (with the same height as the toolbar panel) is visible below the newly painted images - similar to playing card sticking out from a deck. But then, if I manually resize the window by for instance dragging the border, the background is grayed out as it should.
What is going on and how do I fix this?
As outlined here, you need to pack() the frame before calling setVisible(). You can override getPreferredSize() to specify a suitable initial Dimension. Also consider using a Border. See also Initial Threads.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.*;
public class PinTestMCVE extends JPanel implements ActionListener{
private static final int SIZE = 200;
BufferedImage loadedImage;
JButton calcButton;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PinTestMCVE();
}
});
}
public PinTestMCVE() {
loadedImage = getTestImage();
JPanel toolbarPanel = new JPanel();
calcButton = new JButton("calcButton...");
toolbarPanel.add(calcButton);
calcButton.addActionListener(this);
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(toolbarPanel, BorderLayout.NORTH);
jf.add(this, BorderLayout.CENTER);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(loadedImage, 0, 0, this);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent " + e.getActionCommand());
if(e.getSource().equals(calcButton)){
this.repaint();
}
}
//Please ignore the inner workings of this
public static BufferedImage getTestImage(){
BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.GRAY);
g2d.fillRect ( 0, 0, image.getWidth(), image.getHeight() );
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.gray);
GradientPaint redtowhite = new GradientPaint(5, 5, Color.red, SIZE, 5, Color.blue);
g2d.setPaint(redtowhite);
g2d.fill(new RoundRectangle2D.Double(5, 5, SIZE - 10, SIZE - 10, 10, 10));
return image;
}
}

Categories