Java ScrollPane on Buffered Image - java

So I have 4 classes, in my paint program and I am trying to add scrollbars to the canvas so that I can scroll around, When I make my buffered Image it is set to the size of the desktop, but the JFrame is only I think 700 or so pixels so as you expand or resize you are still on canvas. But I cant figure out how to add a JScrollPane to the buffered image so I can scroll around.
//MAIN//
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Main
{
public static int choice;
public static void main(String[] args)
{
Board.getInstance();
}
}
//FRAME//
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
*
* #author Calvin Moss
*/
public class Board extends JFrame implements ActionListener
{
public static Board inst;
Board()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.add(Menu.getInstance(), BorderLayout.NORTH);
getContentPane().add(Drawing.getInstance(), BorderLayout.CENTER);
Drawing.getInstance().add(new JScrollPane());
setSize(1200, 800);
setBackground(Color.WHITE);
setVisible(true);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu help = new JMenu("Help");
menuBar.add(help);
JMenuItem about = new JMenuItem("About");
help.add(about);
about.addActionListener(this);
}
public static Board getInstance()
{
if(inst == null)
inst = new Board();
return inst;
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("About"))
{
JFrame about = new JFrame("About");
about.setSize(300, 300);
JButton picture = new JButton(new ImageIcon("C:/Users/TehRobot/Desktop/Logo.png"));
about.add(picture);
about.setVisible(true);
}
}
}
//MENUPANEL//
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.TitledBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.image.BufferedImage;
/**
*
* #author Calvin Moss
*/
public class Menu extends JPanel implements MouseListener, ActionListener{
public static Color bgColor = null;
public static int stroke = 0;
public static Menu instance;
private JButton clear;
private JButton line;
private JButton color;
private JButton erase;
private JButton pen;
public static boolean once = true;
public static BufferedImage buf = new BufferedImage(50,25,2);
public static Graphics2D gr = buf.createGraphics();
public static BufferedImage buf2 = new BufferedImage(50,25,2);
public static Graphics2D gr2 = buf2.createGraphics();
public static BufferedImage buf3 = new BufferedImage(50,25,2);
public static Graphics2D gr3 = buf3.createGraphics();
public static BufferedImage buf1 = new BufferedImage(50,25,2);
public static Graphics2D gr1 = buf1.createGraphics();
Menu()
{
setBackground(Color.GRAY);
TitledBorder titledBorder = BorderFactory.createTitledBorder("Toolbox");
setBorder(titledBorder);
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
;
clear = new JButton("Clear");
clear.setActionCommand("Clear");
clear.addActionListener(this);
pen = new JButton("Pen");
pen.setActionCommand("Pen");
pen.addActionListener(this);
erase = new JButton("Erase");
erase.setActionCommand("e");
erase.addActionListener(this);
color = new JButton("Color");
color.setActionCommand("Color");
color.addActionListener(this);
ImageIcon ir2 = new ImageIcon(buf3);
JButton emptyR = new JButton(ir2);
emptyR.addActionListener(this);
emptyR.setActionCommand("ER");
ImageIcon ir1 = new ImageIcon(buf2);
JButton emptyO = new JButton(ir1);
emptyO.addActionListener(this);
emptyO.setActionCommand("EO");
ImageIcon ir = new ImageIcon(buf);
JButton fillR = new JButton(ir);
fillR.addActionListener(this);
fillR.setActionCommand("FR");
ImageIcon io = new ImageIcon(buf1);
JButton fillO = new JButton(io);
fillO.addActionListener(this);
fillO.setActionCommand("FO");
line = new JButton("Line");
line.setActionCommand("L");
line.addActionListener(this);
JButton button6 = new JButton("Line");
button6.addActionListener(this);
JRadioButton thin = new JRadioButton("Thin Line");
thin.addActionListener(this);
JRadioButton medium = new JRadioButton("Medium Line");
medium.addActionListener(this);
JRadioButton thick = new JRadioButton("Thick Line");
thick.addActionListener(this);
ButtonGroup lineOption = new ButtonGroup( );
lineOption.add(thin);
lineOption.add(medium);
lineOption.add(thick);
add(clear);
add(erase);
add(color);
add(pen);
add(line);
add(thin);
add(medium);
add(thick);
add(emptyR);
add(emptyO);
add(fillR);
add(fillO);
buttonGraphics();
once = false;
}
public static Menu getInstance()
{
if(instance == null)
instance = new Menu();
return instance;
}
public static void buttonGraphics()
{
if (once == true)
{
gr.setColor(Color.RED);
gr1.setColor(Color.RED);
gr2.setColor(Color.RED);
gr3.setColor(Color.RED);
}else
gr3.setColor(bgColor);
gr3.drawRect(0, 0, 48, 23);
gr2.setColor(bgColor);
gr2.drawOval(0, 0, 47, 23);
gr.setColor(bgColor);
gr.fillRect(0, 0, 50, 23);
gr1.setColor(bgColor);
gr1.fillOval(0, 0, 50, 25);
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Clear"))
{
Drawing.getInstance().clear();
repaint();
}
if (e.getActionCommand().equals("e"))
{
Main.choice = 8;
Drawing.getInstance().draw();
}
if (e.getActionCommand().equals("Color"))
{
bgColor = JColorChooser.showDialog(this,"Choose Background Color", getBackground());
gr.setColor(bgColor);
gr1.setColor(bgColor);
gr2.setColor(bgColor);
gr3.setColor(bgColor);
Main.choice = 7;
buttonGraphics();
repaint();
Drawing.getInstance().draw();
}
if (e.getActionCommand().equals("L"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 1;
repaint();
}
if (e.getActionCommand().equals("FR"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 2;
repaint();
}
if (e.getActionCommand().equals("EO"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 3;
repaint();
}
if (e.getActionCommand().equals("FO"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 4;
repaint();
}
if(e.getActionCommand().equals("ER"))
{
Drawing.getInstance().FoE = 2;
Main.choice = 5;
repaint();
}
if (e.getActionCommand().equals("Thin Line"))
{
stroke = 0;
Drawing.getInstance().eraserHeight = 5;
Drawing.getInstance().eraserWidth = 5;
}
if (e.getActionCommand().equals("Medium Line"))
{
stroke = 1;
Drawing.getInstance().eraserHeight = 15;
Drawing.getInstance().eraserWidth = 15;
}
if (e.getActionCommand().equals("Thick Line"))
{
stroke = 2;
Drawing.getInstance().eraserHeight = 25;
Drawing.getInstance().eraserWidth = 25;
}
if(e.getActionCommand().equals("Pen"))
{
Main.choice = 10;
Drawing.getInstance().draw();
}
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
}
//DRAWING CANVAS PANEL//
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.event.*;
import java.awt.image.BufferedImage;
/**
*
* #author Calvin Moss
*/
public class Drawing extends JPanel implements MouseListener, ActionListener, MouseMotionListener
{
public int x1, x2 ,y1, y2;
public static Drawing instance;
public int FoE;
public int eraserWidth = 15;
public int eraserHeight = 15;
BufferedImage grid;
static Graphics2D gc;
Drawing()
{
setBackground(Color.RED);
addMouseListener(this);
}
public static Drawing getInstance()
{
if(instance == null)
instance = new Drawing();
return instance;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
if(grid == null)
{
Toolkit toolkit = Toolkit.getDefaultToolkit ();
Dimension dim = toolkit.getScreenSize();
grid = (BufferedImage)(this.createImage(dim.width,dim.height));
gc = grid.createGraphics();
gc.setColor(Color.RED);
BufferedImage grid;
Graphics2D gc;
}
g2.drawImage(grid, null, 0, 0);
}
public void draw()
{
Graphics2D g = (Graphics2D)getGraphics();
int w = x2 - x1;
if (w<0)
w = w *(-1);
int h = y2-y1;
if (h<0)
h= h*(-1);
gc.setColor(Menu.bgColor);
switch(Main.choice)
{
case 1:
{
removeMouseMotionListener(instance);
if (Menu.stroke == 0)
gc.setStroke(new BasicStroke (1));
if (Menu.stroke == 1)
gc.setStroke(new BasicStroke (3));
if (Menu.stroke == 2)
gc.setStroke(new BasicStroke (6));
gc.drawLine(x1, y1, x2, y2);
repaint();
break;
}
case 2:
{
removeMouseMotionListener(instance);
check();
gc.drawRect(x1, y1, w, h);
gc.fillRect(x1, y1, w, h);
repaint();
break;
}
case 3:
{
removeMouseMotionListener(instance);
check();
gc.drawOval(x1, y1, w, h);
repaint();
break;
}
case 4:
{
removeMouseMotionListener(instance);
check();
gc.drawOval(x1, y1, w, h);
gc.fillOval(x1, y1, w, h);
repaint();
break;
}
case 5:
{
removeMouseMotionListener(instance);
check();
gc.drawRect(x1, y1, w, h);
repaint();
break;
}
case 6:
{
removeMouseMotionListener(instance);
repaint();
Color temp = gc.getColor();
gc.setColor(Color.WHITE);
gc.fillRect(0, 0, getWidth(), getHeight());
gc.setColor(temp);
repaint();
break;
}
case 7:
{
removeMouseMotionListener(instance);
gc.setColor(Menu.bgColor);
break;
}
case 8:
{
FoE = 0;
addMouseMotionListener(instance);
break;
}
case 10:
{
FoE = 1;
addMouseMotionListener(instance);
break;
}
}
}
public void check()
{
if (Menu.stroke == 0)
gc.setStroke(new BasicStroke (1));
if (Menu.stroke == 1)
gc.setStroke(new BasicStroke (3));
if (Menu.stroke == 2)
gc.setStroke(new BasicStroke (6));
if (x1 > x2)
{
int z = 0;
z = x1;
x1 = x2;
x2 =z;
}
if (y1 > y2)
{
int z = 0;
z = y1;
y1 = y2;
y2 = z;
}
}
public void clear()
{
repaint();
Color temp = gc.getColor();
gc.setColor(Color.WHITE);
gc.fillRect(0, 0, getWidth(), getHeight());
gc.setColor(temp);
repaint();
}
public void mouseExited(MouseEvent e){ }
public void mouseEntered(MouseEvent e){}
public void mouseClicked(MouseEvent e){
}
public void mousePressed(MouseEvent evt)
{
x1 = evt.getX();
y1= evt.getY();
}
public void mouseReleased(MouseEvent evt)
{
x2 = evt.getX();
y2 = evt.getY();
removeMouseMotionListener(instance);
draw();
}
public void mouseDragged(MouseEvent me)
{
check();
if (FoE == 0)
{
Color c = gc.getColor();
gc.setColor(Color.WHITE);
gc.drawOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
gc.fillOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
gc.setColor(c);
repaint();
}
else if (FoE == 1)
{
gc.setColor(gc.getColor());
gc.drawOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
gc.fillOval(me.getX(), me.getY(), eraserWidth, eraserHeight);
repaint();
}
else
{
}
}
public void mouseMoved(MouseEvent arg0)
{
}
public void actionPerformed(ActionEvent arg0) {
}
}

I haven't tested your code but it looks like you're trying to add add JScrollPane to your JPanel (Drawing). It should be the other way around you should add the JPanel to the JScrollPane and then add the JScrollPane to the content pane of the frame:
JScrollPane scrollPane = new JScrollPane(Drawing.getInstance());
getContentPane().add(scrollPane, BorderLayout.CENTER);
How to use JScrollPane

You need to override the getPreferredSize() method of your Drawing class to return the size of the BufferedImages.
Scrollbars only appear when the preferred size of the component added to the scroll pane is greater than the size of the scroll pane.

Related

Issues with paint after zooming in and zooming out of JPanel

I have a scrollable JPanel, with some number drawn through the "drawString" method. When I click the zoom in button, the repaint method is invoked and the number becomes larger, as expected. But when I try to scroll to the right, part of the number is either missing or is painted in its original size instead of the new zoomed size. Below is the minimal reproducible code.
package sometest;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
public class SomeTest implements Runnable
{
public static JButton in;
public static JButton out;
public static void main(String[] args)
{
SomeTest st = new SomeTest();
st.run();
}
#Override
public void run()
{
JMenuBar mb = new JMenuBar();
in = new JButton("Zoom In");
out = new JButton("Zoom Out");
JFrame f = new JFrame("Example");
Visualization v = new Visualization();
JScrollPane sp = new JScrollPane(v);
MouseAdapter mouseAdapter = new MouseAdapter()
{
private Point origin;
#Override
public void mousePressed(MouseEvent e)
{
origin = new Point(e.getPoint());
}
#Override
public void mouseDragged(MouseEvent e)
{
JViewport vp = null;
if (origin != null)
{
vp = sp.getViewport();
}
if (vp != null)
{
int deltaX = origin.x - e.getX();
int deltaY = origin.y - e.getY();
Rectangle view = vp.getViewRect();
view.x += deltaX;
view.y += deltaY;
v.scrollRectToVisible(view);
}
}
};
sp.getViewport().addMouseListener(mouseAdapter);
sp.getViewport().addMouseMotionListener(mouseAdapter);
f.add(sp);
f.setJMenuBar(mb);
mb.add(in);
mb.add(out);
f.setContentPane(sp);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
package sometest;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import javax.swing.JPanel;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
import static sometest.SomeTest.in;
import static sometest.SomeTest.out;
public class Visualization extends JPanel implements Scrollable, ActionListener
{
private double zoomFactor = 1;
private double prevZoomFactor = 1;
private boolean zoomer;
private double xOffset = 0;
private double yOffset = 0;
public Visualization()
{
in.addActionListener(this);
out.addActionListener(this);
Font currentFont = getFont();
Font newFont = currentFont.deriveFont(currentFont.getSize() * 18F);
setFont(newFont);
setBackground(Color.WHITE);
}
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==in)
{
zoomer = true;
zoomFactor *= 1.1;
repaint();
}
if(e.getSource()==out)
{
zoomer = true;
zoomFactor /= 1.1;
repaint();
}
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if(zoomer)
{
AffineTransform at = new AffineTransform();
Dimension center = getPreferredScrollableViewportSize();
Double xRel = center.getWidth()/2;
Double yRel = center.getHeight()/2;
double zoomDiv = zoomFactor / prevZoomFactor;
xOffset = (zoomDiv) * (xOffset) + (1 - zoomDiv) * xRel;
yOffset = (zoomDiv) * (yOffset) + (1 - zoomDiv) * yRel;
at.translate(xOffset, yOffset);
at.scale(zoomFactor, zoomFactor);
prevZoomFactor = zoomFactor;
g2d.transform(at);
zoomer = false;
}
g2d.drawString("1234567890", 500, 200);
g2d.dispose();
}
#Override
public Dimension getPreferredSize()
{
if(zoomer)
{
return new Dimension((int)(2000*zoomFactor), (int)(750*zoomFactor));
}
else
{
return new Dimension(2000, 750);
}
}
#Override
public Dimension getPreferredScrollableViewportSize()
{
return new Dimension(1550, 750);
}
#Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
{
return 32;
}
#Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
{
return 32;
}
#Override
public boolean getScrollableTracksViewportWidth()
{
return false;
}
#Override
public boolean getScrollableTracksViewportHeight()
{
return false;
}
}
When I zoom in and scroll, I'm expecting the drawn number to remain the same size. As far as I know, the repaint method is supposed to automatically handle cases such as when scrolling or resizing. Have I misused the repaint method or is my problem something entirely different?
It might be better to use the AffineTransform#concatenate(AffineTransform) method to combine the AffineTransform for zoom and the AffineTransform for translation.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
AffineTransform scrollTransform = g2d.getTransform();
scrollTransform.concatenate(zoomTransform);
g2d.setTransform(scrollTransform);
g2d.drawString("1234567890", 500, 200);
g2d.dispose();
}
SomeTest2.java
// package sometest;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class SomeTest2 {
public JComponent makeUI() {
Visualization v = new Visualization();
MouseAdapter mouseAdapter = new DragScrollListener();
v.addMouseListener(mouseAdapter);
v.addMouseMotionListener(mouseAdapter);
JButton in = new JButton("Zoom In");
in.addActionListener(e -> v.setZoomFactor(1.1));
JButton out = new JButton("Zoom Out");
out.addActionListener(e -> v.setZoomFactor(1 / 1.1));
JMenuBar mb = new JMenuBar();
mb.add(in);
mb.add(out);
EventQueue.invokeLater(() -> v.getRootPane().setJMenuBar(mb));
return new JScrollPane(v);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SomeTest2().makeUI());
f.setSize(640, 480);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class Visualization extends JPanel {
private final AffineTransform zoomTransform = new AffineTransform();
private final Rectangle rect = new Rectangle(2000, 750);
public Visualization() {
Font currentFont = getFont();
Font newFont = currentFont.deriveFont(currentFont.getSize() * 18F);
setFont(newFont);
setBackground(Color.WHITE);
}
public void setZoomFactor(double zoomFactor) {
zoomTransform.scale(zoomFactor, zoomFactor);
revalidate();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
AffineTransform scrollTransform = g2d.getTransform();
scrollTransform.concatenate(zoomTransform);
g2d.setTransform(scrollTransform);
g2d.drawString("1234567890", 500, 200);
g2d.dispose();
}
#Override
public Dimension getPreferredSize() {
Rectangle r = zoomTransform.createTransformedShape(rect).getBounds();
return new Dimension(r.width, r.height);
}
}
class DragScrollListener extends MouseAdapter {
private final Point origin = new Point();
#Override
public void mouseDragged(MouseEvent e) {
Component c = e.getComponent();
Container p = SwingUtilities.getUnwrappedParent(c);
if (p instanceof JViewport) {
JViewport viewport = (JViewport) p;
Point cp = SwingUtilities.convertPoint(c, e.getPoint(), viewport);
Point vp = viewport.getViewPosition();
vp.translate(origin.x - cp.x, origin.y - cp.y);
((JComponent) c).scrollRectToVisible(new Rectangle(vp, viewport.getSize()));
origin.setLocation(cp);
}
}
#Override
public void mousePressed(MouseEvent e) {
Component c = e.getComponent();
Container p = SwingUtilities.getUnwrappedParent(c);
if (p instanceof JViewport) {
JViewport viewport = (JViewport) p;
Point cp = SwingUtilities.convertPoint(c, e.getPoint(), viewport);
origin.setLocation(cp);
}
}
}

Adding Start, Stop, Reset button to simple java game

I am a new coder. I am having trouble adding a start and stop button for this piece of example code that i am working off. I'm sure i have to mess with with Thread.sleep(10); in the game class. This code starts the game when the program is run. is there a way i could add start button to start the thread. I have created j button already. Thanks.
Game Class
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Game extends JPanel {
Ball ball = new Ball(this);
Racquet racquet = new Racquet(this);
public Game() {
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
racquet.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
racquet.keyPressed(e);
}
});
setFocusable(true);
}
private void move() {
ball.move();
racquet.move();
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
racquet.paint(g2d);
}
public void gameOver() {
JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Mini Tennis");
Game game = new Game();
frame.add(game);
frame.setSize(300, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
game.move();
game.repaint();
Thread.sleep(10);
}
}
}
Ball Class
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class Ball {
private static final int DIAMETER = 30;
int x = 0;
int y = 0;
int xa = 1;
int ya = 1;
private Game game;
public Ball(Game game) {
this.game= game;
}
void move() {
if (x + xa < 0)
xa = 1;
if (x + xa > game.getWidth() - DIAMETER)
xa = -1;
if (y + ya < 0)
ya = 1;
if (y + ya > game.getHeight() - DIAMETER)
game.gameOver();
if (collision()){
ya = -1;
y = game.racquet.getTopY() - DIAMETER;
}
x = x + xa;
y = y + ya;
}
private boolean collision() {
return game.racquet.getBounds().intersects(getBounds());
}
public void paint(Graphics2D g) {
g.fillOval(x, y, DIAMETER, DIAMETER);
}
public Rectangle getBounds() {
return new Rectangle(x, y, DIAMETER, DIAMETER);
}
}
Racquet Class
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
public class Racquet {
private static final int Y = 330;
private static final int WIDTH = 60;
private static final int HEIGHT = 10;
int x = 0;
int xa = 0;
private Game game;
public Racquet(Game game) {
this.game = game;
}
public void move() {
if (x + xa > 0 && x + xa < game.getWidth() - WIDTH)
x = x + xa;
}
public void paint(Graphics2D g) {
g.fillRect(x, Y, WIDTH, HEIGHT);
}
public void keyReleased(KeyEvent e) {
xa = 0;
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa = -1;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = 1;
}
public Rectangle getBounds() {
return new Rectangle(x, Y, WIDTH, HEIGHT);
}
public int getTopY() {
return Y;
}
}
This is an mcve demonstrating the structure outlined in Hovercraft Full Of Eels comment :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionListener;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class AnimationUsingTimer {
private Timer timer;
AnimationUsingTimer() {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AnimationPanel animationPanel = new AnimationPanel();
window.add(animationPanel);
JButton start = new JButton("Start");
start.addActionListener(e -> animationPanel.start());
window.add(start, BorderLayout.PAGE_START);
JButton stop = new JButton("Stop");
stop.addActionListener(e -> animationPanel.stop());
window.add(stop, BorderLayout.PAGE_END);
window.pack();
window.setVisible(true);
}
class AnimationPanel extends JPanel{
private BufferedImage img;
private Area ball, walls;
private final static int W = 450, H = 300, DIAMETER = 20;
private int x = W/2, y = H/2, xDelta = 3, yDelta = 2;
AnimationPanel() {
img = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);
JLabel imageLabel = new JLabel(new ImageIcon(img));
add(imageLabel);
walls = new Area(new Rectangle(0,0,W,H));
ActionListener animate = e -> {
animate();
repaint();
};
timer = new Timer(50, animate);
}
public void animate() {
x+=xDelta; y+=yDelta;
ball = new Area(new Ellipse2D.Double(x, y, DIAMETER, DIAMETER));
if (checkCollision(ball,walls)) {
if ( x+DIAMETER>img.getWidth() || x<0 ) {
xDelta *= -1;
}
if(y+DIAMETER>img.getHeight() || y<0 ) {
yDelta *= -1;
}
}
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2D = img.createGraphics();
g2D.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2D.setColor(Color.CYAN);
g2D.fillRect(0, 0, img.getWidth(), img.getHeight());
if(ball != null){
g2D.setColor(Color.RED);
g2D.fill(ball);
}
g2D.dispose();
}
void start(){
timer.start();
}
void stop(){
timer.stop();
}
private boolean checkCollision(Area area1, Area area2) {
return area1.getBounds().intersects(area2.getBounds());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new AnimationUsingTimer());
}
}

