Java GUI: How to add several classes to "Frame" class [duplicate] - java

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 ;)

Related

I can't tell why JLabel is not showing

I have a main class that creates the instance of the JFrame and JPanel and I set the JPanel as public so I can access it from another class to add more things into it (I don't know if this is how it works, that's just my logic).
public class Main {
private JFrame obj;
public Gameplay gamePlay;
public Main() {
obj = new JFrame();
gamePlay = new Gameplay();
}
public void execute() {
//properties of the jframe
obj.setBounds(10, 10, 700, 600);
obj.setTitle("Brick breaker");
obj.setResizable(false);
obj.setVisible(true);
obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//add the jpanel inside the jframe
obj.add(gamePlay);
}
public static void main(String[] args) {
Main main = new Main();
main.execute();
}
}
Then, I have another class named Gameplay which extends JPanel. One of the methods inside has to draw things inside the JPanel and add a label when a condition is true.
Note that the commented region at the end where "GAME OVER" is drawn by with graphics g it does work correctly, but I want to put a label instead because I want to use custom font. The label never shows up. All the other things that the method pait() has to paint also work fine.
public void paint(Graphics g) {
//background
g.setColor(Color.black);
g.fillRect(1, 1, 692, 592);
//more code of drawing things
//...
if(ballposY > 570) {
play = false;
ballXdir = 0;
ballYdir = 0;
lblGameOver = new JLabel("GAME OVER");
lblGameOver.setForeground(Color.green);
lblGameOver.setFont(pixels);//custom font
Main main = new Main();
main.gamePlay.add(lblGameOver);
//g.setColor(Color.green);
//g.setFont(new Font("serif", Font.BOLD, 30));
//g.drawString("GAME OVER", 250, 300);
}
g.dispose();
}
You are need to add this line to your code:
lblGameOver.setOpaque(true);
It's will add your BackGroud and make that methode works well
lblGameOver.setForeground(Color.green);

Why can't I draw in a JPanel?

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.

How to draw a roundedRectangle with text inside a class extending JPanel

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 :

Not able to see the graphics stuff inside paint() method

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.

JPanel setBackground(Color.BLACK) does nothing

I have the folowing custom JPanel and I have aded it to my frame using Netbeans GUI builder but the background won't change! I can see the circle, drawing with g.fillOval(). What's wrong?
public class Board extends JPanel{
private Player player;
public Board(){
setOpaque(false);
setBackground(Color.BLACK);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(player.getxCenter(), player.getyCenter(), player.getRadius(), player.getRadius());
}
public void updatePlayer(Player player){
this.player=player;
}
}
If your panel is 'not opaque' (transparent) you wont see your background color.
You have to call the super.paintComponent(); as well, to allow the Java API draw the original background. The super refers to the original JPanel code.
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(player.getxCenter(), player.getyCenter(), player.getRadius(), player.getRadius());
}
You need to create a new Jpanel object in the Board constructor.
for example
public Board(){
JPanel pane = new JPanel();
pane.setBackground(Color.ORANGE);// sets the background to orange
}
setOpaque(false);
CHANGED to
setOpaque(true);
I just tried a bare-bones implementation and it just works:
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello");
frame.setPreferredSize(new Dimension(200, 200));
frame.add(new Board());
frame.pack();
frame.setVisible(true);
}
}
public class Board extends JPanel {
private Player player = new Player();
public Board(){
setBackground(Color.BLACK);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(player.getCenter().x, player.getCenter().y,
player.getRadius(), player.getRadius());
}
}
public class Player {
private Point center = new Point(50, 50);
public Point getCenter() {
return center;
}
private int radius = 10;
public int getRadius() {
return radius;
}
}
In order to completely set the background to a given color :
1) set first the background color
2) call method "Clear(0,0,this.getWidth(),this.getHeight())" (width and height of the component paint area)
I think it is the basic procedure to set the background...
I've had the same problem.
Another usefull hint : if you want to draw BUT NOT in a specific zone (something like a mask or a "hole"), call the setClip() method of the graphics with the "hole" shape (any shape) and then call the Clear() method (background should previously be set to the "hole" color).
You can make more complicated clip zones by calling method clip() (any times you want) AFTER calling method setClip() to have intersections of clipping shapes.
I didn't find any method for unions or inversions of clip zones, only intersections, too bad...
Hope it helps

Categories