This question already has answers here:
Show an animated BG in Swing
(3 answers)
Closed 6 years ago.
im making a mathematical game and want to use a gif as a background. Its dimensions are 1100*800
I searched many posts how to add a GIF as background, but with no success. Any suggestions for a easy method (if using other components -JPanel,...; could you please show how?)
So far, this is my code of the JFrame:
public class Game extends JFrame implements ActionListener {
private JButton play, endG, tutorial, login, easy, medium, hard, next, checkAnswer;
private JTextArea answer;
int total, goodAnswer = 0;
public Game(String heading) {
super(heading);
this.setSize(1100, 800);
this.setLayout(null);
firstScreen();
setResizable(false);
}
public void firstScreen() {
getContentPane().removeAll();
play = new JButton();
play.setBounds(373, 350, 354, 80);
play.setIcon(new ImageIcon("entrancePlayButton.png"));
play.addActionListener(this);
play.setOpaque(false);
play.setContentAreaFilled(false);
add(play);
tutorial = new JButton("Tutorial");
tutorial.setBounds(345, 520, 150, 50);
tutorial.setFont(new Font("Arial", Font.PLAIN, 20));
tutorial.addActionListener(this);
tutorial.setOpaque(false);
tutorial.setContentAreaFilled(false);
add(tutorial);
endG = new JButton("End Game");
endG.setBounds(605, 520, 150, 50);
endG.setFont(new Font("Arial", Font.PLAIN, 20));
endG.addActionListener(this);
endG.setOpaque(false);
endG.setContentAreaFilled(false);
add(endG);
revalidate();
repaint();
}
public void difficultyScreen() {
getContentPane().removeAll();
easy = new JButton("Easy");
easy.setBounds(450, 310, 200, 80);
easy.setFont(new Font("Arial", Font.PLAIN, 30));
easy.addActionListener(this);
easy.setOpaque(false);
easy.setContentAreaFilled(false);
add(easy);
medium = new JButton("Medium");
medium.setBounds(450, 440, 200, 80);
medium.setFont(new Font("Arial", Font.PLAIN, 30));
medium.addActionListener(this);
medium.setOpaque(false);
medium.setContentAreaFilled(false);
add(medium);
hard = new JButton("Hard");
hard.setBounds(450, 570, 200, 80);
hard.setFont(new Font("Arial", Font.PLAIN, 30));
hard.addActionListener(this);
hard.setOpaque(false);
hard.setContentAreaFilled(false);
add(hard);
endG = new JButton("Exit");
endG.setBounds(1000, 700, 60, 30);
endG.setFont(new Font("Arial", Font.PLAIN, 15));
endG.addActionListener(this);
endG.setOpaque(false);
endG.setContentAreaFilled(false);
add(endG);
revalidate();
repaint();
}
public void playGameScreen() {
getContentPane().removeAll();
revalidate();
repaint();
}
public void tutorialScreen() {
getContentPane().removeAll();
revalidate();
repaint();
}
private static double stringToDouble(String number) {
double num = Double.parseDouble(number);
return num;
}
public static void main() {
Game areaGame = new Game("Area Game");
areaGame.setVisible(true);
}
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == play) {
difficultyScreen();
}
if (actionEvent.getSource() == tutorial) {
tutorialScreen();
}
if (actionEvent.getSource() == endG) {
int reply = JOptionPane.showConfirmDialog(null, "You are about to exit the game, are you sure?", "Exit game", JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
}
}
There are two ways to do this:
you can override the paintComponent() method of your JPanel.
like this:
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(yourImage, 0, 0, this);
}
or you can use a JLabel by loading the image as an ImageIcon and then displaying it in a JLabel.
Related
I have a Jlabel called status that is empty. When I do status.setText() the first time it works normally but when I change it again it overlaps the first change instead of replacing it like it should. What is going on?
package panda.org;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.Math;
public class NumberGame implements ActionListener{
JFrame frame;
JLabel rules;
JLabel rulesText;
JLabel rulesText2;
JLabel lets;
JButton play;
JButton exit;
JPanel panel;
Font myFont = new Font("Serif Plain", Font.BOLD, 15);
NumberGame() {
frame = new JFrame("NumberGame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 500);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setResizable(true);
Image icon = Toolkit.getDefaultToolkit().getImage("C:\\Users\\Gaming MSI\\Pictures\\Saved Pictures\\download (1).png");
frame.setIconImage(icon);
rules = new JLabel("Rules: ");
rules.setFont(myFont);
rules.setBounds(50, 100, 100, 75);
rulesText = new JLabel("We will pick a random number in the range of 1 -> 50.");
rulesText.setBounds(100, 100, 315, 75);
rulesText2 = new JLabel("Your job is to guess that number!");
rulesText2.setBounds(100, 120, 315, 75);
play = new JButton("Play");
play.setBounds(150, 300, 100, 75);
play.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int failedAttempts = 0;
JLabel label = new JLabel("Guess the number from 1 till 50");
label.setFont(myFont);
label.setBounds(150, 75, 315, 75);
JLabel hints = new JLabel("");
JTextField text = new JTextField();
text.setBounds(250, 150, 100, 25);
JButton check = new JButton("Check");
check.setBounds(150, 150, 75, 25);
double randomDouble = Math.random();
randomDouble = randomDouble * 50 + 1;
int randomInt = (int) randomDouble;
double finalRandomDouble = randomDouble;
check.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(randomInt);
String nb = text.getText();
int change = Integer.parseInt(nb);
JLabel status = new JLabel("");
status.setBounds(150, 160, 1000, 100);
frame.add(status);
if(randomInt == change) {
status.setText("You chose the correct number!");
status.setForeground(Color.green);
}
if(randomInt != change) {
status.setText("Wrong choice! Try again.");
status.setForeground(Color.red);
}
}
});
rules.setText("");
rulesText.setText("");
rulesText2.setText("");
frame.add(hints);
frame.add(label);
frame.add(check);
frame.add(text);
}
});
exit = new JButton("Exit");
exit.setBounds(350, 300, 100, 75);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(frame,"Are you sure want to exit?", "Exit",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if(result == JOptionPane.YES_OPTION){
System.exit(0);
}else if (result == JOptionPane.NO_OPTION){
}else {
}
}
});
frame.add(play);
frame.add(exit);
frame.add(rules);
frame.add(rulesText);
frame.add(rulesText2);
frame.setVisible(true);
}
public static void main(String[] args) {
NumberGame number = new NumberGame();
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Someone asked for more code so this is all of my code! I hope this helps :D
The problem is in these lines
if(randomInt == change) {
status.setText("You chose the correct number!");
status.setForeground(Color.green);
}
if(randomInt != change) {
status.setText("Wrong choice! Try again.");
status.setForeground(Color.red);
}
}
This is how the result appears:
There are some improvements to do in your code:
You're using null-layout and setBounds(...) which is not advised it will give you more headaches than solutions, it may seem like the best / easiest way to build complex GUIs but it's not, here's an example of why. Swing has to deal with multiple OS, PLAFs, screen sizes and resolutions, let the layout managers do that work for you, all you have to do is combine them.
Every time you call check.addActionListener(new ActionListener() {, you're creating a new instance of your JLabel named status, and because you're using null-layout and you're placing it in the same position, they're overlapping.
Follow the first advice given in this answer, rebuild the whole thing with layout managers, move the status label as a class member and you shouldn't have any problems.
try this:
if(randomInt == change) {
status.setText("You chose the correct number!");
status.setForeground(Color.green);
}else{
status.setText("Wrong choice! Try again.");
status.setForeground(Color.red);
}
This is a simple class I would like to add to an applet, but how do I do it?
These are the variables being used:
int force = 1;
int distance = 50/force;
int x = distance*60;
int WIDTH = 300 - x;
This is the paint method:
public void paint(Graphics g){
g.setColor(Color.GRAY);
g.drawString("Use the buttons to control the input force", 100, 25);
g.fillRect(300, 250, 300, 25);
g.fillRect(x, 250, WIDTH, 25);
If I should change what method these buttons are located in, please tell me. (Currently are in the paint method)
JButton subtract = new JButton("-");
JButton add = new JButton("+");
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
force++;
}
});
subtract.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
force--;
}
});
add.setSize(50, 25);
subtract.setSize(50, 25);
if(force<=0){
force =1 ;
}
add.setLocation(0,0);
subtract.setLocation(51, 0);
LApplet app = new LApplet();
app.add(add);
app.add(subtract);
app.setBackground(Color.BLACK);
}}
I am trying to simulate a traffic light with radio buttons. No matter where I put the call to repaint(), it does not seem to call the paintComponent method. Any help would be appreciated. Here is my code. Sorry if this is kind of long.
package trafficlight;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.event.*;
public class Frame extends JFrame{
Drawing ob = new Drawing();
private JPanel buttonPanel;
private JRadioButton red;
private JRadioButton yellow;
private JRadioButton green;
public Frame(String title, int width, int height) {
super(title);
setSize(width, height);
buttonPanel = new JPanel();
//creating JFrame components
red = new JRadioButton("Red");
yellow = new JRadioButton("Yellow");
green = new JRadioButton("Green");
buttonPanel.add(red);
buttonPanel.add(yellow);
buttonPanel.add(green);
//JRadioButton group allows only one button to be selected at a time
ButtonGroup group = new ButtonGroup();
group.add(red);
group.add(yellow);
group.add(green);
//adding components to frame
add(buttonPanel, BorderLayout.SOUTH);
//Adding action listeners
red.addActionListener(new Listener());
yellow.addActionListener(new Listener());
green.addActionListener(new Listener());
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//Listener class to handle action events
private class Listener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
if(red.isSelected()){
ob.setRed(true);
ob.setYellow(false);
ob.setGreen(false);
ob.repaint();
}
else if(yellow.isSelected()){
ob.setYellow(true);
ob.setGreen(false);
ob.setRed(false);
ob.repaint();
}
else if(green.isSelected()){
ob.setGreen(true);
ob.setYellow(false);
ob.setRed(false);
ob.repaint();
}
}
}
}
Here is my seconds class
package trafficlight;
import java.awt.*;
import javax.swing.*;
public class Drawing extends JPanel{
private boolean red = false;
private boolean yellow = false;
private boolean green = false;
public void setRed(boolean clicked){
this.red = clicked;
}
public void setYellow(boolean clicked){
this.yellow = clicked;
}
public void setGreen(boolean clicked){
this.green = clicked;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawRect(85, 20, 60, 110);
if(!red){
g.setColor(Color.black);
g.drawOval(100, 25, 30, 30);
}
else{
g.setColor(Color.red);
g.fillOval(100, 25, 30, 30);
}
if(!yellow){
g.setColor(Color.black);
g.drawOval(100, 60, 30, 30);
}
else{
g.setColor(Color.yellow);
g.fillOval(100, 60, 30, 30);
}
if(!green){
g.setColor(Color.black);
g.drawOval(100, 95, 30, 30);
}
else{
g.setColor(Color.green);
g.fillOval(100, 95, 30, 30);
}
}
}
And here's the main method
package trafficlight;
public class TrafficLight {
public static void main(String[] args) {
Frame test = new Frame("TrafficLight", 250, 250);
test.add(new Drawing());
}
}
Some improvements for your code
Don't inherit from JFrame. You don't add any value to this class (composition over inheritance)
Your ActionListener doesn't need to be a named class because it hasn't got any state
No need for a field in your case
Use the Color constants with the UPPERCASE i.e. Color.BLACK
Enqueue Swing application in the EDT
Use more descriptive names for classes and variables
Then your program may look like this:
public class TrafficLightUI {
public TrafficLightUI(String title, int width, int height) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
JRadioButton redRadioButton = new JRadioButton("Red");
JRadioButton yellowRadioButton = new JRadioButton("Yellow");
JRadioButton greenRadioButton = new JRadioButton("Green");
buttonPanel.add(redRadioButton);
buttonPanel.add(yellowRadioButton);
buttonPanel.add(greenRadioButton);
//JRadioButton group allows only one button to be selected at a time
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(redRadioButton);
buttonGroup.add(yellowRadioButton);
buttonGroup.add(greenRadioButton);
TrafficLightPanel trafficLight = new TrafficLightPanel();
//adding components to frame
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
mainPanel.add(trafficLight, BorderLayout.CENTER);
//Adding action listeners
redRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(true, false, false, trafficLight);
}
});
yellowRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(false, true, false, trafficLight);
}
});
greenRadioButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setTrafficLight(false, false, true, trafficLight);
}
});
frame.add(mainPanel);
frame.setVisible(true);
}
private void setTrafficLight(boolean red, boolean yellow, boolean green, TrafficLightPanel trafficLight) {
trafficLight.setGreen(green);
trafficLight.setYellow(yellow);
trafficLight.setRed(red);
trafficLight.repaint();
}
}
TrafficLightPanel
public class TrafficLightPanel extends JPanel {
private static final long serialVersionUID = 1L;
private boolean red = false;
private boolean yellow = false;
private boolean green = false;
public void setRed(boolean isRed) {
this.red = isRed;
}
public void setYellow(boolean isYellow) {
this.yellow = isYellow;
}
public void setGreen(boolean isGreen) {
this.green = isGreen;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawRect(85, 20, 60, 110);
if (!red) {
g.setColor(Color.BLACK);
g.drawOval(100, 25, 30, 30);
} else {
g.setColor(Color.RED);
g.fillOval(100, 25, 30, 30);
}
if (!yellow) {
g.setColor(Color.BLACK);
g.drawOval(100, 60, 30, 30);
} else {
g.setColor(Color.YELLOW);
g.fillOval(100, 60, 30, 30);
}
if (!green) {
g.setColor(Color.BLACK);
g.drawOval(100, 95, 30, 30);
} else {
g.setColor(Color.GREEN);
g.fillOval(100, 95, 30, 30);
}
}
}
Main
public class TrafficLight {
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TrafficLightUI("TrafficLight", 250, 250);
}
});
}
}
I seem to be unable to move any objects I bring into my class, my other classes seem to be functional when I set bounds, but not this one.
I'm wondering why it isn't working and functionally like my other classes.
Some of the bounds are extreme as that's me making sure I can notice if any of the objects are moving; which they are not.
package student.information.in.java;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.sql.*;
public class CreatedBy extends JFrame {
JButton btnJoelHogg, btnAndrewCameron, btnConorElliman, btnTiarnanByrne, btnproject;
JLabel lblJoel, lblAndrew, lblConor, lblTiarnan, lbl_title, lbl_Info;
public CreatedBy() {
super("Project team and information");
setLayout(null);
lbl_title = new JLabel("Information about the system & its creators", JLabel.CENTER);
add(lbl_title);
lbl_title.setBounds(200, 200, 200, 200);
lbl_title.setFont(new Font("Calibri", Font.PLAIN, 30));
lbl_title.setForeground(Color.BLACK);
lblJoel = new JLabel("Joel Hogg");
add(lblJoel);
lblJoel.setBounds(30, 140, 200, 30);
lblJoel.setFont(new Font("Calibri", Font.PLAIN, 14));
lblJoel.setForeground(Color.BLACK);
btnJoelHogg = new JButton("About Joel");
btnJoelHogg.setFont(new Font("Calibri", Font.PLAIN, 14));
btnJoelHogg.setBackground(Color.LIGHT_GRAY);
btnJoelHogg.setForeground(Color.BLACK);
lblAndrew = new JLabel("Andrew Cameron");
add(lblAndrew);
lblAndrew.setBounds(80, 50, 400, 30);
lblAndrew.setFont(new Font("Calibri", Font.PLAIN, 14));
lblAndrew.setForeground(Color.BLACK);
btnAndrewCameron = new JButton("About Andrew");
btnAndrewCameron.setFont(new Font("Calibri", Font.PLAIN, 14));
btnAndrewCameron.setBackground(Color.LIGHT_GRAY);
btnAndrewCameron.setForeground(Color.BLACK);
lblJoel = new JLabel("Conor Elliman");
add(lblJoel);
lblJoel.setBounds(20, 540, 170, 380);
lblJoel.setFont(new Font("Calibri", Font.PLAIN, 14));
lblJoel.setForeground(Color.BLACK);
btnConorElliman = new JButton("About Conor");
btnConorElliman.setFont(new Font("Calibri", Font.PLAIN, 14));
btnConorElliman.setBackground(Color.LIGHT_GRAY);
btnConorElliman.setForeground(Color.BLACK);
lblTiarnan = new JLabel("TiarnĂ¡n");
add(lblTiarnan);
lblTiarnan.setBounds(202, 506, 170, 30);
lblTiarnan.setFont(new Font("Calibri", Font.PLAIN, 14));
lblTiarnan.setForeground(Color.BLACK);
btnTiarnanByrne = new JButton("About TiarnĂ¡n");
btnTiarnanByrne.setFont(new Font("Calibri", Font.PLAIN, 14));
btnTiarnanByrne.setBackground(Color.LIGHT_GRAY);
btnTiarnanByrne.setForeground(Color.BLACK);
Container c = getContentPane();
FlowLayout fl = new FlowLayout(FlowLayout.LEFT);
c.setLayout(fl);
c.add(btnJoelHogg);
c.add(btnAndrewCameron);
c.add(btnConorElliman);
c.add(btnTiarnanByrne);
ButtonHandler handler = new ButtonHandler();
btnJoelHogg.addActionListener(handler);
btnAndrewCameron.addActionListener(handler);
btnConorElliman.addActionListener(handler);
btnTiarnanByrne.addActionListener(handler);
setSize(600, 400);
show();
}
public static void main(String[] args) {
// Make frame
CreatedBy f = new CreatedBy();
f.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("Exit via windowClosing.");
System.exit(0);
}
}
);
} // end of main
// inner class for button event handling
private class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnJoelHogg) {
System.out.println(
"Joel Hogg button pressed");
}
if (e.getSource() == btnAndrewCameron) {
System.out.println(
"Andrew Cameron button pressed");
}
if (e.getSource() == btnTiarnanByrne) {
System.out.println("Tiarnan Byrne button pressed");
}
if (e.getSource() == btnConorElliman) {
System.out.println("Conor Elliman button pressed");
}
}
} // end of inner class
} // end of outer class
I want to change the input in the textfield which will instantly update to the display, instead of press ENTER button to update it.
Here is my code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyProgram01 extends JFrame
{
private JTextField text1;
private JCheckBox check1;
private JCheckBox check2;
private String message;
private JLabel label1;
private JLabel label2;
private Font font;
public MyProgram01(String title)
{
super(title);
check1 = new JCheckBox("Bold");
check2 = new JCheckBox("Italics");
label1 = new JLabel("Text : ");
label2 = new JLabel("Style : ");
message = "Good Morning...";
text1 = new JTextField(message, 100);
font = new Font("Times New Roman", Font.PLAIN, 36);
setBounds(0, 0, 600, 300);
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setBounds(0, 0, 600, 120);
panel.setBackground(Color.ORANGE);
label1.setFont(new Font("Times New Roman", Font.PLAIN, 36));
label1.setBounds(15, 15, 100, 36);
panel.add(label1);
text1.setBounds(120, 15, 400, 36);
panel.add(text1);
label2.setFont(new Font("Times New Roman", Font.PLAIN, 36));
label2.setBounds(15, 65, 100, 36);
panel.add(label2);
check1.setBounds(120, 65, 100, 36);
check2.setBounds(220, 65, 100, 36);
panel.add(check1);
panel.add(check2);
check1.addActionListener(new CheckBoxListener());
check2.addActionListener(new CheckBoxListener());
text1.addActionListener(new TextFieldListener());
setLayout(null);
add(panel);
}
public void paint(Graphics g)
{
super.paint(g);
g.setFont(font);
g.drawString(message, 15, 255);
}
private class CheckBoxListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(check1.isSelected() && check2.isSelected())
{
font = new Font("Times New Roman", Font.BOLD + Font.ITALIC, 36);
repaint();
}
else if(check1.isSelected())
{
font = new Font("Times New Roman", Font.BOLD, 36);
repaint();
}
else if(check2.isSelected())
{
font = new Font("Times New Roman", Font.ITALIC, 36);
repaint();
}
else
{
font = new Font("Times New Roman", Font.PLAIN, 36);
repaint();
}
}
}
private class TextFieldListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
message = text1.getText();
repaint();
}
}
public static void main(String[] args)
{
JFrame frame = new MyProgram01("My Program 01");
frame.setVisible(true);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
How can I change the code to instantly update to the display?
EDIT :
It's work with the keyListener, but my program will only start display after second key is pressed.
For example, I key in abc, the program will start show a when I press b, and when I pressed c, it displays ab and c is missing, unless I press ENTER.
Here the part of the code :
text1.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
message = text1.getText();
repaint();
}
});
Add a KeyListener to your textfield.
You can do that like this:
textField.addKeyListener(new KeyAdapter(){
#Override
public void keyPressed(KeyEvent e){
message = textField.getText();
repaint();
}
});
OR
Add a DocumentListener to your textfield's Document.
You can do that like this:
private JFrame getFrame(){
return this;
}
...
textField.getDocument().addDocumentListener(new DocumentListener(){
#Override
public void insertUpdate(DocumentEvent e) {
message = textField.getText();
getFrame().repaint();
}
#Override
public void removeUpdate(DocumentEvent e) {
message = textField.getText();
getFrame().repaint();
}
#Override
public void changedUpdate(DocumentEvent e) {
// on change
}
});
Instead of using ActionListener for the class TextFieldListener, use KeyListener interface and use the keyTyped(KeyEvent e) method. When ever the event arises you can use getText() of texfield and repaint it.