I need some help, I have been looking around on the internet for code, for a splash screen, I have found some code which is perfect, but there is one problem, I would like the splash screen to open my program after it is done loading, how would I go about doing this? Here is the code for my Splash Screen:
/*
* This demonstration program is released without warranty or restrictions.
* You may modify and use it as you wish.
* Just don't complain to me if you have trouble.
*/
package splashdemo;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.SplashScreen;
import java.awt.geom.Rectangle2D;
/**
* Example for Splash Screen tutorial
* #author Joseph Areeda
*/
public class Main
{
static SplashScreen mySplash; // instantiated by JVM we use it to get graphics
static Graphics2D splashGraphics; // graphics context for overlay of the splash image
static Rectangle2D.Double splashTextArea; // area where we draw the text
static Rectangle2D.Double splashProgressArea; // area where we draw the progress bar
static Font font; // used to draw our text
public static void main(String[] args)
{
splashInit(); // initialize splash overlay drawing parameters
appInit(); // simulate what an application would do before starting
if (mySplash != null) // check if we really had a spash screen
mySplash.close(); // we're done with it
// begin with the interactive portion of the program
}
/**
* just a stub to simulate a long initialization task that updates
* the text and progress parts of the status in the Splash
*/
private static void appInit()
{
for (int i = 1; i <= 10; i++)
{ // pretend we have 10 things to do
int pctDone = i * 10; // this is about the only time I could calculate rather than guess progress
splashText("Configuring Program"); // tell the user what initialization task is being done
splashProgress(pctDone); // give them an idea how much we have completed
try
{
Thread.sleep(1000); // wait a second
}
catch (InterruptedException ex)
{
break;
}
}
}
/**
* Prepare the global variables for the other splash functions
*/
private static void splashInit()
{
// the splash screen object is created by the JVM, if it is displaying a splash image
mySplash = SplashScreen.getSplashScreen();
// if there are any problems displaying the splash image
// the call to getSplashScreen will returned null
if (mySplash != null)
{
// get the size of the image now being displayed
Dimension ssDim = mySplash.getSize();
int height = ssDim.height;
int width = ssDim.width;
// stake out some area for our status information
splashTextArea = new Rectangle2D.Double(15., height*0.88, width * .45, 32.);
splashProgressArea = new Rectangle2D.Double(width * .55, height*.92, width*.4, 12 );
// create the Graphics environment for drawing status info
splashGraphics = mySplash.createGraphics();
font = new Font("Dialog", Font.PLAIN, 14);
splashGraphics.setFont(font);
// initialize the status info
splashText("Starting");
splashProgress(0);
}
}
/**
* Display text in status area of Splash. Note: no validation it will fit.
* #param str - text to be displayed
*/
public static void splashText(String str)
{
if (mySplash != null && mySplash.isVisible())
{ // important to check here so no other methods need to know if there
// really is a Splash being displayed
// erase the last status text
splashGraphics.setPaint(Color.LIGHT_GRAY);
splashGraphics.fill(splashTextArea);
// draw the text
splashGraphics.setPaint(Color.BLACK);
splashGraphics.drawString(str, (int)(splashTextArea.getX() + 10),(int)(splashTextArea.getY() + 15));
// make sure it's displayed
mySplash.update();
}
}
/**
* Display a (very) basic progress bar
* #param pct how much of the progress bar to display 0-100
*/
public static void splashProgress(int pct)
{
if (mySplash != null && mySplash.isVisible())
{
// Note: 3 colors are used here to demonstrate steps
// erase the old one
splashGraphics.setPaint(Color.LIGHT_GRAY);
splashGraphics.fill(splashProgressArea);
// draw an outline
splashGraphics.setPaint(Color.BLUE);
splashGraphics.draw(splashProgressArea);
// Calculate the width corresponding to the correct percentage
int x = (int) splashProgressArea.getMinX();
int y = (int) splashProgressArea.getMinY();
int wid = (int) splashProgressArea.getWidth();
int hgt = (int) splashProgressArea.getHeight();
int doneWidth = Math.round(pct*wid/100.f);
doneWidth = Math.max(0, Math.min(doneWidth, wid-1)); // limit 0-width
// fill the done part one pixel smaller than the outline
splashGraphics.setPaint(Color.GREEN);
splashGraphics.fillRect(x, y+1, doneWidth, hgt-1);
// make sure it's displayed
mySplash.update();
}
}
}
call your program on your splash demo main method,
public static void main(String[] args)
{
splashInit();
appInit();
if (mySplash != null)
mySplash.close();
//call your program here, example HelloWorld.java
HelloWorld hello = new Helloworld();
String[] args = {};
hello.main(args);
}
Related
I am trying to make a 2D game with Java and Swing, and the window refreshes too slow. But if I move the mouse or press keys, the window refreshes as fast as it should!
Here is a GIF showing how the window refreshes quickly only when I move the mouse.
Why does the window refresh slowly like that? Why does the mouse and keyboard affect its refresh rate? How, if possible, do I make it refresh quickly all the time?
Background Info
I use a javax.swing.Timer to update the game state every 1/25 seconds, after which it calls repaint() on the game panel to redraw the scene.
I understand that a Timer might not always delay for exactly 1/25 of a second.
I also understand that calling repaint() just requests the window to be repainted ASAP and does not repaint the window immediately.
My graphics card does not support OpenGL 2+ or hardware accelerated 3D graphics, which is why I am not using libgdx or JME for game development.
System Info
Operating system: Linux Mint 19 Tara
JDK version: OpenJDK 11.0.4
Graphics card: Intel Corporation 82945G/GZ
Research
This Stack Overflow user describes the same problem I have, but the author reportedly solved the issue by calling repaint() repeatedly on a separate timer. I tried this, and it does make the window refresh somewhat faster, but even then it is a slower than I want. In this case, wiggling the mouse on the window still improves the refresh rate. Therefore, it seems like that post did not truly solve the issue.
Another Stack Overflow user also encountered the issue, but they use a continuous while-loop instead of a Timer for their game loop. Apparently, this user solved the problem by using Thread.sleep() in their while loop. However, my code accomplishes the delay using a Timer, so I do not know how Thread.sleep() could solve my problem, or even where I would put it.
I've read through Painting with AWT and Swing to figure out whether I just misunderstood the concept of repainting, but nothing in that document elucidates the issue for me. I call repaint() whenever the game updates, and the window only refreshes quickly when mouse or keyboard input is happening.
I have searched the web for several days now trying to find an answer, but nothing seems to help!
Code
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
class Game {
public static final int screenWidth = 160;
public static final int screenHeight = 140;
/**
* Create and show the GUI.
*/
private static void createAndShowGUI() {
/* Create the GUI. */
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.getContentPane().add(new GamePanel());
frame.pack();
/* Show the GUI. */
frame.setVisible(true);
}
/**
* Run the game.
*
* #param args the list of command-line arguments
*/
public static void main(String[] args) {
/* Schedule the GUI to be created on the EDT. */
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
}
/**
* A GamePanel widget updates and shows the game scene.
*/
class GamePanel extends JPanel {
private Square square;
/**
* Create a game panel and start its update-and-draw cycle
*/
public GamePanel() {
super();
/* Set the size of the game screen. */
setPreferredSize(
new Dimension(
Game.screenWidth,
Game.screenHeight));
/* Create the square in the game world. */
square = new Square(0, 0, 32, 32, Square.Direction.LEFT);
/* Update the scene every 40 milliseconds. */
Timer timer = new Timer(40, (e) -> updateScene());
timer.start();
}
/**
* Paint the game scene using a graphics context.
*
* #param g the graphics context
*/
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/* Clear the screen. */
g.setColor(Color.WHITE);
g.fillRect(0, 0, Game.screenWidth, Game.screenHeight);
/* Draw all objects in the scene. */
square.draw(g);
}
/**
* Update the game state.
*/
private void updateScene() {
/* Update all objects in the scene. */
square.update();
/* Request the scene to be repainted. */
repaint();
}
}
/**
* A Square is a game object which looks like a square.
*/
class Square {
public static enum Direction { LEFT, RIGHT };
private int x;
private int y;
private int width;
private int height;
private Direction direction;
/**
* Create a square game object.
*
* #param x the square's x position
* #param y the square's y position
* #param width the square's width (in pixels)
* #param height the square's height (in pixels)
* #param direction the square's direction of movement
*/
public Square(int x,
int y,
int width,
int height,
Direction direction) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.direction = direction;
}
/**
* Draw the square using a graphics context.
*
* #param g the graphics context
*/
public void draw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
g.setColor(Color.BLACK);
g.drawRect(x, y, width, height);
}
/**
* Update the square's state.
*
* The square slides horizontally
* until it reaches the edge of the screen,
* at which point it begins sliding in the
* opposite direction.
*
* This should be called once per frame.
*/
public void update() {
if (direction == Direction.LEFT) {
x--;
if (x <= 0) {
direction = Direction.RIGHT;
}
} else if (direction == Direction.RIGHT) {
x++;
if (x + width >= Game.screenWidth) {
direction = Direction.LEFT;
}
}
}
}
I guess you probably cannot solve your issue by enabling OpenGL, since your gpu does not support it, a possible silly workaround could be to fire a kind of event manually in each timer's iteration.
/* Update the scene every 40 milliseconds. */
final Robot robot = new Robot();
Timer timer = new Timer(40, (e) -> {
robot.mouseRelease(0); //some event
updateScene();
});
timer.start();
(And the only place you can Thread.sleep() in a Swing Application is inside a SwingWorker's doInBackground method. If you call it in EDT the whole GUI will freeze since events cannot take place.)
I ran into the same issue. The solution is quite simple. Call revalidate() immediately after you call repaint():
private void updateScene() {
/* Update all objects in the scene. */
square.update();
/* Request the scene to be repainted. */
repaint();
revalidate(); // <-- this will now repaint as fast as you wanted it to
}
I am creating a Maze game and want a timer to be displayed on the gameStage.
I have tried using java.util but it requires me to get rid of my swing timer.How could i add a refreshing timer to game
This code is used to make the game frame which contains the button pane and the gameStage.
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
/**
* This class Holds the game pane that has the moving player. It also contains
* the GamePane
*
* #author 602052004
*
*/
public class GamePane extends JPanel implements ActionListener, KeyListener {// *change
// GamePane
// to
// GamePane
// This is were the game screen is made and the player is created.
static final long serialVersionUID = 1L;
JLabel player = new JLabel();
JLabel finish = new JLabel();
JFrame gameFrame;
int playerSpeed = 4;
int FPS = 40;
// This array holds my JLabels for the walls.I used it so that i can have a
// for loop with an index for the labels.
JLabel[] walls = new JLabel[3];
{
walls[0] = new JLabel();
walls[1] = new JLabel();
walls[2] = new JLabel();
}
private final Set<Integer> keys = new HashSet<>();
// The keys set holds the keys being pressed
public static void main(String[] args) {
// Open the GUI window
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Create a new object and
// run its go() method
new GamePane().go();
}
});
}
GamePane() {
// Run the parent class constructor
super();
// Allow the panel to get focus
setFocusable(true);
// Don't let keys change the focus
}
/**
* This method creates the gameFrame and sets its layout to a cardlayout.It
* then proceeds the set up the GameFrame.The gameFrame contains the button
* pane and the gameStage
*
* The walls are an array and are used to create an index which is then used
* for the collisions.I set up the walls location here
*/
protected void go() {
setLayout(new CardLayout());
// Setup the window
gameFrame = new JFrame();
// Add this panel to the window
gameFrame.setLayout(new CardLayout());
gameFrame.add(this, "main");
gameFrame.setContentPane(this);
// Set's the window properties
gameFrame.setTitle("main");
gameFrame.setSize(800, 600);
gameFrame.setResizable(false);
gameFrame.setLocationRelativeTo(null);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.setVisible(true);
gameFrame.add(new ButtonPane(gameFrame), "buttons");
// Creates the new JPanel that will hold the game.
JPanel gamestage = new JPanel();
gamestage.setBackground(Color.darkGray);
gameFrame.add(gamestage, "game");
gamestage.setLayout(null);
// *Move the setup of the player and the timer under the walls
// Get a sample of collisions going so that i can do it over the weekend
// Setup the movable box
player.setBounds(25, 25, 20, 20);
player.setVisible(true);
player.setBackground(Color.red);
// Opaque makes the background visible
player.setOpaque(true);
// Setup the key listener
addKeyListener(this);
// Null layout allows moving objects!!!
gamestage.add(player);
// Set the timer
Timer tm = new Timer(1000 / FPS, this);
tm.start();
walls[0].setBounds(10, 15, 10, 480);// left height
walls[0].setVisible(true);
walls[0].setBackground(Color.white);
walls[0].setOpaque(true);
gamestage.add(walls[0]);
walls[1].setBounds(10, 10, 490, 10);// top width
walls[1].setVisible(true);
walls[1].setBackground(Color.white);
walls[1].setOpaque(true);
gamestage.add(walls[1]);
// wall3.setBounds(x, y, width, height);
walls[2].setBounds(10, 100, 100, 10);
walls[2].setVisible(true);
walls[2].setBackground(Color.white);
walls[2].setOpaque(true);
gamestage.add(walls[2]);
finish.setBounds(30, 455, 20, 20); // *make the game change to the main
// screen when finished
// Add a timer
finish.setVisible(true);
finish.setBackground(Color.LIGHT_GRAY);
finish.setOpaque(true);
gamestage.add(finish);
}
/**
* Check if two JLabel objects are touching
*
* #param a
* The first JLabel
* #param b
* The second JLabel
* #return true if the JLabels are touching
*/
public boolean areColliding(JLabel a, JLabel b) {
return a.getBounds().intersects(b.getBounds());
}
/**
* this method makes the player move. It takes the players speed and
* subtracts or adds the player speed to the current position of the player.
* It also figures out were the player is at currently aswell.
*
* #param arg0
*/
#Override
public void actionPerformed(ActionEvent arg0) {
// Move up if W is pressed
if (keys.contains(KeyEvent.VK_W)) {
player.setLocation(player.getX(), player.getY() - playerSpeed);
}
// Move right if D is pressed
if (keys.contains(KeyEvent.VK_D)) {
player.setLocation(player.getX() + playerSpeed, player.getY());
}
// Move down if S is pressed
if (keys.contains(KeyEvent.VK_S)) {
player.setLocation(player.getX(), player.getY() + playerSpeed);
}
// Move left if A is pressed
if (keys.contains(KeyEvent.VK_A)) {
player.setLocation(player.getX() - playerSpeed, player.getY());
}
for (int i = 0; i < walls.length; i++) {
// I created a for loop instead
// of a do loop because the for
// loop would have been a lot
// simpler to manage
if (areColliding(walls[i], player)) { // Reposition the target
int newX = (int) (25);
int newY = (int) (25);
player.setLocation(newX, newY);
}
}
if (areColliding(finish, player)) {
// Reposition the target
int newX = 25;
int newY = 25;
player.setLocation(newX, newY);
CardLayout layout = (CardLayout) gameFrame.getContentPane()
.getLayout();
layout.show(gameFrame.getContentPane(), "buttons");
}
}
#Override
public void keyPressed(KeyEvent e) {
// Add the key to the list
// of pressed keys
if (!keys.contains(e.getKeyCode())) {
keys.add(e.getKeyCode());
}
}
#Override
public void keyReleased(KeyEvent e) {
// Remove the key from the
// list of pressed keys
keys.remove((Integer) e.getKeyCode());
}
#Override
public void keyTyped(KeyEvent e) {
}
}
this code shows the game pane when the buttob is pressed
/**
* This pane contains the button and sets up the button pane
*/
import java.awt.CardLayout;
import java.awt.Color;
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 ButtonPane extends JPanel {
private JButton startBTN;// Calls the JButton
JFrame game;
public ButtonPane(JFrame g) {
game = g;
setLayout(new GridBagLayout());
setBackground(Color.gray);// Sets the menu stages color blue
startBTN = new JButton("Game");// Creates a new button
add(startBTN);// Adds the button on the startStage
startBTN.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (game.getContentPane().getLayout() instanceof CardLayout) {
CardLayout layout = (CardLayout) getParent().getLayout();
layout.show(game.getContentPane(), "game");
}
}
});
}
}
Okay, so you have a Timer already, which is ticking away at 1000/FPS times a second, cool. All you really need is away to calculate the difference between two points in time, which, amazingly, is very simple.
Start by defining a "start time"
private Instant startTime;
This will be null till you need it. When you want to start the timer, use startTime = Instant.now();
When startTime != null, you want to calculate the difference between it and now...
Duration runningTime = Duration.between(startTime, Instant.now());
This now tells you how long the timer has been running for.
Next, we need to make some decisions, like what to do when the timer runs out, but for that, we actually need to know how lone the timer should run for...
private Duration timeOutDuration = Duration.ofSeconds(5);
This just sets up a timeout of 5 seconds, you can use what ever range you want.
This then allows us to calculate the remaining time of the timer...
Duration timeRemainig = timeOutDuration.minus(runningTime);
and then to make decisions about what to do...
if (timeRemainig.isNegative() || timeRemainig.isZero()) {
// Time has run out...
// startTime = null; // stop the timer
} else {
// Update the UI
}
The date/time API introduced in Java 8 is incredibly powerful and flexible (and a lot of fun, when you get your head around it)
A solution might start looking something like...
private Duration timeOutDuration = Duration.ofSeconds(5);
private Instant startTime; // Set this when you're ready to start the timer
#Override
public void actionPerformed(ActionEvent arg0) {
if (startTime != null) {
Duration runningTime = Duration.between(startTime, Instant.now());
Duration timeRemainig = timeOutDuration.minus(runningTime);
if (timeRemainig.isNegative() || timeRemainig.isZero()) {
// Time has run out...
// startTime = null; // stop the timer
} else {
// Update the UI
}
}
Formatting a Duration for output generally looks something like...
long hours = timeRemainig.toHours();
long mins = timeRemainig.minusHours(hours).toMinutes();
// Or if you're lucky enough to be using Java 9+
//String formatted = String.format("%dhrs %02dmins", duration.toHours(), duration.toMinutesPart());
String formatted = String.format("%dhrs %02dmins", hours, mins);
or simular, depending on how you want it formatted
Why use this approach instead of some "counter"
Simple, it's (super) accurate. Timer only guarantees a "at least" interval, that is, it will delay no less then the value apply, this means that it's possible to introduce a "drag" over time, where a counter would fall out of sync. Sure, over a short period of time, it's probably not a big deal, but since there is a (super easy) better way to do it, why not make use of it.
The solution is also super flexible, applied to a broad spectrum of similar issues. I use the above concept as part of time based animations, which generally produce a far superior, overall, result.
I have to display a message box on some action, I am able to do that but the message dialog box appears smaller in size.Is there any way to increase the size of the message box in java?
here is my code:
Display.getDefault().syncExec(new Runnable () {
#Override
public void run() {
// Get active window page
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
Shell parent = window.getShell();
MessageBox dialog =
new MessageBox(shell,SWT.RESIZE|SWT.ICON_INFORMATION|SWT.OK);
dialog.setText("Project info");
dialog.setMessage("Project info Text will come here");
int returnCode = dialog.open();
System.out.println("returnCode "+ returnCode);
}
});
You can create your own dialog box. Take a look at the examples here. I've copied the relevant code, in case that link stops working:
public class DialogExample extends Dialog {
public DialogExample(Shell parent) {
super(parent);
}
public String open() {
Shell parent = getParent();
Shell dialog = new Shell(parent, SWT.DIALOG_TRIM
| SWT.APPLICATION_MODAL);
dialog.setSize(100, 100);
dialog.setText("Java Source and Support");
dialog.open();
Display display = parent.getDisplay();
while (!dialog.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
return "After Dialog";
}
public static void main(String[] argv) {
new DialogExample(new Shell());
}
}
As far as i know SWT uses the OS system message box so this means you can only change the title/text and icon type.
But you could use JFace which is an extension to SWT and try to use org.eclipse.jface.dialogs.MessageDialog API.
Here's my version: You don't hardcode your dialog size, rather make it variable on the user's screen size.
I've added my personal helper methods below, and demonstrated their usage.
This would be far more flexible than an OS MessageBox, but you're gonna have to add icons manually (oooooor I think you can even override MessageDialog instead of Dialog - your call)
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
/**
*
* #author stackoverflow.com/users/1774643/ggrec
*
*/
public class CustomMessageBox extends Dialog
{
// ==================== 1. Static Fields ========================
/*
* Default ratio values for big dialogs
*/
private static final double DEFAULT_DIALOG_WIDTH_SCREEN_PERCENTAGE = 0.63;
private static final double DEFAULT_DIALOG_HEIGHT_SCREEN_PERCENTAGE = 0.75;
// ==================== Static Helper Methods ====================
/**
* <pre>
* Very useful for dialogs. Resizes the dialog shell to a size proportional
* to the primary monitor bounds.
*
* <b>1920x1080 monitor && 0.63x0.75 ratios => 1400x800 shell</b>
*
* This means 63% of screen's width, and 75% of screen's height.
*
* The advantage of this method is that the dialog will always be proportional
* to the screen, no matter what the screen size is (e.g. big LG flat TV screen,
* or MacOS display).
* </pre>
*
* #param shell Dialog shell (e.g. the 'newShell' object in configureShell API from Dialog)
* #param widthRatio A percentage of current screen's size (i.e. smaller than 1, bigger than 0)
* #param heightRatio
*/
public static void resizeAndCenterShellOnScreen(final Shell shell, final double widthRatio, final double heightRatio)
{
final Display display = shell.getDisplay();
final Monitor primaryMonitor = display.getPrimaryMonitor();
final Rectangle monitorRect = primaryMonitor.getBounds();
// 1.) Resize the Shell
final int newWidth = (int) Math.floor(monitorRect.width * widthRatio);
final int newHeight = (int) Math.floor(monitorRect.height * heightRatio);
shell.setSize(newWidth, newHeight);
centerShellOnScreen(shell);
}
public static void centerShellOnScreen(final Shell shell)
{
final Rectangle shellBounds = shell.getBounds();
final Display display = shell.getDisplay();
final Monitor primaryMonitor = display.getPrimaryMonitor();
final Rectangle monitorRect = primaryMonitor.getBounds();
final int x = monitorRect.x + (monitorRect.width - shellBounds.width) / 2;
final int y = monitorRect.y + (monitorRect.height - shellBounds.height) / 2;
shell.setLocation(x, y);
}
// ==================== 3. Static Methods ====================
public static void main(final String[] args)
{
new CustomMessageBox().open();
}
// ==================== 4. Constructors ====================
public CustomMessageBox()
{
super(Display.getDefault().getActiveShell());
}
// ==================== 5. Creators ====================
#Override
protected Control createDialogArea(final Composite parent)
{
final Composite dialogArea = (Composite) super.createDialogArea(parent);
final Label label = new Label(dialogArea, SWT.NULL);
label.setText("YOLO");
label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
return dialogArea;
}
#Override
protected void configureShell(final Shell newShell)
{
super.configureShell(newShell);
resizeAndCenterShellOnScreen(newShell, DEFAULT_DIALOG_WIDTH_SCREEN_PERCENTAGE, DEFAULT_DIALOG_HEIGHT_SCREEN_PERCENTAGE);
}
}
Cheers.
I was asked by uni to create a 2d racing game in java.
we were told to use one jcomponent in a jframe.
we told to update the game by the swing timer and call repaint() somewhere appropriate in their.
I have now finished but all the way through my use of Graphics g was annoying me. for example below is my gameobject class that players and stuff derive from.
import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
/*
* Provides The basic functionality of Displaying a game object on the screen
* and methods able to change the image
*/
public class GameObject {
public Vector position = new Vector();
//image set up variables
protected BufferedImage[] buffImage;
protected ImageIcon icon = new ImageIcon();
protected int numberOfImages;
protected String filePrefix;
protected String fileExt;
//////////////interactive variables
//image
protected int imageNumber = 0;
public GameObject(int numOfImages, String filePre, String fileE)
{
//if this gives grief about constructors implement a custom initObject() method that can be overridden with super.
this.numberOfImages = numOfImages;
buffImage = new BufferedImage[numOfImages];
filePrefix = filePre;
fileExt = fileE;
}
//Adds images to array
protected void initImageArray()
{
for(int i = 0; i <numberOfImages; i++)
{
try{
buffImage[i] = (BufferedImage) ImageIO.read(new File(filePrefix + "/" + Integer.toString(i) + fileExt));
}
catch(Exception e)
{
System.out.println(e);
}
}
}
//Draws object to screen
public void draw(Graphics g, Component c){
icon.setImage(getNextImage());
icon.paintIcon(c, g, position.x, position.y);
}
//returns current image
protected BufferedImage getNextImage(){
return buffImage[imageNumber];
}
//
protected void increaseImageNumber(){
if(imageNumber < numberOfImages-1){
imageNumber++;
}
else{
imageNumber = 0;
}
}
protected void decreaseimageNumber(){
if(imageNumber > 0){
imageNumber--;
}else{
imageNumber = numberOfImages - 1;
}
}
}
The bit specifically i don't think im doing right is passing the same "Graphics g" parameter to every objects draw method. it works but when i tried to place 15 stars in the back ground and change their imageIcon image from one buffered image array to the next everything became very jarred. I put this down to sharing this one graphic class. It could also just be that we were told not to use a threaded solution but i think any new comp should be able to handle 17 images updating and changing. the update timer is at every 33 milliseconds.
Thank you to anyone who can help explain to me the best way to achieve what i was after or the proper use/sharing of the graphics object.
Having problems loading/showing an image in a java applet. Not sure if I'm loading the image incorrectly or if I'm accessing it incorrectly. Here's the code that draws the ship and the background(it's an asteroid-like game). The background draws correctly but the ship doesn't. This is the main class method that I'm dealing with:
public void paintFrame(Graphics g) {
Dimension d = size();
g.fillRect(0, 0, d.width, d.height);
g.drawImage(ship.getImage(), d.width/2, d.height/2, null);
}
I create an instance of the ship class at the beginning of the class. However, if I try to instantiate the ship class in a method (such as "Ship ship = new Ship();), it says the variable "ship" is never used.
Here's the entire ship class:
public class Ship {
private int dx;
private int dy;
private int x;
private int y;
private Image image;
public Ship() {
ImageIcon ii = new ImageIcon("ship1.png");
image = ii.getImage();
}
public Image getImage() {
return image;
}
}
If I run it as is, it runs without errors, but it doesn't display the ship. If I try to create the instance of the ship anywhere else except at the top, it gives me a NullPointerException.
Update
Here's my entire main class:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
public class RunGame extends Applet implements Runnable {
int frame;
int delay;
Thread animator;
Ship ship = new Ship();
Level level;
Dimension offDimension;
Image offImage;
Graphics offGraphics;
/**
* Initialize the applet and compute the delay between frames.
*/
public void init() {
String str = getParameter("fps");
int fps = (str != null) ? Integer.parseInt(str) : 10;
delay = (fps > 0) ? (1000 / fps) : 100;
}
/**
* Method is called when the applet becomes visible on
* the screen.
*/
public void start() {
animator = new Thread(this);
animator.start();
}
/**
* This method is called by the thread that was created in
* the start method. It does the main animation.
*/
public void run() {
// Remember the starting time
long tm = System.currentTimeMillis();
while (Thread.currentThread() == animator) {
// Display the next frame of animation.
repaint();
// Delay depending on how far we are behind.
try {
tm += delay;
Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
// Advance the frame
frame++;
}
}
/**
* This method is called when the applet is no longer
* visible. Set the animator variable to null so that the
* thread will exit before displaying the next frame.
*/
public void stop() {
animator = null;
offImage = null;
offGraphics = null;
}
/**
* Update a frame of animation.
*/
public void update(Graphics g) {
Dimension d = size();
// Create the offscreen graphics context
if ((offGraphics == null) || (d.width != offDimension.width) || (d.height != offDimension.height)) {
offDimension = d;
offImage = createImage(d.width, d.height);
offGraphics = offImage.getGraphics();
}
// Erase the previous image
offGraphics.setColor(getBackground());
offGraphics.fillRect(0, 0, d.width, d.height);
offGraphics.setColor(Color.black);
// Paint the frame into the image
paintFrame(offGraphics);
// Paint the image onto the screen
g.drawImage(offImage, 0, 0, null);
}
/**
* Paint the previous frame (if any).
*/
public void paint(Graphics g) {
if (offImage != null) {
g.drawImage(offImage, 0, 0, null);
}
}
/**
* Paint a frame of animation.
*/
public void paintFrame(Graphics g) {
Dimension d = size();
g.fillRect(0, 0, d.width, d.height);
//g.drawImage(level.getImage(), 0, 0, null);
g.drawImage(ship.getImage(), 400, 300, null);
}
}
ImageIcon ii = new ImageIcon("ship1.png");
The ImageIcon constructor that accepts a String presumes the string represents ..
..a file name or a file path.
'Applets and files do not mix.' Only a trusted applet can load a File object, and even then, only from the file system of the end user. The File objects cannot point back to the server.
Applets would more typically work with paths formed from an URL. The Applet class provides a number of methods to help form that URL, and the ImageIcon constructor is overloaded to accept an URL.
..Not sure if I'm loading the image incorrectly or if I'm accessing it incorrectly.
Debugging 101 is to display the image immediately after loading it. Drop the image icon into a label and use a JOptionPane to show the label.
Without seeing your full code we can't really tell what's going on with the exception, but in your call to drawImage() specify 'this' as the last parameter instead of null. Images are loaded asynchronously and so they need something that implements ImageObserver (such as your frame) to tell when they have managed to load a bit more (or all of it) - so that they can repaint.