Java Drawing to a JPanel (debugging) - java

I'm trying to draw a basic object to a JPanel
although it doesn't seem to be working.
I'm certain I am doing something wrong with where the paint method
is being called
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class testGui {
static colors gc_colors;
static gui gc_gui;
public static void main(String[] args) {
gc_colors = new colors();
gc_gui = new gui();
gc_gui.cv_frame.setVisible(true);
}
public static class colors {
Color cv_ltGrey;
Color cv_mdGrey;
Color cv_dkGrey;
public colors() {
cv_ltGrey = Color.decode("#DDDDDD");
cv_mdGrey = Color.decode("#CCCCCC");
cv_dkGrey = Color.decode("#111111");
}
}
public static class gui {
JFrame cv_frame;
JPanel cv_panel;
JPanel cv_content;
public gui() {
cv_frame = new JFrame();
cv_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cv_frame.setTitle("Test GUI");
cv_frame.setSize(600, 400);
cv_frame.setLayout(new FlowLayout());
cv_panel = new JPanel();
cv_panel.setBackground(gc_colors.cv_ltGrey);
cv_panel.setPreferredSize(new Dimension(500, 300));
cv_frame.add(cv_panel);
cv_content = new content();
cv_panel.add(cv_content);
}
}
public static class content extends JPanel {
public void paint(Graphics graphic) {
super.paint(graphic);
draw(graphic);
}
public void update() {
repaint();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.setPaint(gc_colors.cv_ltGrey);
graphic2D.fillRect(10, 10, 100, 100);
}
}
}
I have a class for my gui which I am adding a JPanel to (a light grey one).
Which I am then trying to add my drawing to using a JPanel extended class
called content.
When I run it though it seems to create the grey JPanel which I want but
the drawing is just a tiny white square and I'm not sure why.

So, you content panel has a default preferred size of 0x0, FlowLayout honours the preferredSize of its components (with a little margin), hence the reason why you have a nice little small white rectangle.
What you need to do is override the getPreferredSize method of the content panel and return a suitable size, for example
public static class content extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 120);
}
public void paint(Graphics graphic) {
super.paint(graphic);
draw(graphic);
}
public void update() {
repaint();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.setPaint(gc_colors.cv_ltGrey);
graphic2D.fillRect(10, 10, 100, 100);
}
}

I've decided to just leave out the second JPanel altogether.
It was too much of a hassle to put the JPanel inside of another JPanel
so instead I am only going to use a single JPanel
public static class gui {
JFrame cv_frame;
JPanel cv_panel;
JPanel cv_content;
public gui() {
cv_frame = new JFrame();
cv_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cv_frame.setTitle("Test GUI");
cv_frame.setSize(600, 400);
cv_frame.setLayout(new FlowLayout());
cv_content = new content();
cv_content.setBackground(gc_colors.cv_ltGrey);
cv_content.setPreferredSize(new Dimension(500, 300));
cv_frame.add(cv_content);
}
}

Related

How can I move a graphics element on my java panel?

I am currently working on a simple pong-like game, but I got stucked with positioning the rectangle.
I want to change it's Y position to be at the half of the actual panel's height.
package com.game;
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("gEngine");
Player playerOne = new Player(frame);
Player playerTwo = new Player(frame);
}
}
package com.game;
import javax.swing.*;
import java.awt.*;
public class Player {
public Player(JFrame frame) {
MyPanel panel = new MyPanel();
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.BLACK);
frame.setSize(1280, 720);
frame.setVisible(true);
}
}
class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(50, 60, 20, 120);
}
}
Your code has a lot of "problems". I suggest you to find some kind of tutorials or something. You frame.setVisible(true) and stuff inside Player's class constructor. Do you realize that every time you create a Player object, all these things will be applied to the JFrame? Is this necessary? Maybe you should do them only once. Also in order to paint the compnent according to its position according size, you can do g.fillRect(50, getHeight() / 2, 20, 120);
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("gEngine");
Player playerOne = new Player();
Player playerTwo = new Player();
// Set the proper layout manager
frame.setLayout(new GridLayout());
frame.add(playerOne.getMyPanel());
frame.add(playerTwo.getMyPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.BLACK);
frame.setSize(1280, 720);
frame.setVisible(true);
}
public static class Player {
private JPanel myPanel;
public Player() {
this.myPanel = new MyPanel();
}
public JPanel getMyPanel() {
return myPanel;
}
}
static class MyPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
// let the component be painted "natural"
super.paintComponent(g);
// Do custom painting
g.setColor(Color.WHITE);
g.fillRect(50, getHeight() / 2, 20, 120);
}
}
}
Edit (based on comment):
The background is the default one because GridLayout splits the screen into 2 panels (in the middle of the frame). Even the frame has BLACK background, these 2 panels cover it. So the background you see is from the panels, and not from the frame. In order to change it you will have to change the background of the panels (and make them non-transparent):
static class MyPanel extends JPanel {
public MyPanel() {
super();
setOpaque(true);
setBackground(Color.BLACK);
}
#Override
public void paintComponent(Graphics g) {
// let the component be painted "natural"
super.paintComponent(g);
// Do custom painting
g.setColor(Color.WHITE);
g.fillRect(50, getHeight() / 2, 20, 120);
}
}

