When I run the application the whole frame is painted black.
How can I make it so that it starts out clear then it gets painted when I press the button?
package card;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BdayCard extends JFrame {
JButton button1, button2;
JPanel panel;
BdayCard()
{
panel = new JPanel();
button1 = new JButton();
button1.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
});
panel.add(button1);
this.add(panel);
this.setTitle("It's Your Birthday!");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 450);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void paint(Graphics g){
g.fillRect(0, 0, 600, 450);
}
public static void main(String[] args){
new BdayCard();
}
}
your problem with your blackscreen is because you paint at:
g.fillRect(0, 0, 600, 450);
you are using the default colour which is black
I tried your code and used this:
g.setColor(Color.WHITE);
this clears your screen and then use a boolean and set it true when your button is pressed:
public void actionPerformed(ActionEvent e)
{
button=true;
repaint();
}
then finally use:
if(button){/*do stuff here*/}
in the paint method
Related
I am starting with Java and want to make a simple pong game to get into the ways of displaying stuff in java. I have created 2 classes that both extend JPanel and call the repaint() function every 16.6 milliseconds. I added both to a JPanel which I added to the frame, but only the component I added first displays.
I've tried to revalidate() after repaint() in both classes and made sure that the Timer actually works and that it's actionPerformed() method is actually called.
This is the main method:
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Pong");
//...
JPanel mainPanel = new JPanel();
mainPanel.add(new Player());
mainPanel.add(new Ball(frameWidth/2, frameHeight/2 -40));
frame.add(mainPanel);
}
}
This is the important code for the classes (It's basically the same for both of them):
public class Player extends JPanel {
public Player(){
setPreferredSize(new Dimension(Main.frameWidth, Main.frameHeight));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
public void actionPerformed(ActionEvent e){
update();
repaint();
}
}).start();
}
//...
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
(Of coure I left things like #Override or unneseccary functions out to shorten the code)
This code only paints the Player, altough I want it to display all the components of mainPanel.
This is an example that you can (hopefully) run. I had to split it up into 3 files, since I suck at anonymus classes:
Main.java
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 800);
JPanel mainPanel = new JPanel();
mainPanel.add(new Player());
mainPanel.add(new Ball());
frame.add(mainPanel);
frame.setVisible(true);
}
}
///////
Player.java
//////
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Player extends JPanel{
private int x = 20, y = 300, width = 20, height = 100;
public Player(){
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
//////
Ball.java
//////
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Ball extends JPanel{
private int x = 20, y = 300, width = 20, height = 100;
public Ball(){
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
In method paintComponent() of class Player, you paint the exact same Rectangle each time. In order to achieve animation, each time you paint the rectangle you need to change either its size or location or both. What do you expect the Player to do? Should it move up and down along the left edge of the window? Have you seen the lesson entitled How to Use Swing Timers which is part of Oracle's Java Tutorial?
EDIT
I see now that Player hides Ball, because of the default layout manager of JPanel. The below code is essentially the code you posted but I set GridLayout as the layout manager for mainPanel. Also, a java source code file may contain more than one class but exactly one class must be public. Hence in the below code only class Main is public.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel(new GridLayout(0, 2));
mainPanel.add(new Player());
mainPanel.add(new Ball());
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class Player extends JPanel {
public Player() {
setBorder(BorderFactory.createLineBorder(Color.RED, 2, false));
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000 / 60, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(20, 100, 20, 100);
}
}
class Ball extends JPanel {
public Ball() {
setBorder(BorderFactory.createLineBorder(Color.CYAN, 2, false));
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000 / 60, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}).start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(300, 300, 10, 10);
}
}
And here is a screen capture of the GUI...
I just realized that if I extend my window manually, the second JPanel shows up under the one responsible for the Player! This means that I'll need to set the Panels position somehow, right?
#Abra
I am trying to make a GUI in Java. I have a JFrame and I create a JPanel in it. I add them manually when I click on "Design".
When a click with the mouse on the Panel then an icon should appear where I clicked. It should appear as many times as I click on the Panel. I try to use the answer given here but it does not work as the Panel there is not added manually:
Add image on mouse click? Java applet
I am using the same code and I try to adjust it to the event MouseClicked for the jPanel1 which I have added manually:
private Point drawPoint;
Graphics g;
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
System.out.println("I can click.");
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage("Icons/p.png");
drawPoint = new Point(evt.getPoint());
repaint();
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (drawPoint != null) {
g2d.drawImage(image, drawPoint.x, drawPoint.y, this);
}
g2d.dispose();
}
It says that it cannot find symbol for:super.paintComponent(g)
If I use the given code in the example in a newly created class, it works fine without the fact that I want the image to appear again and again instead of removing it each time and appearing only once.
Does anyone know how to fix it?
EDIT
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.imageio.ImageIO;
import javax.swing.*;
public class editorPTnets{
private JButton b1;
private JButton b2;
private JButton b3;
private JButton b4;
public editorPTnets(){
JFrame f = new JFrame("P/T nets");
f.setSize(800, 500);
f.setLayout(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setBackground(Color.gray);
f.add(new TestPane());
f.setLocationRelativeTo(null);
JPanel p = new JPanel();
p.setBounds(5, 50, 760, 400);
p.setBackground(Color.white);
f.add(p);
p.setVisible(true);
b1 = new JButton("");
b1.setBounds(5, 5, 40, 40);
b1.setVisible(true);
b1.setIcon(new
ImageIcon("C:\\Users\\Toshiba\\Desktop\\Java\\Icons\\new.png"));
f.add(b1);
b2 = new JButton("");
b2.setBounds(50, 5, 40, 40);
b2.setIcon(new
ImageIcon("C:\\Users\\Toshiba\\Desktop\\Java\\Icons\\open.png"));
b2.setVisible(true);
f.add(b2);
f.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new editorPTnets();
System.out.println("Hello, world");
public class TestPane extends JPanel {
Image image;
private Point drawPoint;
public TestPane() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
image =
toolkit.getImage("C:\\Users\\Toshiba\\Desktop\\Java\\Icons\\p.png");
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
drawPoint = new Point(e.getPoint());
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 500);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (drawPoint != null) {
g2d.drawImage(image, drawPoint.x, drawPoint.y, this);
}
g2d.dispose();
}
}
}
EDIT 2 FIXED
public mainFrame() {
JFrame f = new JFrame("Editor for graphs");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
f.getContentPane().setBackground(Color.blue);
f.setResizable(false);
f.setLayout(new BorderLayout());
f.add(new Panel1(), BorderLayout.SOUTH);
f.setLocationRelativeTo(null);
f.setVisible(true);
This helped me fix the problem.
I am new in java and i wanted to work on a simple paint program using java swing.
my simple paint program should draw a shape like triangle, circle and square whenever i clicked on buttons.
i managed to draw these shapes and print it without buttons but i can not do it using ActionListener?
As you see i have a single button at the moment, i want to draw the oval whenever this button is clicked.
This is the code that i am working on it so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PaintProject extends JComponent implements ActionListener{
public static void main(String[] args) {
JFrame frame=new JFrame("NEW PAINT PROGRAME!");
JButton button1=new JButton("ADD");
PaintProject paint=new PaintProject();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(paint);
frame.add(button1);
frame.pack();
frame.setVisible(true);
}
#Override
public Dimension getPreferredSize(){
return new Dimension(500,500);
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0,0, 100, 100);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Could you please take following steps:
Step 1:
Insert button1.addActionListener(paint); just after PaintProject paint=new PaintProject(); in the main method of PaintProject.java
Step 2:
Remove the method named protected void paintComponent(Graphics g). Instead create following method:
private void drawOval(){
Graphics g = this.getGraphics();
g.setColor(Color.red);
g.fillOval(0,0, 100, 100);
}
Step 3:
Call the above method as follows:
#Override
public void actionPerformed(ActionEvent e) {
drawOval();
}
EDIT:
Following example demonstrates how to draw two shapes when respective buttons are clicked:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class PaintProject extends JComponent implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("NEW PAINT PROGRAME!");
JButton ovalButton = new JButton("Oval");
ovalButton.setActionCommand("Oval");
JButton rectangleButton = new JButton("Rectangle");
rectangleButton.setActionCommand("Rectangle");
PaintProject paint = new PaintProject();
ovalButton.addActionListener(paint);
rectangleButton.addActionListener(paint);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(paint);
frame.add(ovalButton);
frame.add(rectangleButton);
frame.pack();
frame.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
private void drawOval() {
Graphics g = this.getGraphics();
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
private void drawRectangle() {
Graphics g = this.getGraphics();
g.setColor(Color.green);
g.fillRect(150, 150, 100, 100);
}
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Oval")) {
drawOval();
} else if (command.equals("Rectangle")) {
drawRectangle();
}
}
}
when handset button pressed I want to green button color change red.After a certain time,again
I want to green button.I dont use timer class.Please help me.
For example my code
if (e.getSource() == handsetbutton) {
text1.setBackground(Color.RED);
// What l have to add here?
}
Run this example. I use a Swing Timer and set the delay to 4 seconds. When the button is pressed, it fires an action to change the color and start the timer. When the 4 seconds is up, the color changes back
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class GreenToRed extends JPanel {
private Color color = Color.RED; // global color object
static JButton button = new JButton("Change");
private Timer timer = null;
public GreenToRed(){
timer = new Timer(4000, new ActionListener(){ // Timer 4 seconds
public void actionPerformed(ActionEvent e) {
color = Color.RED; // after 4 seconds change back to red
repaint();
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
color = Color.GREEN; // change to green
repaint(); // repaint
timer.start(); // start timer
}
});
}
private static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new GreenToRed(), BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillOval(getWidth() / 2 - 50, getHeight() / 2 - 50, 100, 100);
}
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
So I have this problem with my code. Whenever I load up the game there is a red square in the center of the screen, and I have not programmed it to do so. I have tried to find the error for hours but I just can't see it. I think it has to do with the panels or something. The second thing is that when I press the button to draw the grid, only a small line appears. It is programmed to be much bigger than what it is, and it is not in the right location either. Below is all my code, and any help is greatly appreciated!!
package com.theDevCorner;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
public class Game extends JPanel implements ActionListener {
public static JButton grid = new JButton("Show Grid");
public static JPanel drawArea = new JPanel();
public static JMenuBar menu = new JMenuBar();
public static JPanel notDrawn = new JPanel();
public static boolean gridPressed = false;
public Game() {
grid.addActionListener(this);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(new Dimension(
Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit
.getDefaultToolkit().getScreenSize().height));
frame.setTitle("Game");
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
menu.setSize(new Dimension(1600, 20));
menu.setLocation(0, 0);
notDrawn.setBackground(new Color(255, 0, 50));
notDrawn.setSize(100, 900);
notDrawn.add(grid);
notDrawn.setLayout(null);
grid.setSize(new Dimension(100, 25));
grid.setLocation(0, 25);
drawArea.setSize(new Dimension((Toolkit.getDefaultToolkit()
.getScreenSize().width), Toolkit.getDefaultToolkit()
.getScreenSize().height));
drawArea.setLocation(100, 0);
drawArea.setBackground(Color.black);
drawArea.add(menu);
drawArea.add(game);
frame.add(drawArea);
frame.add(notDrawn);
}
public void paint(Graphics g) {
Game game = new Game();
if (gridPressed) {
Game.drawGrid(0, 0, g);
}
g.dispose();
repaint();
}
public static void drawGrid(int x, int y, Graphics g) {
g.setColor(Color.white);
g.drawLine(x, y, 50, 300);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == grid && gridPressed == true) {
gridPressed = false;
System.out.println("Unpressed");
}
if (e.getSource() == grid) {
gridPressed = true;
System.out.println("Pressed");
}
}
}
There are a number of problems...
The red "square" you are seeing is actually your grid button. The reason it's red is because of your paint method.
Graphics is a shared resource, that is, each component that is painted on the screen shares the same Graphics context. Because you chose to dispose of the context and because you've failed to honor the paint chain, you've basically screwed it up.
Don't EVER dispose of a Graphics context you didn't create. It will prevent anything from being painted to it again. Always call super.paintXxx. The paint chain is complex and does a lot of very important work. If you're going to ignore it, be ready to have to re-implement it.
null layouts are vary rarely the right choice, especially when you're laying out components. You need to separate your components from your custom painting, otherwise the components will appear above the custom painting.
This frame.setSize(new Dimension(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height)) is not the way to maximize a window. This does not take into consideration the possibility of things like tasks bars. Instead use Frame#setExtendedState
As Andreas has already commented, you actionPerformed logic is wrong. You should be using an if-statement or simply flipping the boolean logic...
Updated with simple example
ps- static is not your friend here...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JPanel implements ActionListener {
private GridPane gridPane;
public Game() {
setLayout(new BorderLayout());
SideBarPane sideBar = new SideBarPane();
sideBar.addActionListener(this);
add(sideBar, BorderLayout.WEST);
gridPane = new GridPane();
add(gridPane);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setTitle("Game");
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(game);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("grid")) {
gridPane.setGridOn(!gridPane.isGridOn());
}
}
public class GridPane extends JPanel {
private boolean gridOn = false;
public GridPane() {
setBackground(Color.BLACK);
}
public boolean isGridOn() {
return gridOn;
}
public void setGridOn(boolean value) {
if (value != gridOn) {
this.gridOn = value;
repaint();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (gridOn) {
g.setColor(Color.white);
g.drawLine(0, 0, 50, 300);
}
}
}
public class SideBarPane extends JPanel {
public JButton grid;
public SideBarPane() {
setBackground(new Color(255, 0, 50));
setLayout(new GridBagLayout());
grid = new JButton("Show Grid");
grid.setActionCommand("grid");
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
gbc.weighty = 1;
add(grid, gbc);
}
public void addActionListener(ActionListener listener) {
grid.addActionListener(listener);
}
}
}