I tried to write clock in Java.
Here is example of my code.
I want to make the background transparent but I don't know how.
I want to place my program on top of all Windows. An example of how that must look :
.
There are two classes in my program. First of the called clock and second is Executor
screen:
.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Calendar;
public class clock extends JFrame
{
private static final long serialVersionUID = 1L;
JLabel timeF;
JPanel panel;
public clock()
{
super("Java Clock by Anton" );
setSize (400,90);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(true);
setLocationRelativeTo(null);
panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.setOpaque(false);
timeF = new JLabel("0:0:0");
timeF.setFont(new Font("Arial",Font.PLAIN,48));
panel.add(timeF);
add(panel);
Timer t = new Timer(1000,new Listener());
t.start();
}
class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Calendar rightNow = Calendar.getInstance();
int hour = rightNow.get(Calendar.HOUR_OF_DAY);
int min = rightNow.get(Calendar.MINUTE);
int sec = rightNow.get(Calendar.SECOND);
timeF.setText(hour + ":" + min + ":" + sec);
}
}
}
Right after you create your JPanel, add the following:
setUndecorated(true);
setVisible(true);
// has the alpha parameter set to transparent.
setBackground(new Color(255,0,0,0));
panel.setOpaque(false);
But once the Frame is undecorated, you won't be able to close it, so you may need to add some additional code in your panel. A mouseListener will work.
Create an inner class
class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent a) {
System.exit(-1);
}
}
Then
panel.addMouseListener(new MyMouseListener());
When you click on the time, it will exit the program.
Note: You should not be extending JFrame. It is best to create an instance and use that. The rule is, prefer composition over inheritance when it makes sense to do so.
Related
So I am making a game that records your reaction time after you see something pop up on the screen, but I am having trouble with getting that reaction time. I want the user to press the up arrow key once they see a blue ball and I want to record their reaction time once they pressed that button.
Here is my code:
public class Game extends JPanel
{
private JLabel start, main, time;
private ImageIcon constant, react;
final int width = 600;
final int height = 600;
private Timer replace;
private Random random;
private int randTime;
private long startTime;
private long stopTime;
private long reactionTime;
private Action upAction;
public Game()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setPreferredSize(new Dimension(width, height));
setBackground(Color.black);
start = new JLabel("Click Up Arrow when you see a blue ball");
start.setForeground(Color.white);
start.setAlignmentX(Component.CENTER_ALIGNMENT);
add(start);
constant = new ImageIcon("constantCircle.png");
main = new JLabel(constant);
main.setAlignmentX(Component.CENTER_ALIGNMENT);
randomTime();
replace = new Timer(randTime, timeListener);
startTime = System.currentTimeMillis();
replace.setRepeats(false);
replace.start();
add(main);
time = new JLabel("0");
time.getInputMap().put(KeyStroke.getKeyStroke("UP"), "upAction");
time.getActionMap().put("upAction", upAction);
add(time);
}
public void randomTime()
{
random = new Random();
int max = 8000;
randTime = random.nextInt(max);
}
ActionListener timeListener = new ActionListener()
{
public void actionPerformed (ActionEvent e)
{
react = new ImageIcon("reactCircle.png");
main.setIcon(react);
}
};
public class UpAction extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
stopTime = System.currentTimeMillis();
reactionTime = stopTime - startTime;
time.setText("" + reactionTime);
}
}
}
I setup a "startTime" using System.currentTimeMillis to get the time after the ball turns blue but I am not sure if that is the correct way to do it.
I also setup a "stopTime" in the "UpAction" class where I want to get the time once the user presses up arrow but I it does not work.
if anything doesn't make sense or isn't clear enough, I'll try my best to elaborate more
I came up with the following GUI.
There are two important principles I want to explain. The first is that creating the GUI is a separate process from updating the GUI. The second is that the game process is a state machine. The game is in six separate states. Here's what I wrote to keep the states in mind.
Sequence of events
Left-click button
Wait 2 - 4 seconds to display the circle.
Capture start time
Left-click button
Capture end time.
Calculate and display reaction time.
Repeat 1 - 6.
So, for the GUI, I created a JFrame and three JPanels; an upper JPanel, a drawing JPanel, and a button JPanel.
I started the Swing application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
The JFrame has a default BorderLayout, which I used to place the three JPanels. The JFrame method calls must be executed in a specific order. This is the order I use for all my Swing applications.
The upper JPanel contains the instructions and the reaction time display. A JTextArea is great for displaying instructions. I put the JTextArea inside an inner JPanel using a FlowLayout, which I placed in the upper JPanel using a BorderLayout. Nesting layouts like this is a good way to organize the Swing components in a logical manner.
I put the reaction time Swing components in another inner JPanel, which I placed in the upper JPanel.
I created a drawing JPanel so I wouldn't have to bother with an image.
The button JPanel holds the Submit JButton.
I created two controller classes. One controller class, ButtonListener, responds to the JButton left-clicks. The other controller class, TimerListener, creates the delay for drawing the circle.
The ButtonListener state variable allows me to provide different functionality with the same ActionListener. If you wish, you can write separate ActionListener classes, one for each function.
By separating my code into view and controller classes, I could separate my concerns and focus on one part of the application at a time.
Here's the complete runnable code. I made all the classes inner classes so I could post this code as one block.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ReactionTimeGame implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new ReactionTimeGame());
}
private long reactionTime;
private DrawingPanel drawingPanel;
private JTextField reactionTimeField;
public ReactionTimeGame() {
this.reactionTime = 0L;
}
#Override
public void run() {
JFrame frame = new JFrame("Reaction Time Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createUpperPanel(), BorderLayout.BEFORE_FIRST_LINE);
this.drawingPanel = new DrawingPanel();
frame.add(drawingPanel, BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createUpperPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel innerPanel = new JPanel(new FlowLayout());
String instructions = "This game will test your reaction time. To play "
+ "the game, left-click on the Submit button. After a random time "
+ "from 2 - 4 seconds, a circle will appear. Left-click the "
+ "Submit button again. Your reaction time will be displayed "
+ "above where the circle was.\n\n"
+ "Left-click the Submit button to start each round of the game.";
JTextArea textArea = new JTextArea(7, 40);
textArea.setEditable(false);
textArea.setText(instructions);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
innerPanel.add(textArea);
panel.add(innerPanel, BorderLayout.BEFORE_FIRST_LINE);
innerPanel = new JPanel(new FlowLayout());
JLabel label = new JLabel("Reaction Time:");
innerPanel.add(label);
reactionTimeField = new JTextField(5);
reactionTimeField.setEditable(false);
updateReactionTime();
innerPanel.add(reactionTimeField);
label = new JLabel("seconds");
innerPanel.add(label);
panel.add(innerPanel, BorderLayout.AFTER_LAST_LINE);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JButton button = new JButton("Submit");
button.addActionListener(new ButtonListener());
panel.add(button);
return panel;
}
public void setReactionTime(long reactionTime) {
this.reactionTime = reactionTime;
}
public void drawCircle() {
drawingPanel.setDrawCircle(true);
drawingPanel.repaint();
}
public void eraseCircle() {
drawingPanel.setDrawCircle(false);
drawingPanel.repaint();
}
public void updateReactionTime() {
double time = 0.001 * reactionTime;
reactionTimeField.setText(String.format("%.3f", time));
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private boolean drawCircle;
public DrawingPanel() {
this.drawCircle = false;
this.setPreferredSize(new Dimension(300, 300));
}
public void setDrawCircle(boolean drawCircle) {
this.drawCircle = drawCircle;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (drawCircle) {
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
int radius = Math.min(getWidth(), getHeight()) * 9 / 20;
int diameter = radius + radius;
g.setColor(Color.MAGENTA);
g.fillOval(centerX - radius, centerY - radius, diameter, diameter);
}
}
}
public class ButtonListener implements ActionListener {
private int state;
private long startTime;
private final Random random;
private Timer timer;
public ButtonListener() {
this.state = 1;
this.random = new Random();
}
#Override
public void actionPerformed(ActionEvent event) {
switch (state) {
case 1:
int delay = random.nextInt(2000) + 2000;
timer = new Timer(delay, new TimerListener(this));
timer.start();
state = 2;
break;
case 2:
setEndTime(System.currentTimeMillis());
eraseCircle();
state = 1;
break;
}
}
public int getState() {
return state;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public void setEndTime(long endTime) {
long elapsedTime = endTime - startTime;
setReactionTime(elapsedTime);
updateReactionTime();
}
}
public class TimerListener implements ActionListener {
private final ButtonListener listener;
public TimerListener(ButtonListener listener) {
this.listener = listener;
}
#Override
public void actionPerformed(ActionEvent event) {
Timer timer = (Timer) event.getSource();
timer.stop();
if (listener.getState() == 2) {
listener.setStartTime(System.currentTimeMillis());
drawCircle();
}
}
}
}
I have 2 jframes, 1 is kinda like the main menu, i want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
I used the sout to see what really happens because it wasnt working, but i see that the level goes from 0 to 1 back to 0 and goes on and on, does someone know why and how to fix?
SpeelVeld frame = new SpeelVeld();
frame.setBounds(0,0,519,591);
frame.setLocationRelativeTo(null);
frame.getContentPane().setBackground(Color.WHITE);
frame.setTitle("RWINA");
frame.setVisible(true);
frame.setLevel(1);
this is in the main method of my original GameProject file.
How can i make a jdialog
I have 2 jframes, 1 is kinda like the main menu,
You shouldn't use 2 JFrames for this. The dependent sub-window, likely your main menu window, should in fact be a JDialog, probably a non-modal dialog from the looks of it.
I want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
and here's a big problem. Understand that in this code, you're creating a new SpeelVeld object, the stress being on the word new. Changing the state of this object will have no effect on the other SeelVeld object that is currently being displayed. Do do that, your second window will need a valid reference to the displayed SeelVeld object. How to do this will depend all on code not yet shown, but often it can be done simply by passing in the displayed SpeelVeld object into the main menu object by use of a constructor parameter or setter method.
For example:
import java.awt.Dialog.ModalityType;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
// JPanel for our main GUI
public class SpeelVeldFoo {
private static void createAndShowGui() {
// JPanel used by the main JFrame
SpeelVeldPanel speelVeldPanel = new SpeelVeldPanel();
// JPanel used by the main menu JDialog. Pass the above into it
MainMenuPanel mainMenuPanel = new MainMenuPanel(speelVeldPanel);
// create your JFrame
JFrame frame = new JFrame("Speel Veld");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(speelVeldPanel); // add the JPanel
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
// create your non-modal JDialog
JDialog menuDialog = new JDialog(frame, "Main Menu", ModalityType.MODELESS);
menuDialog.add(mainMenuPanel); // add the JPanel that holds its "guts"
menuDialog.pack();
menuDialog.setLocationByPlatform(true);
menuDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
#SuppressWarnings("serial")
class SpeelVeldPanel extends JPanel {
private int level = 1; // simple example just has a level int
private JLabel levelLabel = new JLabel("1"); // and displays it in a JLabel
public SpeelVeldPanel() {
add(new JLabel("Level:"));
add(levelLabel);
int ebGap = 50;
setBorder(BorderFactory.createEmptyBorder(ebGap, 2 * ebGap, ebGap, 2 * ebGap));
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
// whenever level is changed, update the display
this.level = level;
levelLabel.setText(String.valueOf(level));
}
}
// class for the JPanel held by the JDialog
#SuppressWarnings("serial")
class MainMenuPanel extends JPanel {
private JSpinner levelSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 5, 1));
private SpeelVeldPanel speelVeldPanel = null; // reference to the main GUI
// note the parameter.... you pass in the displayed main GUI so you can
// change it
public MainMenuPanel(final SpeelVeldPanel speelVeldPanel) {
this.speelVeldPanel = speelVeldPanel; // set the field
// respond when the spinner's data changes
levelSpinner.addChangeListener(new LevelListener());
add(new JLabel("Set the Speel Veld's level:"));
add(levelSpinner);
int ebGap = 10;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
}
private class LevelListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
// when the spinner's data changes
int level = (int) levelSpinner.getValue(); // get the data
speelVeldPanel.setLevel(level); // and send it to the main GUI
}
}
}
You'll note that I don't like extending JFrame or JDialog if I can avoid it. My feeling is that one can paint oneself into a corner by having your class extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding.
You probably want the JFrame to be the top-level container, then have a JPanel that holds your menu. The menu could be whatever you want, I'm using a JTextArea. Then, you need a JButton for the JPanel or JFrame that when pressed, changes the text in the JTextArea. Here is an implementation that you could work from. I'm using the ActionEvent as the trigger for when to mess with the JTextArea:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class SimpleSwing {
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
JPanel mainMenuPanel = new JPanel();
JTextArea textAttribute = new JTextArea("Original Text");
JButton changeAttributeButton = new JButton("Change Attribute");
changeAttributeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textAttribute.setText("Whatever new text you want");
}
});
mainMenuPanel.add(textAttribute);
mainMenuPanel.add(changeAttributeButton);
mainFrame.add(mainMenuPanel);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(500, 500);
mainFrame.setVisible(true);
}
}
I have a problem which is most likely "simple" however I can't figure it out. I am trying to reference my current JFrame so that I can dispose of it, and create a new one, thus "resetting" the program, however I and having trouble figuring out how to reference the JFrame, I have tried, super, this and getParent(), but none of the seem to work. Thanks for any / all help. ^^
Here is my code:
Main Class, just sets up the Jframe and calls the class that creates everything:
public static void main(String args[]) {
JFrame window = new JFrame();
Director director = new Director(window, args);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.pack();
window.setVisible(true);
}
}
Class the creates everything:
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Director extends JFrame implements CollisionListener {
private BrickWall wall;
private JLabel gameTitle, gameScore, gameLives;
private JPanel controlPanel;
private JButton reset, quit;
private JRadioButton hard, normal, easy;
private int score = 6, lives = 5;
private ButtonGroup difficulty;
public Director(JFrame window, String[] args) {
window.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
window.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
}
public void collisionDetected(CollisionEvent e) {
wall.setBrick(e.getRow(), e.getColumn(), null);
}
private JComponent makeGamePanel() {
wall = new BrickWall();
wall.addCollisionListener(this);
wall.buildWall(3, 6, 1, wall.getColumns(), Color.GRAY);
return wall;
}
// Reset method I'm trying to dispose of the JFrame in.
private void reset() {
JFrame frame = new JFrame();
frame.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
frame.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private JComponent gameControlPanel() {
// CONTROL PANEL PANEL!
controlPanel = new JPanel();
gameTitle = new JLabel("Brickles");
gameScore = new JLabel("Score:" + " " + score);
gameLives = new JLabel("Lives:" + " " + lives);
reset = new JButton("Reset");
quit = new JButton("Quit");
hard = new JRadioButton("Hard", false);
normal = new JRadioButton("Normal", true);
easy = new JRadioButton("Easy", false);
difficulty = new ButtonGroup();
difficulty.add(hard);
difficulty.add(normal);
difficulty.add(easy);
controlPanel.setLayout(new GridLayout(4, 2));
controlPanel.add(gameTitle);
controlPanel.add(gameScore);
controlPanel.add(hard);
controlPanel.add(gameLives);
controlPanel.add(normal);
controlPanel.add(reset);
controlPanel.add(easy);
controlPanel.add(quit);
// Action Listener, where I'm caling the reset method.
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
reset();
}
});
return controlPanel;
}
}
You can refer to the "outer this" from a nested class with the following syntax:
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Director.this.reset();
}
});
Yes, you can refer to the outer class by specifying it with the class name as noted in DSquare's good answer (1+ to it), but I urge you not to fling JFrame's at the user as you're program is trying to do. I recommend:
Instead of opening and closing multiple JFrames, use only one JFrame as the main application's window.
If you need helper windows, such as modal windows to get critical information that is absolutely needed, before the program can progress, use modal dialogs such as JDialogs or JOptionPanes.
If you need to swap GUI's, instead of swapping JFrames, swap "views" inside the JFrame via a CardLayout.
Gear your code towards creating these JPanel views and not JFrames as it will make your Swing GUI's much more flexible and portable.
JButton and JLabel disappears when adding custom background. I don't see any problems in my program, but maybe you guys find an solution! I think it's only a little thing I forgot, but I can't figure it out.
Here's the code:
GameWindow.java:
setContentPane(new StartImagePanel(RollrackLogo));
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
The background appears perfect, but not the JButton and JLabel!
Code to the StartImagePanel.java:
public class StartImagePanel extends JComponent{
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
Your button and label are added to your GameWindow frame while they should be added to its contentPane, setContentPane(new StartImagePanel(RollrackLogo)); instead. That's why they are not showing, they are added to the frame.
Make a variable of the StartImagePanel and add the button and label to it and they should show up.
StartImagePanel contentPanel = new StartImagePanel(RollrackLogo);
setContentPane(contentPanel);
...
out.println("adding JLWelcome");
JLWelcome.setText("Welcome to Rollrack, " + namewindow.name);
contentPanel.add(JLWelcome);
JLWelcome.setVisible(true);
out.println("JLWelcome added");
out.println("adding JBRandom");
JBRandom.setText("Random");
contentPanel.add(JBRandom);
JBRandom.setVisible(true);
out.println("added JBRandom");
Answer dispute
The claims in the first paragraph are plain wrong. Here is source that proves it.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AddToCustomContentPane {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new FlowLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.setBackground(Color.RED);
JFrame f = new JFrame("Demo");
f.setContentPane(gui);
// Acid test. Can we add buttons direct to the frame?
f.add(new JButton("Button 1"));
f.add(new JButton("Button 2"));
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
Edit after the custom panel code was given
Here's a snippet that works to show both button and label on a black image background, I removed that was not needed (listeners).
public static void main(String[] v) {
class StartImagePanel extends JPanel {
private Image image;
public StartImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
class GameWindow extends JFrame{
public GameWindow() {
BufferedImage RollrackLogo;
RollrackLogo = new BufferedImage(400,200,BufferedImage.TYPE_INT_RGB);
final JButton JBRandom = new JButton();
final JLabel JLWelcome = new JLabel();
setDefaultCloseOperation(EXIT_ON_CLOSE);
StartImagePanel panel = new StartImagePanel(RollrackLogo);
setContentPane(panel);
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
JLWelcome.setText("Welcome to Rollrack");
panel.add(JLWelcome);
JLWelcome.setVisible(true);
JBRandom.setText("Random");
panel.add(JBRandom);
JBRandom.setVisible(true);
}
}
GameWindow window = new GameWindow();
window.pack();
window.setVisible(true);
}
I rather use an instance of a JFrame, instead of extending it, as #Andrew Thompson suggested in another question.
However, if you're extending it, it might be a good practice to call super() in the constructor.
Additionally, we may need to know what is going on in your StartImagePanel.
It seems, to me, to be the problem.
Ensure both your GameWindow and StartImagePanel extend properly their superclasses (call super();).
Ensure your StartImagePanel has a proper Layout.
Add your components before you set your frame visible. This also means you won't need JLWelcome.setVisible(true);.
Ensure that your code is executed in the EDT (Event-Dispatch Thread).
Example:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class GameWindow extends JFrame{
BufferedImage rollrackLogo;
JButton jbRandom;
JLabel jlWelcome;
public GameWindow() {
super();
jbRandom = new JButton("Random");
jlWelcome = new JLabel("Welcome to Rollrack, " +
namewindow.name);
rollrackLogo = new BufferedImage(400, 200,
BufferedImage.TYPE_INT_RGB);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setContentPane(new StartImagePanel(rollrackLogo));
// Add your components.
add(jlWelcome);
add(jbRandom);
addKeyListener(new KeyListener() {
#SuppressWarnings("static-access")
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == e.VK_ESCAPE){
System.exit(7);
}
}
#Override
public void keyReleased(KeyEvent arg0) {}
#Override
public void keyTyped(KeyEvent arg0) {}
});
// Pack, or otherwise set fullscreen.
pack();
// Now, set frame visible.
setVisible(true);
}
}
Edit: Now that you've posted the code for your StartImagePanel, I see that you're extending JComponent. Follow my previous advice, (call super), set a Layout, and extend JPanel instead.
In the last secong and third line if I say
label.setText("x = ");
The label is moving perfectly but when I change it to
label.setText("x = "+ x);
it does not move. To be specific I want to see the width location of JLabel when it's moving by variable x!
Beside this I said label.setBounds(x,(getHeight()/2),300,300); which set the Y bound of the label to half of the frame size but it's not at the middle of frame? Any Idea?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.JFrame;
public class myTiemr {
public static void main(String args[])
{
TimeFrame frame = new TimeFrame();
}
}
class TimeFrame extends JFrame
{
private static final long serialVersionUID = 1L;
private int x = 0;
JLabel label = new JLabel("Here is my label");
public TimeFrame()
{
int d = 10;
setTitle("My Frame");
setSize(500,500);
this.setLocationRelativeTo(null);
add(label);
Timer time = new Timer(d,new TimerListener());
time.start();
setVisible(true);
}
class TimerListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(x>getWidth()){
x=-100;
}
x+=1;
label.setText("x = "+ x);
//label.setText("x = ");
label.setBounds(x,(getHeight()/2),300,300);
}
}
}
The reason that label.setText("x = "+ x) causes the text to remain still but yet the line label.setText("x = ") causes the label to move across the frame is that revalidate() is called on the JLabel. This will cause the correct behavior applying the current layout manager's rules (namely BorderLayout in this case).
When the text does not change, revalidate() is never called.
As #Sébastien Le Callonnec suggested setting no layout on the frame will cause
label.setText("x = "+ x)
to move as desired.
In the TimeFrame constructor, add:
this.setLayout(null);
after this.setLocationRelativeTo(null);.