Update LookAndFeel Values On The Fly

I want to be able to update the LookAndFeel attributes of my Swing GUI on the fly. In this case, I have a simple Swing/Awt game running what starts out as the Nimbus LookAndFeel. At various points after start up I want to change (let us say) just one detail: the background color of my application.
I can change the background color by doing this:
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED);
SwingUtilities.updateComponentTreeUI(SomeGame.this);
break;
}
}
This "works" in that the background color of the app changes correctly and the program doesn't crash. But on the command line I get error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.synth.SynthLookAndFeel.paintRegion(SynthLookAndFeel.java:371)
at javax.swing.plaf.synth.SynthLookAndFeel.update(SynthLookAndFeel.java:335)
Obviously, something is null, but I can not figure out what it is or how to fix it. There must be something I don't understand. I have looked at other StackOverflow questions about setting background colors in Nimbus and overriding the LookAndFeel information after startup.
When I call getLookAndFeelDefaults() do I need to specify the rest of the defaults as well?
Have there been changes in how this works between Java 1.6 and 1.7?
all code for Java6, have to change Nimbus imports for Java7
Nimbus has a few suprises, one of them is that is possible (without dirty hacks, I'm leaving comments for those hacks) to change Background for JPanel only one time
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.AlphaComposite;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.EmptyBorder;
public class ButtonTest {
private JFrame frame;
private JPanel panel;
private JButton opaqueButton1;
private JButton opaqueButton2;
private SoftJButton softButton1;
private SoftJButton softButton2;
private Timer alphaChanger;
public void createAndShowGUI() {
opaqueButton1 = new JButton("Opaque Button");
opaqueButton2 = new JButton("Opaque Button");
softButton1 = new SoftJButton("Transparent Button");
softButton2 = new SoftJButton("Transparent Button");
opaqueButton1.setBackground(Color.GREEN);
softButton1.setBackground(Color.GREEN);
panel = new JPanel();
panel.setLayout(new java.awt.GridLayout(2, 2, 10, 10));
panel.add(opaqueButton1);
panel.add(softButton1);
panel.add(opaqueButton2);
panel.add(softButton2);
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
frame = new JFrame();
frame.add(panel);
frame.setLocation(150, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
alphaChanger = new Timer(50, new ActionListener() {
private float incrementer = -.03f;
#Override
public void actionPerformed(ActionEvent e) {
float newAlpha = softButton1.getAlpha() + incrementer;
if (newAlpha < 0) {
newAlpha = 0;
incrementer = -incrementer;
} else if (newAlpha > 1f) {
newAlpha = 1f;
incrementer = -incrementer;
}
softButton1.setAlpha(newAlpha);
softButton2.setAlpha(newAlpha);
}
});
alphaChanger.start();
Timer uiChanger = new Timer(3500, new ActionListener() {
private final LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
private int index = 1;
#Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(laf[index].getClassName());
if (laf[index].getClassName().equals("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel")) {
UIManager.getLookAndFeelDefaults().put("Panel.background", Color.orange);
SwingUtilities.updateComponentTreeUI(frame);
} else {
panel.setBackground(Color.yellow);
SwingUtilities.updateComponentTreeUI(frame);
}
opaqueButton1.setText(laf[index].getClassName());
softButton1.setText(laf[index].getClassName());
frame.pack();
} catch (Exception exc) {
exc.printStackTrace();
}
index = (index + 1) % laf.length;
}
});
uiChanger.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest().createAndShowGUI();
}
});
}
private static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
SoftJButton() {
this(null, null);
}
SoftJButton(String text) {
this(text, null);
}
SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}
but for JComponent it is possible to change its Color, Font, etc by calling UIManager.getLookAndFeel().uninitialize();, but this does not work for containers
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
public class NimbusTestButtonsBackground extends JFrame {
private static final long serialVersionUID = 1L;
private javax.swing.JButton button;
public NimbusTestButtonsBackground() {
button = new javax.swing.JButton();
button.setText("Text");
add(button);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
this.pack();
Timer t = new Timer(1000, new ActionListener() {
private Random r = new Random();
#Override
public void actionPerformed(ActionEvent e) {
Color c = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
try {
LookAndFeel lnf = UIManager.getLookAndFeel().getClass().newInstance();
UIDefaults uiDefaults = lnf.getDefaults();
uiDefaults.put("nimbusBase", c);
UIManager.getLookAndFeel().uninitialize();
UIManager.setLookAndFeel(lnf);
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
UIDefaults defaults = UIManager.getDefaults();
defaults.put("Button.background", c);
SwingUtilities.updateComponentTreeUI(button);
}
});
t.start();
}
public static void main(String args[]) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
return;
}
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new NimbusTestButtonsBackground().setVisible(true);
}
});
}
}
then I see (this way as most comfortable, easiest, etc..) overriding paintComponent for JPanel as best the best way
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
public class ChangePanelBackgroundNimbus {
private JFrame frame = new JFrame();
public ChangePanelBackgroundNimbus() {
GradientPane pane = new GradientPane();
pane.setLayout(new GridLayout(6, 4, 10, 10));
for (int i = 1; i <= 24; i++) {
pane.add(createButton(i));
}
pane.setOpaque(false);
frame.add(pane);
RepaintManager.setCurrentManager(new RepaintManager() {
#Override
public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
Container con = c.getParent();
while (con instanceof JComponent) {
if (!con.isVisible()) {
return;
}
if (con instanceof GradientPane) {
c = (JComponent) con;
x = 0;
y = 0;
w = con.getWidth();
h = con.getHeight();
}
con = con.getParent();
}
super.addDirtyRegion(c, x, y, w, h);
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
//frame.setSize(400, 300);
frame.pack();
frame.setVisible(true);
}
private JButton createButton(final int text) {
JButton button = new JButton(Integer.toString(text));
return button;
}
class GradientPane extends JPanel {
private static final long serialVersionUID = 1L;
private final int h = 150;
private BufferedImage img = null;
private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB);
public GradientPane() {
paintBackGround(new Color(150, 250, 150));
Timer t = new Timer(500, new ActionListener() {
private Random r = new Random();
#Override
public void actionPerformed(ActionEvent e) {
paintBackGround(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)));
}
});
t.start();
}
public void paintBackGround(Color g) {
Graphics2D g2 = shadow.createGraphics();
g2.setPaint(g);
g2.fillRect(0, 0, 1, h);
g2.setComposite(AlphaComposite.DstIn);
g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h, new Color(0.4f, 0.8f, 0.8f, 0.5f)));
g2.fillRect(0, 0, 1, h);
g2.dispose();
}
#Override
public void paintComponent(Graphics g) {
if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) {
img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g2 = img.createGraphics();
super.paintComponent(g2);
Rectangle bounds = this.getVisibleRect();
g2.scale(bounds.getWidth(), -1);
g2.drawImage(shadow, bounds.x, -bounds.y - h, null);
g2.scale(1, -1);
g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h, null);
g2.dispose();
g.drawImage(img, 0, 0, null);
repaint();
}
}
public static void main(String[] args) {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ChangePanelBackgroundNimbus ml = new ChangePanelBackgroundNimbus();
}
});
}
}

