package Main;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Main extends JFrame{
public static void main(String[] args) {
int width = 800;
int height = 600;
String title = "Test";
JFrame display = new JFrame();
display.setTitle(title);
display.setSize(width, height);
display.setVisible(true);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
g.setColor(Color.white);
g.drawLine(0, 100, 800, 300);
getContentPane().setBackground(Color.black);
}
}
I'm using Java's JFrame. So this isn't recognising the paint method and cant figure out why. I've been looking on YouTube videos and having a look to see if anyone has had similar problems, however everything I've found doesn't seem to help the problem.
when i set the background colour in the main part, it works, bit in paint, it doesn't seem to do anything and leaves it blank.
Its a white line over a black background, so i should easily be able to see it.
Admittedly, I don't know much about Swing (I prefer JavaFX). However, it's clear that your Main class is a JFrame, so you should not make a new one within it. All of those methods you call on display are built in your current class. Basically, within your JFrame you made a new JFrame. However, your paint method was being called on the parent JFrame, which you never made visible. This solves your problem (you may have to fullscreen the window):
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Main extends JFrame{
public static void main(String[] args) {
new Main();
}
public Main() {
int width = 800;
int height = 600;
String title = "Test";
setTitle(title);
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.drawLine(100, 100, 800, 300);
getContentPane().setBackground(Color.black);
}
}
You are creating an instance of JFrame with
JFrame display = new JFrame();
But the JFrame class has no logic to draw a white line on a black background. That logic is in your custom class Main. So instead, you should create an instance of Main:
JFrame display = new Main();
However, that change along still won't fix the problem because you are setting the background color of the "content pane" but trying to draw directly on the JFrame itself. The preferred solution here is to extend JPanel instead of JFrame and override its paintComponent() method. Then create an instance of your new class to use as the content pain:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainPanel extends JPanel{
public static void main(String[] args) {
int width = 800;
int height = 600;
String title = "Test";
JFrame display = new JFrame();
display.setTitle(title);
display.setSize(width, height);
display.setVisible(true);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setContentPane(new MainPanel());
}
public MainPanel() {
setBackground(Color.black);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.drawLine(0, 100, 800, 300);
}
}
Notes:
I call setBackground() in the constructor because it does not rely on the Graphics instance passed to paintComponent(). This also avoids the overhead of another function call for each render.
In paintComponent(), I call super.panitComponent(). This allows JPanel to clear the area to be painted and any other necessary initialization.
Related
I need help here. I want to give a parameter to the drawLine() method which I get from getSize(). I want to draw a line throughout the whole window by using the getSize() method.
package PROG2;
import java.awt.*;
import javax.swing.*;
class MyComponent extends JComponent {
#Override
public void paintComponent(Graphics g) {
g.drawLine(100, 100, 200, 200);
}
}
public class Übung1 extends JFrame{
public static void berechnen() {
int height = frame.getHeight(); //Here it says it doesn't know "frame" variable but I don't know how to declare it here.
int width = frame.getWidth();
}
public static void main(String[] args){
JFrame frame = new JFrame("First window");
berechnen();
frame.add(new MyComponent());
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Graphics g = frame.getGraphics();
// int width = frame.getWidth();
// int height = frame.getHeight();
System.out.println("Größe:" + frame.getSize());
//System.out.println(width);
}
}
As Andrew already stated,
you don't want to get the dimensions or size of the JFrame but rather the component that is being displayed within the JFrame's contentPane, here your MyComponent instance.
The best place to get that information is inside of the paintComponent method itself, just prior to drawing the line.
And always call the super's painting method first
I also recommend:
Draw within a JPanel's paintComponent method, not a JComponent, if you want an opaque image
Avoid static methods and fields unless absolutely needed
Note that in the code below, the red line draws through the JPanel's diagonal, and continues to draw the diagonal, even when the JFrame is manually resized:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import javax.swing.*;
public class DrawLine extends JPanel {
private static final Stroke LINE_STROKE = new BasicStroke(15f);
private static final Dimension PREF_SIZE = new Dimension(800, 650);
public DrawLine() {
setPreferredSize(PREF_SIZE);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// code to make the line smooth (antialias the line to remove jaggies)
// and to make the line thick, using a wider "stroke"
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(LINE_STROKE);
// if we want a red line
g2.setColor(Color.RED);
// this is the key code here:
int width = getWidth();
int height = getHeight();
// draw along the main diagonal:
g2.drawLine(0, 0, width, height);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
DrawLine mainPanel = new DrawLine();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
I want to make the line I draw of a jpanel not change when I resize the jframe that its on. I just want it to remain in it's original position and if I resize the jframe its on to be smaller, then part of the line should be hidden rather than the line being resized?
import javax.swing.JFrame;
import java.awt.*;
public class GUIIntroduction {
public static void main(String[] args){
DrawPanel panel = new DrawPanel();
JFrame app = new JFrame();
panel.setBounds(0,0,60,60);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.add(panel);
app.setSize(600,600);
app.setVisible(true);
}
}
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawPanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.drawLine(0,height,width,0);
}
}
g.drawLine(0,height,width,0);
If you don't want the size of the line to change, then why are you using dynamic variables in the painting method
The values of width and height change as the frame is resized.
Just use:
g.drawLine(0, 100, 100, 0);
I am trying to do a very simple thing.. set the background color on the JPanel inside my JFrame. I have not used swing very much so I am still learning. However, I have read up on doing something as basic as setting the background color quite a bit, and I do not know why what I have is not working.
I have my JFrame set up in my Main class.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Main extends JFrame {
private static Screen screen;
private static int WIDTH = 600;
private static int HEIGHT = 600;
public Main() {
screen = new Screen();
setTitle("Asteroid");
setSize(WIDTH, HEIGHT);
setLayout(new BorderLayout());
add(screen, BorderLayout.CENTER);
setBackground(Color.BLACK);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
#Override
public void paint(Graphics g) {
}
public static void main(String[] args) {
new Main();
}
}
And then I have my JPanel set up in a Screen class
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
public class Screen extends JPanel {
private static int WIDTH = 600;
private static int HEIGHT = 600;
private Dimension screen = new Dimension(WIDTH, HEIGHT);
public Screen() {
setSize(screen);
setBackground(Color.BLACK);
setOpaque(true);
}
}
I am not sure why this is not working properly.
The problem is that you #Override paint method (you should not) of your JFrame. In addition you leave it empty, without calling the super paint method. So, if you simply add super.paint(g); to your #Override you will see that background is painted without problems.
However, when you want to do custom painting, you should #Override paintComponent(Graphics g) method, and again, start by calling super.paintComponent(g);.
Im trying to add a JScrollpane to my JPanel. The problem is that the scrollpane doesn't recognize that my drawing is outside the frame. So how do I add the JScrollpane correctly?
Main class:
public MainFrame() extends JFrame{
public MainFrame() {
Container container = getContentPane();
container(new BorderLayout());
container.add(new JScrollPane(new Drawing()));
setSize(1280,720);
setVisible(true);
}
Drawing class:
public class Drawing() extends JPanel {
#Override
protected void paintComponent(Graphics g) {
g.drawLine(10, 100, 30000, 10);
}
}
There are a couple of errors in your code, let's step through each of them:
You're extending JFrame, and you should avoid it, see: Extends JFrame vs. creating it inside the program for more information about it. You're actually not changing its behavior so it's not needed to extend it.
For your JScrollPane to show the whole line, you need to change your window's size to be the same size of your line (as shown in this answer by #MadProgrammer).
Related to point 2, avoid the use of setSize(...) and instead override getPreferredSize(): See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more information
You forgot to call super.paintComponent(...) method in your paintComponent() method.
Related to points 2, 3, you need to call pack() so Swing calculates the best preferred size for your component.
See this example:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class LongDraw {
private JFrame frame;
private Drawing drawing;
public static void main(String[] args) {
SwingUtilities.invokeLater(new LongDraw()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
drawing = new Drawing();
JScrollPane scroll = new JScrollPane(drawing);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class Drawing extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(10, 100, 3000, 10);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(3000, 500);
}
}
}
Which produces something similar to this:
Im trying to simplify some basic code, an I've come across a small problem. I was under the impression that the paint method was called automatically, and i based that off every other basic program i have written. I dont get any erros, just the code doesn't work, and i cant call repaint() either.
Code:
public class Dynamic_Bg_Color{
JFrame frame;
public Dynamic_Bg_Color(){
frame = new JFrame("BG Color Changer");
}
public void paint(Graphics g1){
Graphics g = (Graphics)g1;
g.setColor(Color.pink);
g.fillRect(20,20,frame.getWidth()-20,100);
}
public static void main(String[] args){
Dynamic_Bg_Color d = new Dynamic_Bg_Color();
Dimension size = new Dimension(500,400);
d.frame.setPreferredSize(new Dimension(size));
d.frame.setMinimumSize(new Dimension(size));
d.frame.setMaximumSize(new Dimension(size));
d.frame.setLocationRelativeTo(null);
d.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.frame.setLayout(new FlowLayout());
d.frame.setVisible(true);
d.frame.getContentPane().setBackground(Color.cyan);
}
}
The paint method only gets called if it is an override, and the class extends another class where the paint method has meaning. Your class does not do this, and so your paint method is meaningless.
Having said that, I'm going to suggest that you don't overload paint but rather paintComponent(...) in a class that extends JComponent or one of its children. And most importantly, read the painting with Swing tutorial. Please start here.
As an aside, casting a Graphics object to a Graphics object achieves nothing. Perhaps you copied your code incorrectly and were meaning to cast it to a Graphics2D type?
I made the class extend JComponent, and added the override, but nothing has changed.
I don't see where you add the component to the frame.
Even if you did add the component to the frame is wouldn't paint because the default size of your component is (0, 0) so there is nothing to paint.
You also need to restructure your code. A JFrame variable does not belong to the component where you do custom painting. I suggest you read the section from the Swing tutorial on Custom Painting. It will show you:
How to do custom painting including how you specify a preferred size for your component
How to better structure your program, included executing your code on the Event Dispatch Thread
With minimal changes made the working code:
import javax.swing.*;
import java.awt.*;
public class Dynamic_Bg_Color extends JPanel{
JFrame frame;
public Dynamic_Bg_Color(){
frame = new JFrame("BG Color Changer");
}
public void paint(Graphics g1){
Graphics g = (Graphics2D)g1;
g.setColor(Color.pink);
g.fillRect(20,20,frame.getWidth()-20,100);
}
public static void main(String[] args){
Dynamic_Bg_Color d = new Dynamic_Bg_Color();
Dimension size = new Dimension(500,400);
d.setPreferredSize(new Dimension(size));
d.setMinimumSize(new Dimension(size));
d.setMaximumSize(new Dimension(size));
d.frame.add(d);
d.frame.setLocationRelativeTo(null);
d.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.frame.setLayout(new FlowLayout());
d.frame.pack();
d.frame.setVisible(true);
d.frame.getContentPane().setBackground(Color.cyan);
}
}
But, as others said, I don't suggest you use this cause it is very very bad structure of the program. And read the tutorial on painting, even if I think that Oracles tutorial on this is bad (frame.pack() just sets the size of the JFrame window as big as to hold the components it contains).
Heres the final working code. A few changes being it extended JPanel, setting the size of the JPanel, and adding the panel to the JFrame. Yes i know as everybody stated, this is not an optimal way of doing this, but for right now, it works.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Dynamic_Bg_Color extends JPanel{
private static final long serialVersionUID = 1L;
static Dimension size = new Dimension(500,400);
static JFrame frame;
public Dynamic_Bg_Color(){
setPreferredSize(size);
setBackground(Color.cyan);
addMouseListener(new Handler());
}
#Override
public void paintComponent(Graphics g){
System.out.println("Click");
super.paintComponent(g);
g.setColor(Color.blue);
g.fillRect(20,20,getWidth()-40,100);
g.setColor(Color.green);
g.fillRect(20,140,getWidth()-40,100);
g.setColor(Color.orange);
g.fillRect(20,260,getWidth()-40,100);
}
public static void main(String[] args){
Dynamic_Bg_Color d = new Dynamic_Bg_Color();
frame = new JFrame("BG Color Changer");
frame.setPreferredSize(new Dimension(size));
frame.setMinimumSize(new Dimension(size));
frame.setMaximumSize(new Dimension(size));
frame.setLayout(new FlowLayout());
frame.setLocationRelativeTo(null);
frame.add(d);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.cyan);
frame.setVisible(true);
}
public class Handler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if(x>= 20 && x<=getWidth()-40 && y>=20 && y<= 120){
frame.getContentPane().setBackground(Color.blue);
setBackground(Color.blue);
frame.setTitle("Blue");
}
if(x>= 20 && x<=getWidth()-40 && y>=140 && y<= 240){
frame.getContentPane().setBackground(Color.green);
setBackground(Color.green);
frame.setTitle("Green");
}
if(x>= 20 && x<=getWidth()-40 && y>=260 && y<= 360){
frame.getContentPane().setBackground(Color.orange);
setBackground(Color.orange);
frame.setTitle("Orange");
}
}
}
}