I am coding a game in Java. The first screen is the begin screen. On a mouse click, the screen is supposed to switch to a screen that lets you choose a character. Then, the next screen is the first game question. The character choosing screen isn't coming. It is just going to the first question. drawq is the boolean that determines if the question has been drawn. I had initialized it to false in the beginning of my code. Here is my mouselistener method, please help me find a way to get the screen that displays "Choose your character" and the image of the girl.
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
//background image
g.drawImage(theme.getImage(),0,0,WIDTH,HEIGHT,null);
//Choosing character screen
g.drawString("Choose your character", WIDTH-1550, HEIGHT/6);
g.drawImage(girl.getImage(),WIDTH-1550,HEIGHT/2,237,338,null);
//switching drawq to false
drawq=true;
//draw next question on mouse click
if(drawq==true) {
questions[whichquestion].draw(g);
drawq=false;
repaint();
}
It seems like you have got the order of your code mixed up, you set drawq to true and then immediately afterwards check if it's true, which will obviously always result in the if clause beeing run.
There are tons of tutorials for developing games on Java. Also here on SO there are many questions and answers. Just take a look at one or the other and let yourself be inspired.
An example of mouse input and screen output:
public class Main extends JPanel{
private int clicks = 0;
private Random rnd = new Random();
public static void main(String[] args){
var frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setContentPane(new Main());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
public Main(){
addMouseListener(new MouseInputAdapter(){
#Override
public void mouseClicked(MouseEvent e){
clicks = e.getClickCount();
repaint();
}
});
setPreferredSize(new Dimension(640, 480));
repaint();
}
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
g.drawString("Click your Mousebutton! One, two, three times or more ;-)", 20, 20);
if(clicks > 0) {
g.drawString("Clicks counted: " + clicks, 20, 40);
for(int i = 0; i < clicks; i++){
g.setColor(new Color(rnd.nextInt(256),rnd.nextInt(256),rnd.nextInt(256),255));
g.drawLine(20, 60 + i * 10, 100 + i * 20, 60 + i * 10);
}
}
}
}
I suggest that you go back to the drawing board. You should create a JFrame subclass that has a JLabel and a JImage on it. Then when the user clicks the button, just show that JFrame.
In gneeral, don't use a Graphics object outside of paintComponent(). And don't use drawImage() or drawText() unless you have a good reason. In this case, a JLabel and a JImage are much more appropriate for implementing the elements in the screen.
Related
I am trying to draw a car as a polygon in swing and move it left and right when clicking button
The problem is that I can't display the buttons on the screen when running the program and can't make them works
And I Don't know how implement the buttons inside of the user interface when using polygon
Here is my code:-
package java2d;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Java2D extends JFrame{
int xValues[];
int yValues[];
private JButton Right, Left;
public Java2D() {
super( "Drawing lines, rectangles and ovals" );
setSize( 500, 300 );
setVisible( true );
}
public void paint( Graphics g ) {
int xValues[] = { 40, 100, 130, 230, 260, 320, 320, 40 };
int yValues[] = { 120, 120, 40, 40, 120, 120, 170, 170 };
Polygon polygon1 = new Polygon( xValues, yValues, 8 );
g.setColor(Color.blue);
g.drawPolygon( polygon1 );
Right = new JButton("Right");
Left = new JButton("Left");
Right.setSize(50, 50);
Left.setSize(50, 50);
Right.setLocation(100, 200);
Left.setLocation(200, 200);
g.add(Right);
g.add(Left);
}
public void actionPerformed(ActionEvent event) {
if(event.getActionCommand().equals("Right")){
for (int i=0; i<xValues.length;i++) {
xValues[i] = xValues[i] + 10;
yValues[i] = yValues[i] + 10;
}
}
if(event.getActionCommand().equals("Left")){
for (int i=0; i<xValues.length;i++) {
xValues[i] = xValues[i] + 10;
yValues[i] = yValues[i] + 10;
}
}
repaint();
}
public static void main(String[] args) {
Java2D application = new Java2D();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
}
THANKS
Many issues:
Variable names should NOT start with an upper case character.
Custom painting is done by overriding the paintComponent() method of a JPanel and then you add the panel to the frame. Read the section from the Swing tutorial on Custom Painting for more information and working examples to get you started. Start with the working code and modify it for your requirement.
Never create Swing components in a painting method. The painting method is continually invoked when Swing determines the component needs to be repainted, so you don't want to keep creating new buttons.
Typically to add buttons to the frame you would create a JPanel and add the buttons to the panel. Then you add the panel to the frame using frame.add(buttonsPanel, BorderLayout.PAGE_START). Then you would add your painting panel to the frame using frame.add(paintingPanel, BorderLayout.CENTER). Read the section from the Swing tutorial on Layout Managers for more information and examples.
Instead of attempting to update the values of the Arrays used to create the Polygon you should be using the translate() method of the Polygon.
Keep a reference to the Swing tutorial handy as it contains examples for most Swing basics.
I'm in a rut trying to program a traffic lights simulation for my Intro to Programming in Java course. When I run the applet, all three lights are still lit up even though I haven't clicked any of the JButtons yet. When I do, the applet does turn blank momentarily like it's doing something, and if I press GO, the car does move. I'm wondering if I need to reset the colors in the graphics class, or use switch statements (which I'm not really certain how to do) and begin with a color as I've seen in other examples. Is there anything incorrect in my code that's hindering me from getting the results I want? Any help would be greatly appreciated. Thank you.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/**
* Class TrafficLights - At the click of a button, change the traffic lights
*
* #author Mickey Mouse
* #version JDK 8
* #course CSCI 1130-01
* #date 10-2-15
*/
public class TrafficLights extends JApplet implements ActionListener {
private JButton WAIT, STOP, GO;
private boolean clickWAIT = false;
private boolean clickSTOP = false;
private boolean clickGO = false;
private int carX = 200;
/**
* Called by the browser or applet viewer to inform this JApplet that it
* has been loaded into the system. It is always called before the first
* time that the start method is called.
*/
public void init()
{
setLayout( new FlowLayout()); // changes the layout from BorderLayout to FlowLayout
WAIT = new JButton ("WAIT"); //adds WAIT label to button
WAIT.setForeground(Color.yellow); //changes the label to yellow
//adds the WAIT JButton to the screen
add (WAIT);
WAIT.addActionListener(this);
GO = new JButton ("GO"); //adds GO label to button
GO.setForeground(Color.green); //changes the label to green
//adds the button to the screen
add (GO);
GO.addActionListener(this);
STOP = new JButton ("STOP"); //adds STOP label to button
STOP.setForeground(Color.red); //changes the label to red
//adds STOP JButton to screen
add (STOP);
STOP.addActionListener(this);
}
/**
* Called by the browser or applet viewer to inform this JApplet that it
* should start its execution. It is called after the init method and
* each time the JApplet is revisited in a Web page.
*/
public void start()
{
// provide any code requred to run each time
// web page is visited
}
/**
* Called by the browser or applet viewer to inform this JApplet that
* it should stop its execution. It is called when the Web page that
* contains this JApplet has been replaced by another page, and also
* just before the JApplet is to be destroyed.
*/
public void stop()
{
// provide any code that needs to be run when page
// is replaced by another page or before JApplet is destroyed
}
/**
* Paint method for applet.
*
* #param g the Graphics object for this applet
*/
public void paint(Graphics g)
{
super.paint(g);
//declares and retrieves the images from their file locations
Image img = getImage(getDocumentBase(), "stoplights.png");
Image img2 = getImage(getDocumentBase(), "car.jpg");
g.drawImage( img, 50, 100, 300, 350, 0, 0, 5000, 5000, this ); //draws and resizes the stoplights image
g.drawImage( img2, carX, 400, 1000, 1000, 0, 0, 5000, 5000, this); //draws and resizes the car image
//draw and fill an oval red for the STOP stoplight when STOP is pressed
if (clickSTOP == true);
{
g.drawOval(63, 112, 30, 30);
g.setColor(Color.red);
g.fillOval(63, 112, 30, 30);
clickSTOP = false;
}
//draw and fill an oval yellow for the WAIT stoplight when WAIT is pressed
if (clickWAIT == true);
{
g.setColor(Color.black);
g.drawOval(63, 148, 30, 30);
g.setColor(Color.orange);
g.fillOval(63, 148, 30, 30);
clickWAIT = false;
}
//draw and fill an oval green for the GO stoplight when GO is pressed
if (clickGO == true);
{
g.setColor(Color.black);
g.drawOval(63, 184, 30, 30);
g.setColor(Color.green);
g.fillOval(63, 184, 30, 30);
clickGO = false;
}
}
public void actionPerformed(ActionEvent event)
{
/*
* Links the JButtons and the graphic sequences to display the lights
*
*/
if(event.getSource() == GO) //display green if GO is clicked
{
clickGO = true;
carX -=15;
repaint();
}
if (event.getSource() == WAIT) //display yellow if WAIT is clicked
{
clickWAIT = true;
repaint();
}
if (event.getSource() == STOP) //display red if STOP is clicked
{
clickSTOP = true;
repaint();
}
}
/**
When I run the applet, all three lights are still lit up even though I haven't clicked any of the JButtons yet
This is because you have a ; after each of your if statements, which is basically short circuiting your logic, so the code following it, is always executed, regardless of the state of the variable...
if (clickSTOP == true);
So, instead, you should be using something more like
if (clickSTOP == true)
{
g.setColor(Color.red);
g.fillOval(63, 112, 30, 30);
clickSTOP = false;
}
You are also modifying the state of the program from within you paint method, this is generally discouraged, as paint should just do that, paint the current state.
The better place to change the state is in the ActionListener.
Rather then having three state variables, which are generally describing the same thing, you should have a single state variable, so the state can only ever be go or wait or stop, never a combination of all three.
Equally, you could use a ButtonGroup and JToggleButtons or JRadioButtons, this would allow the buttons to carry a certain amount of the information about the state, as only only button could be selected at a time.
Have a look at How to Use the ButtonGroup Component and How to Use Buttons, Check Boxes, and Radio Buttons for more details
When I do, the applet does turn blank momentarily like it's doing something
This could be caused by the fact that you are loading images from within the paint method, but as a general rule, you should avoid overriding paint of top level containers like this.
I am developing a simple game where have to write words. So I taught to make a TextArea where the words typed goes, to this I need a scroll to can see all words. But i have a render method that have this:
public void onRender(Graphics2D g) {
g.drawImage(imgBG, 0,0, null); //draws my background
g.setColor(Color.WHITE);
g.setFont(titulo);
g.drawString("Type the Word!", 260, 240);
g.setColor(Color.darkGray);
for(int i=0;i < wordFind.length();i++)
{
g.fillRect(inicioTraco+(60*i),yTraco,40,10);
}
if(tag_s == true)
{
tag_s = false;
g.setFont(titulo);
g.drawString("s",posicao, 100);
}
this.getMainWindow().add(new JTextArea("Test",10,20));
}
getMainWindow is a method that return my main JFrame, and i put this JTextArea to show the words.
But it is not appearing in my game.
I taught to make a white rect (fillrect) but it will not have scoll.
So I don't know what to do. Can someone clear my mind?
thanks.
I need a certain image to be redrawn at different locations constantly as the program runs. So I set up a while loop that should move an image across the screen, but it just redraws the image on top of itself over and over again. What am I doing wrong? Is there a way to delete the old image before drawing it in a new location?
JFrame frame = buildFrame();
final BufferedImage image = ImageIO.read(new File("BeachRoad_double_size.png"));
JPanel pane = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int num = 0;
boolean fluff = true;
while (fluff == true) {
num = num + 1;
g.drawImage(image, num, 0, null);
if (num == 105) {
fluff = false;
}
}
}
};
frame.add(pane);
You can't code a loop in the paintComponent() method. The code will execute so fast that the image will only be painted in the final position, which in your case should be with an x position of 105.
Instead you need to use a Swing Timer to schedule the animation every 100 milliseconds or so. Then when the timer fires you update the x position and invoke repaint() on the panel. Read the Swing tutorial on Using Swing Timers for more information.
Putting a while loop inside a paintComponent method is not the way to do it. Instead, there should be some setup like the following:
...
final int num = 0;
final JPanel pane;
Timer timer = new Timer(10, new ActionListener() {
public void actionPerformed(ActionEvent e) {
num++;
pane.repaint();
}
});
pane = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, num, 0, null);
}
});
timer.start();
This will move the image ever 10 milliseconds, as specified in the Timer constructor.
This is a common issue people starting out in animation have, as I did. You can't 'remove an image' from the screen. However, you can repaint the entire screen, then redraw your image at a new location.
In psuedocode:
while (condition)
background(white); //or whatever color your background is
drawImage(x,y);
The code above clears the screen so it's safe for you to redraw your image. This effectively 'deletes' your image.
Edit: I didn't read your code, I just addressed your question. So other answers that fix your code are probably better than mine.
I'm attempting to create my own custom ToolTip for a program I've ported to Java, I'm trying to match the original programs ToolTips (it was written in Delphi). I've got some code that allows me to draw "inside" a ToolTip but for some reason, if I Override paint(Graphics g, JComponent c) and leave it blank it still draws a ToolTip, and anything I attempt to draw will be drawn "inside" this little boxed ToolTip and I can't draw "outside" of it.
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicToolTipUI;
class MultiLineToolTipUI extends BasicToolTipUI {
#Override
public void paint(Graphics g, JComponent c) {
//int mY = 0;
//int mX = 0;
//int xPoints[] = {mX, mX, mX + 15};
//int yPoints[] = {mY, mY + 25, mY + 25};
//Polygon p = new Polygon(xPoints, yPoints, 3);
//g.setColor(Color.BLACK);
//g.fillPolygon(p);
//g.fillRoundRect(mX, mY, 100, 50, 30, 30);
}
public static void main (String args[])
{
JButton button = new JButton ("Mouse Over ME!") {
public JToolTip createToolTip() {
MultiLineToolTip tip = new MultiLineToolTip();
tip.setComponent(this);
return tip;
}
};
//JButton button = new JButton("Mouse Over ME!");
button.setToolTipText("Hello, World");
JFrame frame = new JFrame("Basic SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( button );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
static class MultiLineToolTip extends JToolTip
{
public MultiLineToolTip()
{
setUI(new MultiLineToolTipUI());
}
}
}
This is what I have, and like I said, even without the lines in paint it's drawing on it's own.
Any advice to get around this? Or a better way to go about what I'm trying to do?
CLARIFICATION: The first answer by Camickr was very helpful, however I should clarify my goal is to get the box that is automatically drawn from somewhere outside of paint to go away, or be invisible.
The size of the tool tip is determined by the text. Add:
System.out.println( c.getSize() );
to the paint(...) method to see the size of the tool tip. You are trying to paint outside its bounds. If you want to override the default size then you need to set the preferred size yourself. I think you want:
public Dimension getPreferredSize(JComponent c)
{
return new Dimension(100, 50);
}
Edit: A tooltip is a component with a border and a background. If you want to remove them you can use:
tip.setOpaque(false);
tip.setBorder(new javax.swing.border.EmptyBorder(0, 0, 0, 0));
This will only work when to tooltip is fully contained withing the frame. When the tooltip is displayed outside the bounds of the frame, then the tooltip is added to a JWindow, in which case you will see the background of the window. I don't know how to disable this behaviour because all Swing components must be painted within the bounds of a top level container.