I'm trying to make a Weather applet for school but I'm having a problem calling a class to a main class. In the end I will want 3 permanent components (Location, Temperature, Precipitation) then in image box I want to do an if statement that pics the appropriate image from the data in components.
Layout idea
Main Class code
// The "Weather" class.
import java.applet.*;
import javax.swing.*;
import java.awt.*;
public class Weather extends Applet
{
//TempBar Intergers
//int x=
//int y=
//int H= //H = Heat
//PercipBar Intergers
//int x2=
//int y2=
//int P = //P = pericipitation
public void init ()
{
GridLayout umm = new GridLayout(0,2);
PercipBar percip = new PercipBar();
getContentPane.addItem (percip());
}
public void paint (Graphics g)
{
}
}
PercipBar Code
import java.awt.*;
import java.applet.*;
public class PercipBar extends Applet
{
int x2 =2;
int y2 =2;
int P =80;//P = percipitation will be declared in main file
public void paint (Graphics g)
{
g.setColor (Color.black);
g.drawRect (x2, y2, 100, 20);//outline of bar
g.setColor (Color.blue);
g.fillRect (x2+1, y2+4, P, 14 ); //indicator bar (+4 puts space beetween outline bar)
}
}
That GUI seems well suited to being contained in a BorderLayout.
location gui would be put in position BorderLayout.PAGE_START
image would be put in BorderLayout.CENTER
temp would be put in BorderLayout.LINE_END
percip (which is spelled precip) would be put in position BorderLayout.PAGE_END
Note that the precipitation bar should net be another applet! It should just be a Component.
In order to be assigned space in the BorderLayout, a custom painted component will need to return a sensible preferred size.
Preferably, rather than custom paint such things, just use a Label to display the text. That way, we don't need to override either the paint method or getPreferredSize. The GUI will takes its hints from the natural size of the label.
Related
I am currently trying to use paintComponent to draw a square in the middle of my JFrame on top of a JPanel. The size of my frame is 600 x 600, but when I try to draw the square with Xcoordinate = 300 and Ycoordinate = 300 the square is not really even close to the middle of my Frame.
Am I doing something wrong? This is for a school project, so any tips would also be appreciated. Thanks in advance!
Write a complete working program that draws a square in the middle of the
frame.
When the user clicks on a square (left click), it then replaces it with 4
smaller
squares drawn in separate quadrants, each of which is a quarter of the size
of the original
square and has random color. If user clicks (right click) on any square, it
is removed/deleted from the frame.
If user remains inactive for 15 seconds ( (i.e., stops clicking), all squares should start moving away
from the center (any speed is fine, overlaps are fine but not preferred). If squares, hit the edges,
they are deleted again. If user presses 'S', the squares stop moving. The frame is cleared when user
presses 'Delete' key three times in quick succession (within 3 seconds) and you start all over again.
Test your program to draw unique patterns.
My frame class:
import javax.swing.*;
import java.awt.*;
public class SquareFrame extends JFrame {
private final int WIDTH = 600, HEIGHT = 600;
private final Dimension frameSize;
private SquarePanel panel;
public SquareFrame(){
panel = new SquarePanel();
frameSize = new Dimension(WIDTH,HEIGHT);
this.setTitle("Sqaures");
this.setSize(frameSize);
this.getContentPane().add(panel);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args){
SquareFrame frame = new SquareFrame();
}
}
My panel class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class SquarePanel extends JPanel implements MouseListener {
public SquarePanel(){
this.setBackground(Color.BLACK);
this.setFocusable(true);
this.setVisible(true);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Square test = new Square();
g.setColor(Color.WHITE);
g.drawRect(test.x,test.y,test.width,test.height);
}
#Override
public void mouseClicked(MouseEvent e) { }
#Override
public void mousePressed(MouseEvent e) { }
#Override
public void mouseReleased(MouseEvent e) { }
#Override
public void mouseEntered(MouseEvent e) { }
#Override
public void mouseExited(MouseEvent e) { }
}
My square class:
import java.awt.*;
public class Square extends Rectangle {
public Square(){
this.height = 100;
this.width = 100;
this.x = 300;
this.y = 200;
}
}
Write a complete working program that draws a square in the middle of the
frame.
Well, I think that is a terrible requirement. The frame contains a title bar and 4 borders. As the frame shrinks in size you won't be able to paint the square on the title bar.
Custom painting is done on the panel that is added to the frame. So I think you should really be trying to center the panel in the bounds of the panel. You need to clarify the actual requirement.
public class Square extends Rectangle {
Why are you extending Rectangle?
If you need, the x, y, width, height information then you just use the getBounds() method of the Rectangle class to get the information.
However, you don't need the x/y values.
If you want to center the rectangle then you need to calculate the x/y values dynamically as you do your custom painting based on the current size of the panel.
What you need to know is the width/height of the rectangle you want to paint, so really you should be creating a Dimension object. Something like:
Dimension d = new Dimension(100, 100);
Then to center the rectangle in the panel you need to know the width of the panel and the width of the rectangle to calculate the location to do the painting of the rectangle:
int x = (getWidth() - d.getWidth()) / 2;
int y = ...
g.drawRect(x, y, d.width, d.height);
I want to learn to use ArrayList together with graphical elements in java.
I have a class that creates squares with a random x and a random y position:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Square extends Canvas {
public int x, y;
Random r = new Random();
public void paint(Graphics g) {
x = r.nextInt(640);
y = r.nextInt(480);
g.setColor(Color.BLACK);
g.fillRect(x, y, 30, 30);
}
}
And i have a class that creates a JFrame and Add square elements to an ArrayList. But i can't figure it out. I think the solution might be simple and technical, i just need a slight push.
import java.util.ArrayList;
import javax.swing.JFrame;
public class Frame {
public int width, height;
public String title;
public JFrame jframe;
ArrayList<Square> squares = new ArrayList<Square>();
public Frame(String title, int width, int height) {
this.width = width;
this.height = height;
this.title = title;
display();
}
public void display() {
jframe = new JFrame();
jframe.setTitle(title);
jframe.setSize(width, height);
jframe.setResizable(false);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
jframe.setLocationRelativeTo(null);
for(int i = 0; i < 20; i++) {
squares.add(new Square());
}
jframe.add(squares);
}
}
Get rid of the Square class and restart.
Do not have it extend Canvas -- you do not want to unnecessarily mix AWT and Swing
And your Square class should be a logical class, not a GUI class, meaning it shouldn't extend any GUI component.
Do not randomize within the painting method.
Give your Square class x and y int fields
Give it a public void draw(Graphics g) method where it draws itself using the Graphics object passed in.
Create another class, one that extends JPanel, and give it an ArrayList<Square>.
Override this JPanel's paintComponent method.
In the override be sure to call the super's method.
In the override, iterate through the array list, calling each Square's draw method.
Place this JPanel into your JFrame.
From what I see you are doing you are adding multiple canvases to the frame which will overlap each other.
Rather create a canvas with a list of Squares(x and y ints) that it draws in its paint and then add one canvas to the frame.
Also I am not sure if JFrame.add() will add the whole canvas and resize it. Rather use a layoutManager to add your components like FlowLayout.
Layout managers
I'm trying to create a program that draws 100 random lines every few seconds. I want to add a text field that allows the user to adjust the amount of time in between each refresh.
However, whenever I try to add any more components to my JFrame, the paintComponent disappears completely. How do I create a window with a text field and a drawing?
This is what I have so far
{
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.Timer;
import java.util.*;
public class Screensaver extends JPanel implements ActionListener {
public static void main (String[] args){ //Create Canvas
JFrame one = new JFrame("ScreenSaver");
one.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Screensaver f = new Screensaver();
one.add(f);
one.setSize(600,600);
one.setVisible(true);
}
public void paintComponent (Graphics a){
super.paintComponent(a);
this.setBackground(Color.WHITE);
a.setColor(Color.BLUE); //Outline
Random rand = new Random();
Timer time = new Timer(4000, this);
time.start();
for(int i =0; i<100; i++){
int x1 =rand.nextInt(600);
int y1 =rand.nextInt(600);
int x2 =rand.nextInt(600);
int y2 =rand.nextInt(600);
a.drawLine(x1, y1, x2, y2);
}
}
public void actionPerformed(ActionEvent e) {
repaint();
}
}
JTextField textField = new JTextField(10);
one.add(textField, BorderLayout.PAGE_START);
one.add(f, BorderLayout.CENTER);
The default layout manager for a frame is the BorderLayout, so you need to add tomponens to a different area of the layout. Read the section from the Swing tutorial on How to Use BorderLayout for more information and examples. The tutorial also has examples of other layout managers and will show you how to better design your class.
The tutorial also has a section on Custom Painting your should read because you also should set the preferred size of your custom painting panel.
I have a class called CharMove,in it are the paint(Graphics g) method, and some custom methods. The class should create a square,then move that square randomly around the screen. However,when I create two instances of this class in my World Class,only one square appears. First the square doesn't move but the new coord.'s are displayed,then after 5 runs the square begins to move randomly. I think the program is getting caught on the Graphics method because only one square is being created,when the CharMove class should be creating another instance of Graphics.I have searched online but can't find a way to create different instances of Graphics.Thanks in advance.
CharMove Class
import java.awt.*;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import java.util.Random;
public class CharMove extends JPanel {
int x = 250;
int y = 250;
public void paint(Graphics g) {
Graphics pane = (Graphics2D) g;
pane.setColor(Color.blue);
pane.fillRect(x, y, 10, 10);
}
public void movement(JFrame frame) {
for (int i=0;i<5;i++) {
try {
TimeUnit.SECONDS.sleep(1);
this.x = Getx(this.x,frame);
this.y = Gety(this.y,frame);
frame.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public int Getx(int a, JFrame frame) {
Random rn = new Random();
int xnum = rn.nextInt(10)-5;
a += xnum;
System.out.println("x:" + a);
return a;
}
public int Gety(int b, JFrame frame){
Random rn = new Random();
int ynum = rn.nextInt(10)-5;
b += ynum;
System.out.println("y:" + b);
return b;
}
}
World Class
import java.awt.*;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import java.util.Random;
public class World {
public static void main(String[] args) {
JFrame game = new JFrame();
game.setTitle("Matrix");
game.setSize(500, 500);;
game.getContentPane().setBackground(Color.white);
game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.setVisible(true);
CharMove char1 = new CharMove();
CharMove char2 = new CharMove();
game.add(char1);
game.add(char2);
char1.movement(game);
char2.movement(game);
}
}
In swing, all of your painting should be down in paintComponent(Graphics g) (rename your method)
To do animation, you should use a Swing Timer (w/ an ActionListener) to update the positions of your animated items. Once that's done, the timer should call repaint();
public void actionPerformed(ActionEvent ae) {
this.x = Getx(this.x,frame);
this.y = Gety(this.y,frame);
frame.repaint();
}
However,when I create two instances of this class in my World Class,only one square appears.
The default layout manager for a JFrame is a BorderLayout.
game.add(char1);
game.add(char2);
When you add components without specifying a constraint then both components are added to the CENTER. However, only one component can be added to the CENTER so only the last one added is displayed.
Try:
game.add(char1, BorderLayout.PAGE_START);
game.add(char2, BorderLayout.PAGE_END);
However when you do this the componens won't be displayed because they have a (0, 0) preferredSize. So you will also need to override the getPreferredSize() method of your CharMove class.
#Override
public Dimension getPreferredSize()
{
return new Dimension(300, 200);
}
Also, custom painting should be done in the paintComponent(...) method and you need to invoke super.paintComponent(...) at the start to clear the background.
The repaint() method in your movement() method should be on the panel, not the frame, since you are changing properties of the panel.
Each CharMove is essentially a JPanel which draws a single square of size 10 somewhere on itself when it is painted. You are adding two CharMove panels to the game JFrame (which in fact adds them to the default content pane, which has a subclassed BorderLayout). As you are not providing a layout constraints object, in fact both panels are being added to the BorderLayout.CENTER of the content pane, and the second is completely covering the first.
To correct this you should modify CharMove so that it paints all of the squares (eg by maintaining an array or some sort of collection of squares, and painting all of them in the paint method) and just add that one panel to the JFrame.
Apart from this issue, while you are animating the squares in the movement method you are blocking the Event Dispatch Thread, meaning that during the animation you won't be able to move any other windows or respond to any mouse clicks or other inputs. Take ControlAltDel's advice about using the Swing Timer for animation to correct this problem.
Before I start know this: I am extremely new to Java and programming. How would I properly draw the "grass.jpg" to the screen?
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import java.util.Random;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Game extends Canvas {
private static int Height = 300, Width = 600; //25x50
private Random generator = new Random();
private String[][] TerrainList = new String[12][12];
public void GameSetup() {
JFrame container = new JFrame("CARSSémon");
// get hold the content of the frame and set up the resolution of the game
JPanel panel = (JPanel) container.getContentPane();
panel.setPreferredSize(new Dimension(Width,Height));
//panel.setLayout(null);
//setBounds(0,0,800,600);
//panel.add(this);
// finally make the window visible
container.pack();
container.setResizable(false);
container.setVisible(true);
container.setLocationRelativeTo(null); //Centers screen
container.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
PrepareTerrain();
PreparePlayer();
}
public void PrepareTerrain() {
for (int a=0; a<=11; a++){
for (int b=0; b<=11; b++){
TerrainList[a][b]="grass"; //Sets defult terrain of grass
}
}
int BushLocationx = generator.nextInt(12);
int BushLocationy = generator.nextInt(12);
BushCheck(BushLocationx,BushLocationy); //Checks to see if it can make bushs at the location
}
#Override
public void paint(Graphics g) {
super.paint(g);
// Draw an Image object
Image grass = new ImageIcon("grass.jpg").getImage();
Image bushes = Toolkit.getDefaultToolkit().getImage("bushes.jpg");
g.setColor(Color.BLACK);
g.drawImage(grass, 0, 0, null);
g.drawImage(grass, 0, 50, null);
g.drawImage(grass, 50, 0, null);
g.drawImage(grass, 200, 200, null);
}
public void DrawTerrain() {
for (int r=0; r<=11; r++){
for (int c=0; c<=11; c++){
}
}
}
private void BushCheck(int x, int y){
}
public void PreparePlayer() {
}
public static void main(String[] args) {
Game G =new Game();
G.GameSetup();
}
}
Now I obviously realize that this program has basically nothing implemented but I figured what's the point of starting to implement things if I could never even display any pictures?
My problem is that I can not figure out why the .jpgs aren't being displayed. Shouldn't the paint(); method be called when the JFrame and JPanel are created? The code is pretty messy, but I figured it would be best to include all of it.
In case this matters, this is eventually going to be a Pokemon like game, where the the run window is made up of many 16x16 pixel squares, that a player could move around on. Before starting any of that I wanted to experiment with outputting some images at random places. I've been reading similar questions and looking at examples, I just read a section of Java text on graphics but could only find information on loading images, not displaying through paint. If anyone could help by even pointing me in the right way, it would be greatly appreciated.
(I realize that I will most likely completely need to restart, and are going about things completely wrong but anything you could do would help.)
I just read a huge section of Java text on graphics but could only find information on loading images, not displaying through paint.
For a Pokemon style game, I don't think using JLabel for each icon/image would provide any benefit. Instead:
Create a BufferedImage of the desired size of the game area.
Get Image instances for each of the smaller icons that you might need to paint (characters, elements in the terrain etc.) & paint them to the Graphics instance of the main BufferedImage1.
To display the main 'game' image there are two good options:
Add the main image to a JLabel and add it to a JPanel, call label.repaint().
Paint the game image directly to the Graphics instance supplied to the paintComponent() method of a JComponent.
For the last part, I would recommend option 1.
1. E.G.
public void gameRenderLoop() {
Graphics2D g2 = gameImage.createGraphics();
g2.drawImage(playerImage, 22, 35, this);
...
g2.dispose();
}
Examples of dealing with BufferedImage & Graphics
Very simple example of painting an image.
More complicated example dealing with text & clips.
A slightly different tack (extending a JLabel) showing image painting with transparency.
Don't reinvent the wheel. Use a JLabel with an ImageIcon to paint your image for you. Just add it to a JPanel and you're all set.