How can I make the Image disappear when I click into it?

I have an image inside the JOptionPane and I want it to disappear whenever I point the mouse cursor and click into it.
Is there something to do about the position?
Thanks...
Here's the code :
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
class ImageBlinking extends JComponent
{
BufferedImage image;
boolean showImage;
int x = -1;
int y = -1;
Random r;
ImageBlinking()
{
try
{
File sourceimage = new File("ball.gif");
image = ImageIO.read(sourceimage);
}
catch (IOException e)
{
e.printStackTrace();
}
r = new Random();
ActionListener listener = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (image != null)
{
if (!showImage)
{
int w = image.getWidth();
int h = image.getHeight();
int rx = getWidth() - w;
int ry = getHeight() - h;
if (rx > -1 && ry > -1)
{
x = r.nextInt(rx);
y = r.nextInt(ry);
}
}
showImage = !showImage;
repaint();
}
}
};
Timer timer = new Timer(200, listener);
timer.start();
setPreferredSize(new Dimension(1000, 1000));
JOptionPane.showMessageDialog(null, this);
timer.stop();
}
public void paintComponent(Graphics g)
{
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
if (image != null)
{
g.drawImage(image, x, y,80,80, this);
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ImageBlinking();
}
});
}
}
(Edited:)
I put a Keylistener on your JComponent, then I look if the MouseEvent is on your Image and if its the case, I stop the timer and put the color of the image to Black
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
class BlockBlinking extends JComponent {
BufferedImage image;
boolean showImage;
int x = -1;
int y = -1;
int imageW = 20;
int imageH = 20;
Random r;
private Timer timer;
Color imageColor=null;
BlockBlinking() {
{
try
{
File sourceimage = new File("ball.gif");
image = ImageIO.read(sourceimage);
}
catch (IOException e)
{
e.printStackTrace();
}
this.addMouseListener(new MyMouseListener());
r = new Random();
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (image != null) {
if (!showImage) {
int w = image.getWidth();
int h = image.getHeight();
int rx = getWidth() - w;
int ry = getHeight() - h;
if (rx > -1 && ry > -1) {
x = r.nextInt(rx);
y = r.nextInt(ry);
}
}
showImage = !showImage;
repaint();
}
}
};
timer = new Timer(500, listener);
timer.start();
setPreferredSize(new Dimension(500, 400));
JOptionPane.showMessageDialog(null, this);
timer.stop();
}
}
public void paintComponent(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
if (image != null) {
if(imageColor != null){
Graphics imageGraphic =image.createGraphics();
imageGraphic.setColor(imageColor);
imageGraphic.fillRect(0, 0, image.getWidth(), image.getHeight());
}
g.drawImage(image, x, y,imageW,imageH, this);
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new BlockBlinking();
}
});
}
class MyMouseListener extends MouseAdapter {
#Override
public void mouseReleased(MouseEvent e) {
if (e.getX() >= x && e.getX() <= x + imageW && e.getY() >= y && e.getY() <= y + imageH) {
imageColor = Color.BLACK;
repaint();
timer.stop();
}
}
}
}
Edit: look at the fields imageW and imageH
One approach is to use a JToggleButton.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
class ImageVanish extends JComponent {
ImageVanish() {
// put your image reading code here..
BufferedImage imageSelected = new BufferedImage(
32,32,BufferedImage.TYPE_INT_ARGB);
BufferedImage image = new BufferedImage(
32,32,BufferedImage.TYPE_INT_ARGB);
Graphics g = image.createGraphics();
g.setColor(Color.ORANGE);
g.fillOval(0,0,32,32);
g.dispose();
// END - image read
JToggleButton b = new JToggleButton();
b.setIcon(new ImageIcon(image));
b.setSelectedIcon(new ImageIcon(imageSelected));
b.setBorderPainted(false);
b.setContentAreaFilled(false);
JOptionPane.showMessageDialog(null, b);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ImageVanish();
}
});
}
}
For the positioning, see #Hovercraft FOE's advice on their answer to your earlier question.