How to draw PNG Image onto JPanel?

I'm trying to draw a image onto a JPanel by overriding the paintComponent method. However, I'm having no luck with it at all and I don't know why.
Here's the code I've got at the moment:
DrawPanel
public class DrawPanel extends JPanel{
private Image backgroundImg;
public DrawPanel()
{
backgroundImg = Toolkit.getDefaultToolkit().createImage("C:\\Users\\Administrator\\workspace\\Scrub\\src\\loginBackground.png");
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(backgroundImg, 0, 0, null);
}
}
LoginWindow Class
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LoginWindow extends Window{
private DrawPanel panel;
public LoginWindow(int width, int height)
{
super("", width, height);
panel = new DrawPanel();
this.add(panel);
panel.setVisible(true);
}
}
Main
public class Main
{
public static void main(String[] args)
{
LoginWindow loginWindow = new LoginWindow(500, 300);
}
}
There are lots of reasons this might not work
The image might not be getting loaded. You should use ImageIO.read instead, as it will throw an IOException if something goes wrong
The layout manager is using the preferred size of your panel, which is defaulted to 0x0, making the component effectively invisible
You're not setting the window to be visible...
For example
public class DrawPanel extends JPanel{
//...
public Dimension getPreferredSize() {
return backgroundImg == null ? new Dimesion(100, 100) : new Dimension(backgroundImg.getWidth(this), backgroundImg.gtHeight(this));
}
And then in your Window class...
public LoginWindow(int width, int height)
{
super("", width, height);
panel = new DrawPanel();
this.add(panel);
// Swing components are visible by default
//panel.setVisible(true);
// windows aren't
setVisible(true);
}
A simpler soliton would be to use a JLabel...
setLayout(new BorderLayout());
BufferedImage img = ImageIO.read(new File(...));
JLabel label = new JLabel(new ImageIcon(img));
add(label);
setVisible(true);
Take a look at How to use Labels and Reading/Loading an Image for more details

Class - Graphics - drawString()

I'm trying to display a message in a JPanel.
I've used the drawString() function of the Graphics class.
Here's my code :
public class Frame {
JFrame frame;
JPanel panel;
Graphics graph;
Frame() {
frame = new JFrame();
panel = new JPanel();
frame.setTitle("My wonderful window");
frame.setSize(800, 600);
frame.ContentPane(panel);
frame.setVisible(true);
}
void displayMessage(String message) {
graph = new Graphics();
graph.drawString(message, 10, 20);
}
}
I've this error :
error: Graphics is abstract; cannot be instantiated
Override the JPanel's paintComponent(Graphics g) method. IN the method you have access to a valid Graphics instance. The method called on each paint.
But may be it's better to add a JLabel to the panel. The label initially has no text and when you have a message just call setText(messageText) of the label.
You should create subclasses for your JFrame and JPanel, and override the methods you want. You could try something like:
package test;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Frame extends JFrame {
public static final String message = "HELLO WORLD!!!";
public class Panel extends JPanel {
public void paintComponent(Graphics graph) {
graph.drawString(message, 10, 20);
}
}
public Frame() {
Panel panel = new Panel();
this.setTitle("My wonderful window");
this.setSize(800, 600);
this.setContentPane(panel);
this.setVisible(true);
}
public static void main(String[] args) {
new Frame();
}
}
Also, there are a lot of great books/tutorials about this. You should read one.
Edit:
You should also read about all the JComponents (JButtons, JLabels...). They're rather useful.

Java - Swing - painting (adding another shapes on a JPanel)

class that makes a JFrame, adds a JPanel on it and draws a rectangle on the JPanel
class Frame {
JFrame frame;
myPanel panel;
void draw() {
frame = new JFrame ("qwertz");
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setSize(300,200);
panel = new myPanel();
panel.setLayout(null);
frame.add(panel);
myPanel.a = 50;
myPanel.b = 30;
}
void add() {
//
}}
second class is the JPanel that the first class uses
class myPanel extends JPanel {
static int a;
static int b;
public void paint(Graphics g) {
g.drawRect(a,a,b,b);
}}
what is the easiest way to add another rectangle on the panel ?
(I would like the code that adds it to be in the add() method in the first class, if its possible)
You don't want to call a method "add". Every Swing component has an add method.
Create a GUI model class that holds as many rectangles as you want to define.
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
public class RectangleModel {
private List<Rectangle> rectangles;
public RectangleModel() {
this.rectangles = new ArrayList<Rectangle>();
}
public void addRectangle(int x, int y, int width, int height) {
this.rectangles.add(new Rectangle(x, y, width, height));
}
public void addRectangle(Rectangle rectangle) {
this.rectangles.add(rectangle);
}
public void draw(Graphics g) {
for (Rectangle rectangle : rectangles) {
g.drawRect(rectangle.x, rectangle.y, rectangle.width,
rectangle.height);
}
}
}
Modify your JPanel so it looks like this:
class MyPanel extends JPanel {
private RectangleModel model;
public MyPanel(RectangleModel model) {
this.model = model;
this.setPreferredSize(new Dimension(300, 200));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
model.draw(g);
}}
}
Now, all your main class has to do is:
Execute SwingUtilities.invokeLater to put all of your GUI components on the Event Dispatch thread (EDT).
Create your GUI model.
Create your GUI frame class and panel class.
Add Rectangles to your GUI model.
Pack the JFrame.

