I'm new with Java and I'm trying to a class that extends JPanel. I have a updateView() method that is suppose to draw rounded rectangles with text in the middle inside the JPanel. Also, I would need to stock the textfield and the rounded rectangle in a LinkedHashMap. I already got a var for this, I just don't know witch type of var I need to use.
I'have been searching the solution for a while, and all the answers I found are either to complicated for me to understand or just doesn't apply to my case.
I know that it's almost nothing, but here is what I got so far...
package game;
import javax.swing.JPanel;
public class GameNumView extends JPanel
{
private Map<Integer,Integer> backgroundText = new LinkedHashMap<"My rounded rectangle","My textfield">();
public GameNumView()
{
}
public void UpdateView(String[] pNumbers)
{
//Create the background
//Create the text
}
}
I'll give you the right path. It's up to you to adapt it to your existing code.
The idea is to use the Graphics object with the paintComponent method of an extended class of JPanel.
Here is the code, it is clear enough I think but if you have any question, do not hesitate.
The MyFrame class :
public class MyFrame extends JFrame {
public MyFrame(){
this.setTitle("Hello");
this.setSize(200, 200);
this.setLocationRelativeTo(null);
MyPanel pan = new MyPanel();
pan.setBackground(Color.ORANGE);
this.setContentPane(pan);
this.setVisible(true);
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
}
}
And here is the MyPanel class :
public class MyPanel extends JPanel{
#Override
public void paintComponent(Graphics g) {
g.setColor(Color.black);
g.drawRoundRect(10, 10, this.getWidth()-20, this.getHeight()-20, 15, 15);
g.setColor(Color.black);
g.drawString("Hello", 75, 75);
}
}
And here is a picture of what you should have :
Related
public void display() {
pan.repaint();
fen.add(pan);
fen.addKeyListener(this);
fen.setResizable(false);
fen.setTitle("Le Jeu 2D");
img.setText("Coucou");
pan.add(img);
pan.repaint();
pan.setBackground(Color.yellow);
fen.setVisible(true);
fen.setSize(480, 272);
pan.repaint();
fen.revalidate();
}
public void paintComponent(Graphics g) {
System.out.println("zzz");
pan.paint(g);
g.setColor(Color.red);
g.drawRect(10, 10, 10, 10);
}
It doesn't draw anything. Why? I have defined the paint component method, so I don't understand why.
Edit: I edited my code, please take a look
You don't create an instance of your Game class and don't add it to the JFrame.
Here is the Game panel which you are painting on:
Game.java
public class Game extends JPanel {
#Override
public final void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.drawRect(10, 10, 10, 10);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(300, 300);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(300, 300);
}
}
You then need to create an instance of this Game panel and add it to your JFrame:
GameFrame.java
public class GameFrame extends JFrame {
public GameFrame() {
setLocationRelativeTo(null);
setResizable(false);
setTitle("2D Game");
Game game = new Game();
setContentPane(game);
pack();
setVisible(true);
}
}
Then when you create an instance of the JFrame:
Example.java
public class Example {
public static void main(String[] args) {
new GameFrame();
}
}
The panel will be added, and painted:
You never create an instance of the Game class and you never add the Game class to the frame. Even if you did create an instance the size would still be (0, 0) so there would be nothing to paint.
Basically the whole structure of your code is wrong.
I suggest you start over and start with the demo code found in the Swing tutorial on Custom Painting.
The basic structure of your code seems weird.
You could instantiate a JFrame in your main control class, ie. it should be GAME class in this case. Then you can create a new JPanel class and add its object into the JPanel object. Within the JPanel class, you can create all the elements you need and set corresponding parameters. You could also add the event listener in an inner class or a separate class.
This question already has an answer here:
Java GUI repaint() problem?
(1 answer)
Closed 8 years ago.
I am a complete beginner at Java coding and I have never worked with GUI before. Here's what I am trying to do. I have main class "Frame" and two classes: "Circle" and "Square". How do I add Circle and Square to Frame that they'll appear on the frame?
Sorry for this easy question but I need your help on this.
Thanks in advance!
public class Frame extends JFrame{
public static void main(String[] args) {
Frame f = new Frame();
Circle circle = new Circle();
Square square = new Square();
f.add(circle);
f.add(square);
}
public Frame(){
setTitle("Frame");
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
public class Circle extends JFrame{
public Circle(){
}
public void paint(Graphics g){
g.setColor(Color.GREEN);
g.drawOval(300, 300, 200, 200);
}
}
public class Square extends JFrame{
public Square(){
}
public void paint(Graphics g){
g.setColor(Color.GREEN);
g.drawRect(300, 300, 500, 500);
}
}
First off all you cannot add a JFrame to a JFrame because you would be adding a window to a window. What you could do though is make circle and square extend JPanel. This way you would be able to add them to your JFrame without any problem and they will do what they have to do. Also my JDK tells me that Circle and Square should have their own file. And also depending on the order you add square and circle in to the JFrame, you'll only see one of them because the second one is painted over the first one. Ok so after this your code would transform into:
File 1 Frame:
public class Frame extends JFrame{
public static void main(String[] args) {
Frame f = new Frame();
Circle circle = new Circle();
Square square = new Square();
f.add(circle);
f.add(square);
}
public Frame(){
setTitle("Frame");
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
File 2 Circle:
public class Circle extends JPanel{
public Circle(){
}
public void paint(Graphics g){
g.setColor(Color.GREEN);
g.drawOval(300, 300, 200, 200);
}
}
File 3 Square:
public class Square extends JPanel{
public Square(){
}
public void paint(Graphics g){
g.setColor(Color.GREEN);
g.drawRect(300, 300, 500, 500);
}
}
Hope this help you and that you understand why this works. If you do not feel free to ask for more clarification.
P.S. Welcome to Java GUI programming ;)
I'm doing all Graphics stuffs such as g.drawLine() etc. inside class MyCanvas.java
public class MyCanvas extends JComponent{
public void paint(Graphics g){...}
}
And my Main.java class is
class Main{
public static void main(String[] args){
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 1000, 350);
window.getContentPane().setLayout(new FlowLayout());
MyCanvas mc = new MyCanvas();
JScrollPane jsp = new JScrollPane(mc);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
window.getContentPane().add(jsp);
window.getContentPane().setBackground(Color.WHITE);
window.setVisible(true);
}
}
However, JFrame is only showing white plain background, It isn't showing any Graphics stuff from paint(Graphics g).
Note that, If I remove JScrollPane from above Main.java, then it shows everything perfectly.
class Main{
public static void main(String[] args){
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 1000, 350);
window.getContentPane().add(new MyCanvas());
window.getContentPane().setBackground(Color.WHITE);
window.setVisible(true);
}
}
Where my logic is going wrong? Is there any problem while adding JScrollPane ? Please help. Thanks.
class MyCanvas extends JComponent{
public void paint(Graphics g){...}
}
Should be:
class MyCanvas extends JComponent{
#Override
public void paintComponent(Graphics g){...}
}
By using paintComponent we respect the painting chain. Also be sure to add super.paintComponent(g); as the first statement in the overridden method, to assure that the BG color and borders etc. are painted.
I am new to Java....I studied that we can add two things on frame... I added button and in response by clicking on button I want rectangle as output....but i don't understand that..Why i am not getting output.....
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class customizedgui5 implements ActionListener {
JButton button;
JFrame frame;
public static void main(String[] args) {
customizedgui5 hi = new customizedgui5();
hi.go();
}
public void go() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("click me");
button.addActionListener(this);
myclass a = new myclass();
frame.getContentPane().add(button, BorderLayout.CENTER);
frame.getContentPane().add(a, BorderLayout.SOUTH);
frame.setSize(100, 100);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
frame.revalidate();
}
}
class myclass extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.orange);
g.fillRect(20, 50, 100, 100);
}
}
I would start by taking a look at Performing Custom Painting.
The main problem in your code is you are getting NullPointerException when you click the button because the reference of frame is null.
It is null because you've shadowed it in the constructor (basically, declared another variable of the same name within the constructor)...
// I'm null..
JFrame frame;
public void go() {
// Not the same as frame above...
JFrame frame = new JFrame();
You are also going to not see any changes because of a number of reasons...
The myclass panel has no size. With BorderLayout, this won't be "too" much of a problem, but...
You've drawing outside of the visible range of the panel. The rectangle you are painting won't appear because it is being painted outside of the width and height of the panel.
The rectangle will appear before you press the button as paintComponent will be called to update the state of the panel once it's made visible on the screen...
The first thing you need to is provide some kind of size hints to the BorderLayout. Try adding...
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 150);
}
To myclass.
You also don't need to repaint the frame, what you really want to repaint is the instance of myclass. Try updating customizedgui5 so that a becomes a instance variable (like frame...
//...
myclass a;
//...
public void go() {
//...
a = new myclass();
//...
}
public void actionPerformed(ActionEvent event) {
a.repaint();
}
Now, the rectangle will still be shown the moment that the panel is made visible on the screen. Sure you could try setting it invisible, but this will affect the layout of the frame, hiding your component to start with, so, instead, we need some kind of flag we can trip so we know when to paint the rectangle. This is easily achieved by using a simple boolean variable, for example...
class myclass extends JPanel {
private boolean paintRect;
public void setPaintRect(boolean paint) {
paintRect = paint;
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 150);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (paintRect) {
g.setColor(Color.orange);
g.fillRect(20, 50, 100, 100);
}
}
}
Then in you actionPerformed method, you just need to set the flag...
public void actionPerformed(ActionEvent event) {
a.setPaintRect(true);
}
You may also want to take a read through Code Conventions for the Java Programming Language. It will make it easier for people to read your code...
When you click on your button, you're calling the method actionPerformed(ActionEvent event)
Take a look at what you did there. Currently, you repaint and re-validate the frame. If you want to add a rectangle to your frame, you need to do so by adding a new component to the frame that will draw the rectangle.
You could add another instance of your myclass JPanel which paints a rectangle like so:
public void actionPerformed(ActionEvent event) {
frame.getContentPane().add(new myclass(), BorderLayout.NORTH);
frame.repaint();
}
This would add your custom rectangle-drawing panel to the North section of your BorderLayout. If you want to add the rectangle "on top of" your button, you should embed your button within a JPanel, then add the rectangle-drawing panel to that instead of your main JFrame
I need to pass a JPanel extending class to the main class.
Here is what I have so far:
Main class
import java.awt.Color;
import javax.swing.*;
public class main {
private gamePanel gamepanel = new gamePanel();
public JPanel createContentPane(){
// We create a bottom JPanel to place everything on.
JPanel totalGUI = new JPanel();
//We set the Layout Manager to null so we can manually place
// the Panels.
totalGUI.setLayout(null);
//Now we create a new panel and add it to the bottom JPanel.
totalGUI.add(gamepanel);
totalGUI.setOpaque(true);
return totalGUI;
}
private static void createAndShowGUI(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] There's a JPanel in here! [=]");
//Create and set up the content pane.
main demo = new main();
frame.setContentPane(demo.createContentPane());
//The other bits and pieces that make your program a bit more stable.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,500);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a jog for the event-dispatching thread:
//creating and showing this application's GUI.
System.out.println(gamepanel);
SwingUtilities.invokeLater(new Runnable() {
public void run(){
createAndShowGUI();
}
});
}
}
The gamePanel class
public class gamePanel extends JPanel implements Commons {
private Dimension d;
private ArrayList snowmens;
private coreFunctions functions = new coreFunctions();
private int snowmenX = 150;
private int snowmenY = 5;
private final String snowmenpix = "snowman.png";
private JPanel background;
public gamePanel() {
add(new JLabel("TEST"));
setFocusable(true);
setDoubleBuffered(true);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 700, 700);
}
}
I can't figure out why the blue background and the label is not being shown...
EDIT:
Here are more details:
Ok so I am trying to make a little 2D game. For that I need to create some snowmen on the gamePanel class and display it via the main class. To start it off, the createContentPane creates a background panel, the root panel if you want. The createandshowgui creates a JFrame.
The gamepanel class is in fact a JPanel which has 1 panel as of now, which is the background panel. For now, I only want it to have a blue background.
I tried putting it like this because I saw some examples and they were pretty similar to what I have, but for some reason, I can't get it to work....
Thank you,
Ara
You should use LayoutManager instead of setLayout(null); and if only one component is being added no need for it either (that component will stretch to fill unless others are added)
see here for tutorial on LayoutManagers:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html
If all you are trying to do is have a blue background (on which you can add components) then simply override paintComponent() of your gamePanel and paint the background blue:
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
}
then you can add your JLabel as if it was a normal Panel as the background is now being painted blue and not set by/as a component.
If you have an image look into g.drawImage(Image image,int x,int y,ImageObserver iO)
EDIT
DROP THE CALL TO:
setLayout(null);
and it will work