Bricks change color every instance of time

so, i'm doing breakout in java (this is not h/w, school is over)
I want to bricks to be random in color, but my bricks change color while the game is running. so right now, it looks like the bricks are lighting up!! please help!!
package main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Random;
public class Brick {
public static final int X = 0, Y = 0, ROW_SIZE = 8, COL_SIZE = 5;
private Random random = new Random();
private ArrayList<Rectangle> arr = new ArrayList<>();
public Brick(int width, int height) {
for(int i = 0; i < COL_SIZE; i++){
for(int j = 0; j < ROW_SIZE; j++) {
Rectangle r = new Rectangle(X + (j * (width / ROW_SIZE)),
Y + (i * (height / COL_SIZE)), (width / ROW_SIZE), (height / COL_SIZE));
arr.add(r);
}
}
}
public ArrayList<Rectangle> getList(){
return arr;
}
public void setList(ArrayList<Rectangle> rects){
arr = rects;
}
public void paint(Graphics g){
for(Rectangle rect : arr){
g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
}
}
package main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GamePanel extends JPanel implements ActionListener, KeyListener {
Player player = new Player();
Ball ball = new Ball();
Brick brick = new Brick(Pong.WIDTH, Pong.HEIGHT / 3);
JLabel label, gameOverLabel;
Timer time;
public GamePanel() {
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
time = new Timer(50, this);
time.start();
this.addKeyListener(this);
setFocusable(true);
// Displaying score
label = new JLabel();
gameOverLabel = new JLabel();
gameOverLabel.setPreferredSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
gameOverLabel.setAlignmentX(CENTER_ALIGNMENT);
label.setAlignmentX(CENTER_ALIGNMENT);
add(label);
add(gameOverLabel);
}
private void update() {
player.update();
if (ball.update()) {
gameOverLabel.setText("GAME OVER");
time.stop();
}
ball.checkCollisionWith(player);
ball.checkBrickCollision(brick);
}
public void paintComponent(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
player.paint(g);
ball.paint(g);
brick.paint(g);
}
public void actionPerformed(ActionEvent e) {
update();
label.setText("Score: " + ball.getScore());
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
// Speed of player
int playerVelocity = 8;
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.setXVelocity(playerVelocity);
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
player.setXVelocity(-playerVelocity);
} else if (e.getKeyCode() == KeyEvent.VK_R) {
ball = new Ball();
player = new Player();
ball.setScore(0);
label.setText("Score: " + ball.getScore());
gameOverLabel.setText("");
repaint();
time.start();
}
}
#Override
public void keyReleased(KeyEvent e) {
player.setXVelocity(0);
}
#Override
public void keyTyped(KeyEvent e) {
}
}
please help! thank you...
public void paint(Graphics g){
for(Rectangle rect : arr){
g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
}
Indeed it change color on every repaint - you're creating new random Color on every call. I think you should create color in Brick constructor and reuse it.

Categories

Resources