Backgroundproblem in Swing, without Netbeans

I am a total Beginner and while I had most of the Application right away. I can t make a background picture for my swing gui.
I ve read that you should do it with the overriding the paint methode, which I did. But somewhere I am making a mistake. Since nothing chances, except that the Button is invisible until I go over it with the Mouse. I tried several things, maybe one of you can see the Problem and help me out? Thanks a lot :)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
*
* #author Shore
*/
public class GUI extends JFrame implements ActionListener {
Container c;
JButton überprüfungsButton = new JButton();
JTextField eingabeTextField = new JTextField();
JTextArea ausgabeTextFeld = new JTextArea();
Image hintergrundBild;
public GUI(){
this.hintergrundBild = Toolkit.getDefaultToolkit().getImage( "Bild2.jpg" );
c = getContentPane();
c.setLayout(new BorderLayout());
c.setBackground(Color.LIGHT_GRAY);
überprüfungsButton = new JButton("Test");
überprüfungsButton.addActionListener(this);
c.add(überprüfungsButton, BorderLayout.CENTER);
eingabeTextField = new JTextField(40);
c.add(eingabeTextField, BorderLayout.PAGE_START);
eingabeTextField.setOpaque(false);
ausgabeTextFeld = new JTextArea(30,30);
c.add(ausgabeTextFeld, BorderLayout.PAGE_END);
ausgabeTextFeld.setOpaque(false);
}
public static void main(String[] args) {
GUI fenster = new GUI();
fenster.setTitle("Für");
fenster.setSize(800, 800);
fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
protected void paintComponent(Graphics g) {
if (hintergrundBild != null) {
g.drawImage(hintergrundBild, 0, 0, getWidth(), getHeight(), null);
}
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == überprüfungsButton){
Thanks whoever took the Time to take a look at it.
Update: I actually can resolve the Problem with Netbeans and the swing-GUI Creator.
However, I am still very curious!
If you could still help me, I would appreciate it.
JFrame does not override paintComponent so Swing will not invoke it.
Adding the #Override annotation above the method will show that the method is not contained in the super class.
The simplest way to implement a background image is to create a subclass of JPanel and override paintComponent there.
Update:
There are many examples on the web where the class JFrame is extended. From a design point is view this is not necessary as you typically do not any new functionality to the frame. For this reason just creating a direct instance & using is better (shown):
public class BackGroundProblem {
public static void main(String[] args) throws IOException {
final Image image = ImageIO.read(new URL("http://news.beloblog.com/ProJo_Blogs/architecturehereandthere/hallstattsumm.jpg"));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
JPanel backgroundPanel = new ImagePanel(image);
backgroundPanel.add(new JButton("Sample Button 1"));
backgroundPanel.add(new JButton("Sample Button 2"));
frame.add(backgroundPanel);
frame.setLocationByPlatform(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class ImagePanel extends JPanel {
private static final long serialVersionUID = 1L;
private Image image;
ImagePanel(Image image) {
this.image = image;
};
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
}

Categories