I've ben researching how to use swing timers for 2 days now and am trying to figure out how to change the image I have at the center of my JFrame. As of now my program runs properly, but the image does not change the way I want it to. This class was just used as a test so it might not have proper java syntax.
package hauntedHouseAdventure;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class timertest {
static JFrame sceneOne = new JFrame();
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ImageIcon image = new ImageIcon(
"/Users/computerscience2/Desktop/dark-forest-night-image.jpg");
JLabel imageLabel = new JLabel("", image, JLabel.CENTER);
JPanel panel = new JPanel(new BorderLayout());
panel.add(imageLabel, BorderLayout.NORTH);
sceneOne.add(panel);
sceneOne.setResizable(false);
imageLabel.setVisible(true);
sceneOne.pack();
JButton leave=new JButton("Leave");
JButton stay= new JButton ("Stay");
leave.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
sceneOne.setVisible(false);
}
});
stay.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent f)
{
//Execute when button is pressed
sceneOne.setVisible(false);
}
});
panel.add(leave, BorderLayout.EAST);
panel.add(stay, BorderLayout.WEST);
JLabel label1 = new JLabel("Test");
label1.setText("<html><font color='red'> It was approximately 11:30 pm. The night sky was black not a single star piercing through the darkness"
+ "except the thick and powerful moonlight."
+ "<br>"
+ "You are alone leaving a costume party at a friend's place."
+ "It was rather boring and you decided to leave early."
+ "A stutter is heard and your"
+ "<br>"
+ "car begins to shake"
+ "Your headlights and car lights crack. The engine is left dead silent."
+ "You are left in a total silence"
+ "and baked in merely the moonlight."
+ "<br>"
+ "There is a mere second of silence till a harsh chill ripes through the"
+ "car like a bullet through paper. You are left dumbfounded. What do you do?</font><html>");
label1.setHorizontalAlignment(JLabel.CENTER);
label1.setVerticalAlignment(JLabel.BOTTOM);
label1.setVisible(true);
label1.setOpaque(false);
panel.add(label1);
final ActionListener updater = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
ImageIcon image = new ImageIcon(
"/Users/computerscience2/Desktop/image-slider-5.jpg");
JLabel imageLabel = new JLabel("", image, JLabel.CENTER);
JPanel panel = new JPanel(new BorderLayout());
panel.add(imageLabel, BorderLayout.NORTH);
sceneOne.add(panel);
}
};
Timer timer = new Timer(1000, updater);
timer.start();
sceneOne.setSize(2000,1000);
sceneOne.setTitle("The Car");
sceneOne.setVisible(true);
sceneOne.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sceneOne.setLocation(250, 200);
}
}
I see two problems in your code.
You are adding the new image to your panel, but not removing the old image.
You are not telling to your frame that your components changed and he needs to redraw.
I think the best way to do this, is just changing the icon of your imageLabel. Like this:
final JLabel imageLabel = new JLabel("", image, JLabel.CENTER);
......
final ActionListener updater = new ActionListener() {
public void actionPerformed(ActionEvent e) {
ImageIcon image = new ImageIcon("/Users/computerscience2/Desktop/image-slider-5.jpg");
imageLabel.setIcon(image);
imageLabel.updateUI(); //Tell to your frame he needs to redraw the image
}
};
I didn't look in detail but to change the image on the label then you don't need to create a new control, you just need to change the image on the existing one.
public void actionPerformed(ActionEvent event) {
ImageIcon image = new ImageIcon(
"/Users/computerscience2/Desktop/image-slider-5.jpg");
imageLabel.setIcon(image);
}
You will also need to make imageLabel either a member variable or final so that the actionPerformed method can see it.
Related
to start off I will just say that I am new to java.
I want to create a simple Java app with a Jframe and some buttons which takes screenshots of any selected monitors.
What I use is a macbook and 2 monitors ( different resolutions, than the mac ). I will use action listeners for each buttons.
I searched the net and saw that the GraphicsEnvironment library could do this ( right now it detects all 3 monitors ).
So, how can I assign each monitor to buttons Screen1/2/3 ( probably Screen 1 will be the default monitor which is the mac )
And the functionality would be : if Screen 2 is selected, when clicking on Take Screenshot button, only monitor 2 will be captured.
Also, another newb question : what am i doing wrong for the i++ button ??
Below is the "empty" jframe created.
Thank you.
import java.awt.*;
import javax.swing.JTextField;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static java.lang.String.*;
public class Main {
public static void main(String[] args) {
try {
// Get local graphics environment
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
// Returns an array of all of the screen GraphicsDevice objects.
GraphicsDevice[] devices = env.getScreenDevices();
int numberOfScreens = devices.length;
System.out.println("Number of available screens = " + numberOfScreens);
} catch (HeadlessException e) {
// We'll get here if no screen devices was found.
e.printStackTrace();
}
// Jframe module
JFrame frame = new JFrame("ScreenShot");
frame.setTitle("Screenshot");
JLabel cadru1 = new JLabel("Step:");
JTextField text1 = new JTextField("1");
JButton plus1 = new JButton("+");
JLabel cadru2 = new JLabel("SubStep:");
JTextField text2 = new JTextField("1");
JButton plus2 = new JButton("+");
JButton scr1 = new JButton("Screen 1");
JButton scr2 = new JButton("Screen 2");
JButton scr3 = new JButton("Screen 3");
JButton path = new JButton("Set Path");
JButton Take = new JButton("Take ScreenShot");
frame.add(cadru1);
frame.add(text1);
frame.add(plus1);
frame.add(cadru2);
frame.add(text2);
frame.add(plus2);
frame.add(scr1);
frame.add(scr2);
frame.add(scr3);
frame.add(path);
frame.add(Take);
frame.setBackground(Color.DARK_GRAY);
Take.setForeground(Color.red);
frame.setLayout(new GridLayout(4, 3));
frame.setSize(200, 400);
frame.setVisible(true);
frame.pack();
frame.setVisible(true);
public void actionPerformed(ActionEvent) {
plus1++;
cadru1.setText("1" + plus1 );
})
}
}
My JTextArea has text appended to it then it is updated with
jTexaArea.update(jTextArea.getGraphics());
But while appending I cannot select or edit text nor scroll.
NetBeans system output allows for these features, how do I include them in my program?
While appending text if it is triggered by a JButton click event, the UI becomes unresponsive till the event is finished. This is because the event dispatch thread waits for the event to get finished before proceeding with next event.
If your requirement is to work on Text Area when an event is getting processed you can choose following approaches:
Using SwingWorker
Implementing Lazy appending of text in JTextArea
Following is a sample lazy appending example:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import java.awt.Font;
import javax.swing.JScrollPane;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Date;
import java.util.List;
import javax.swing.Timer;
import javax.swing.text.DefaultCaret;
public class LazyAppender extends JFrame implements ActionListener {
/**
* Demonstrates two different ways of appending text into TextArea
*/
private static final long serialVersionUID = 1L;
JTextArea textArea1;
JTextArea textArea2;
public LazyAppender() {
initUI();
}
public final void initUI() {
GridLayout experimentLayout = new GridLayout(2,2);
JPanel panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(experimentLayout);
//Button 1
JButton button1 = new JButton("Button 1");
button1.setToolTipText("Append JtextArea1 without using Swing Timer");
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
textArea1.append(getText());
textArea1.update(textArea1.getGraphics());
}
});
//Button 2
JButton button2 = new JButton("Button 2");
button2.setToolTipText("Lazy Append JtextArea2 using Swing Timer");
Timer timer2 = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
textArea2.append(getText());
}
});
timer2.setRepeats(false); //Execute only once
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
//Start timer, this will release the button immediately
timer2.start();
}
});
//TextArea 1
textArea1 = new JTextArea("This is an editable JtextArea1. " +
"A text area is a \"plain\" text component, " +
"which means that although it can display text " +
"in any font, all of the text is in the same font."
);
textArea1.setFont(new Font("Serif", Font.ITALIC, 16));
textArea1.setLineWrap(true);
textArea1.setWrapStyleWord(true);
//ScrollPane 1
JScrollPane areaScrollPane1 = new JScrollPane(textArea1);
areaScrollPane1.setViewportView(textArea1);
//TextArea 2
textArea2 = new JTextArea("This is an editable JtextArea2. " +
"A text area is a \"plain\" text component, " +
"which means that although it can display text " +
"in any font, all of the text is in the same font."
);
textArea2.setFont(new Font("Serif", Font.ITALIC, 16));
textArea2.setLineWrap(true);
textArea2.setWrapStyleWord(true);
//ScrollPane 2
JScrollPane areaScrollPane2 = new JScrollPane(textArea2);
areaScrollPane2.setViewportView(textArea2);
//Add Components into Panel
panel.add(button1);
panel.add(button2);
panel.add(areaScrollPane1);
panel.add(areaScrollPane2);
setTitle("Text Area Append Verify");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
}
public String getText(){
String stringToAppend = "This is your life. Do what you want and do it often." +
"If you don't like something, change it." +
"If you don't like your job, quit." +
"If you don't have enough time, stop watching TV." +
"If you are looking for the love of your life, stop; "+
"they will be waiting "+
"for you when you start doing things you love." +
"Stop over-analysing, life is simple." +
"All emotions are beautiful." +
"When you eat, appreciate every last bite." +
"Life is simple." +
"Open your heart, mind and arms to new things and people, "+
"we are united in our differences." +
"Ask the next person you see what their passion is and "+
"share your inspiring dream with them." +
"Travel often; getting lost will help you find yourself." +
"Some opportunities only come once, seize them." +
"Life is about the people you meet and the things you create "+
"with them, so go out and start creating." +
"Life is short, live your dream and wear your passion." +
"~ Holstee Manifesto, The Wedding Day ";
//Simulated delay
long start = new Date().getTime();
while(new Date().getTime() - start < 1000L){}
return stringToAppend;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
LazyAppender ex = new LazyAppender();
ex.setVisible(true);
}
});
}
}
Also, check this question JTextArea thread safe? for an in-depth discussion on whether its safe to JTextArea in multi-threaded environments.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm creating a "Snake" game as homework and I've passed hours searching around all the possible methods to close a JFrame, without conclusion. I started the program creating a JFrame with a background image and a menu, nothing more. When I click on the "Start game" button (JMenuItem) it opens a new JFrame with a thread to play the game. My problem is that the first JFrame doesn't close anyway I try to. I tried using these solutions and these and these but that JFrame's still there. It looks like the only command he listens to is the "EXIT_ON_CLOSE" as DefaultCloseOperation, not even the "DISPOSE_ON_CLOSE" is working. This is my SnakeFrame class:
package snake;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
/**
*
* #author Giacomo
*/
public class SnakeFrame extends Snake{
protected JMenuItem start = new JMenuItem("Start game");
public void pullThePlug(final SnakeFrame frame) {
/*// this will make sure WindowListener.windowClosing() et al. will be called.
WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
// this will hide and dispose the frame, so that the application quits by
// itself if there is nothing else around.
frame.setVisible(false);
frame.dispose();*/
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentHidden(ComponentEvent e) {
((JFrame)(e.getComponent())).dispose();
}
});
}
public int game(final SnakeFrame frame,final JFrame gameFrame){
short game_ok=0;
try{
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GameThread gamethread = new GameThread(frame,gameFrame);
gamethread.start();
pullThePlug(frame);
}
});
}
catch(Exception e){
game_ok=1;
}
return game_ok;
}
//-----------Frame initialization with relative Listeners and Events.---------\\
public SnakeFrame(){
JFrame frame= new JFrame("Le Snake");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
+ "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
frame.setIconImage(icon.getImage());
frame.setResizable(false);
frame.setLayout(new GridLayout());
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
JMenuItem close = new JMenuItem("Exit");
close.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menu.add(start);
menu.add(close);
frame.setJMenuBar(menuBar);
try {
frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read
(new File("C:\\Users\\Giacomo\\Documents\\NetBeansProjects\\"
+ "Snake\\src\\res\\default.png")))));
} catch (IOException e) {
System.out.println("Exception with the background image.");
}
frame.pack();
}
//-------------------------Frame initialization ended.-----------------------\\
}
Here's the game thread's code instead (for now):
package snake;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
/**
*
* #author Giacomo
*/
public class GameThread extends Thread implements Runnable{
private final SnakeFrame frame;
private final JFrame gameFrame;
public GameThread(final SnakeFrame f,final JFrame gF){
this.frame = f;
this.gameFrame = gF;
}
#Override
public void run(){
System.out.println("Game Thread started.");
final Label[][] griglia = new Label[50][50];
final Container container = new Container();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
gameFrame.setVisible(true);
gameFrame.setBounds(((int)larghezza/4),((int)altezza/4),
800, 600);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
+ "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
gameFrame.setIconImage(icon.getImage());
gameFrame.setResizable(false);
gameFrame.addWindowListener(new WindowAdapter(){
#Override
public void windowClosing(WindowEvent e){
//Just to be sure he dies.
gameFrame.dispose();
frame.dispose();
System.exit(0);
}
});
gameFrame.setLayout(new GridLayout(50,50));
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
griglia[i][j] = new Label();
griglia[i][j].setBackground(Color.BLACK);
container.add(griglia[i][j]);
}
}
gameFrame.add(container);
}
}
Did I forget something? Does anyone have an idea? Sorry if my code's bad but I'm at school to learn :P I'm using NetBeans 8.0.2. Thanks everyone.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EDIT:
I have now solved most of the problems I had, and here is the main:
public static void main(String[] args) {
final SnakeFrame frame = new SnakeFrame();
short isGameOk;
isGameOk =(short)frame.game(frame);
if(isGameOk==1)
System.err.println("Game Error!");
}
while here's the SnakeFrame class ("fixed"):
public class SnakeFrame extends Snake{
private final JMenuItem start = new JMenuItem("Start game");
private final BackgroundPanel defaultpanel;
public int game(final SnakeFrame frame){
short game_ok=0;
try{
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
defaultpanel.setVisible(false);
JPanel panel = new JPanel();
JLabel[][] griglia = new JLabel[50][50];
panel.setLayout(new GridLayout(50,50));
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
griglia[i][j] = new JLabel();
griglia[i][j].setBackground(Color.BLACK);
panel.add(griglia[i][j]);
}
}
frame.add(panel);
griglia[45][30].setIcon(new ImageIcon
("src\\res\\sneikhead.png"));
panel.setVisible(true);
}
});
}
catch(Exception e){
game_ok=1;
}
return game_ok;
}
//-----------Frame initialization with relative Listeners and Events.---------\\
public SnakeFrame(){
JFrame frame= new JFrame("Le Snake");
ImageIcon imm = new ImageIcon(getClass().getResource
("/res/default.png"));
Image background = imm.getImage();
defaultpanel = new BackgroundPanel(background, BackgroundPanel.ACTUAL,
1.0f, 0.5f);
frame.add(defaultpanel);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon imageIcon = new ImageIcon(getClass().getResource("/res/Snake-icon.png"));
Image icon = imageIcon.getImage();
frame.setIconImage(icon);
frame.setResizable(false);
frame.setLayout(new GridLayout());
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
JMenuItem close = new JMenuItem("Exit");
close.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menu.add(start);
menu.add(close);
frame.setJMenuBar(menuBar);
frame.pack();
}
//-------------------------Frame initialization ended.-----------------------\\
}
I am now able to change the SnakeFrame's background with a defaultpanel.setVisible(false); but the panel full of black colored labels that should show isn't visible even if I set it true. How can I get it visible? Thank you.
Some general comments:
Why are you creating a second frame? Usually a game is played in its own frame? You have a menu that allows you to change options of the game and this is done by display a modal JDialog. Then you have a "Start" button that starts the game by adding a panel to the existing frame.
Don't use a ComponentListener on the frame. There is no need to handle componentHidden.
Why do you have the game() method? I don't even see in your code where you invoke the method. Just add the actionListener to the Start menu item in the constructor of your class. Keep the creation of the menu item and the assignment of the actionListener in the same block of code so we don't need to look all over the class to find all the related properties for the component.
When I click on the "Start game" button (JMenuItem) it opens a new JFrame with a thread to play the game.
This is wrong. You should NOT be starting a separate Thread. All Swing components should be created on the Event Dispatch Thread (EDT). So basically the code should just be invoked from within your ActionListener since all event code does execute on the EDT.
It looks like the only command he listens to is the "EXIT_ON_CLOSE" as DefaultCloseOperation, not even the "DISPOSE_ON_CLOSE" is working.
Those are properties that you set for the frame. Then when the user clicks on the "X" button at the top/right of the frame the frame will close depending on the property. These properties have no effect when you invoke frame.dispose() or System.exit() directly.
GameThread gamethread = new GameThread(frame,gameFrame);
Why are you passing the frame to your other class? If you goal is to close the original frame. Then close the frame here after creating the other frame. In fact why do you even have a reference to the "gameFrame" here. If you have another class that creates the components of the frame, it should create the frame as well.
pullThePlug(frame);
This code does nothing. You are invoking this method AFTER you attempt to close the frame.
In general, I can't follow your logic since the code is not complete. However as a general rule an application should only contain a single JFrame. Hiding/showing multiple frames is not an experience uses want to see. When a new game starts you should just refresh the content pane of the existing frame.
I am trying to make a Wizard without using libraries that I Have seen to easily make wizards lol its for a project, I have done the layout and frames and panels, what am having trouble with is when I click the "-->" it does not go to panel2 , nothing happens, it does store the name but thatt is it. Could anybody help me out?
EDIT it works now :) now am having trouble displaying the second "panel2" it goes into nothing after i click the arrow. lol
package project4;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class WizardGUI extends JFrame implements ActionListener {
private JLabel enterName;
private JTextField name;
private JButton prev, fow;
private String storeName = "";
WizardGUI(){
super("Wizard");
name();
}
void name()
{
JPanel FPanel = new JPanel();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
// JLabel textLabel = new JLabel("lol");
//textLabel.setPreferredSize(new Dimension(300, 100));
// frame.getContentPane().add(textLabel);
//prev = new JButton("<--");
fow = new JButton ("-->");
this.add(FPanel);
enterName = new JLabel("Enter Your Name: ");
name = new JTextField(10);
enterName.setBounds(60, 30,120,30);
name.setBounds(80,60,130,30);
this.setSize(300,390); //set frame size
this.setVisible(true);
FPanel.add(enterName);
FPanel.add(name);
//FPanel.add(prev);
FPanel.add(fow);
fow.addActionListener(this);
}
void enter()
{
JPanel panel2 = new JPanel();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
//prev = new JButton("<--");
fow = new JButton ("-->");
this.add(panel2);
enterName = new JLabel("Enter Your Name: ");
name = new JTextField(10);
enterName.setBounds(60, 30,120,30);
name.setBounds(80,60,130,30);
this.setSize(300,390); //set frame size
this.setVisible(true);
panel2.add(enterName);
panel2.add(name);
//FPanel.add(prev);
panel2.add(fow);
fow.addActionListener(this);
this.getContentPane().removeAll();
validate();
repaint();
this.add(panel2);
}
void add()
{
}
void select()
{
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == fow) {
storeName = name.getText();
enter();
//JOptionPane.showMessageDialog(null, "hello " + storeName);
}
}
}
Thanks :)
You both extend JFrame and you create your own JFrame. This means you have two instances of JFrame. One is your WizardGUI class which I'm guessing is referenced in your main somewhere and the other is a local variable named frame.
In the constructor you are building everything in the frame instance. In the Sscreen method you are modifying the this instance so nothing that you've done to the frame instance is modified.
You should get rid of the local variable frame and replace all references to it with this.
Also, you should call super("Wizard") as your first line in the WizardGUI constructor. Calling parent constructors is important and everyone forgets to do that.
I have a JPanel with GroupLayout with 3 JLabels in it. I also have a hidden JButton in it.
I have added a MouseListener to JPanel showing the button in mouseEntered and hide the button in mouseExited events respectively.
At this time, their is space for button between 2 labels and their only the button is shown or hidden using setVisible(). When the btn is visible, the labels below it goes down making space for button and if the btn is hidden it again comes to its original size.
What I want - in mouseEntered, the button should show on the label itself (let it be overlap) and I should be able to click on the button. This all should happen very smoothly without screen flickering. Similarly in mouseExited, the button should be removed.
How do I achieve this ? Can anyone help me with this.
UPDATE
#Andrew, Thanks I tried with JLayeredPane and it does work. Though the button is not set to visible false. Here's my mouseMoved code :
public void mouseMoved(MouseEvent e) {
if (e.getComponent() == layeredPane) {
if (! startCustomBtn.isVisible())
startCustomBtn.setVisible(true);
startCustomBtn.setLocation(e.getX()-55, e.getY()-30);
} else {
if (startCustomBtn.isVisible()) {
startCustomBtn.setVisible(false);
revalidate();
}
}
}
Layout of the JPanel :
private void layeredLayout() {
layeredPane = new JLayeredPane();
layeredPane.addMouseMotionListener(this);
Insets insets = this.getInsets();
Dimension size = rateLabel.getPreferredSize();
rateLabel.setBounds(insets.left + 45, insets.top + 15, size.width, size.height);
size = imageLabel.getPreferredSize();
imageLabel.setBounds(insets.left + 15, insets.top + 40, size.width, size.height);
size = label.getPreferredSize();
label.setBounds(insets.left + 45, insets.top + imageLabel.getWidth() + 20 , size.width, size.height);
size = startCustomBtn.getPreferredSize();
startCustomBtn.setBounds(insets.left + 45, insets.top + 40 + size.height, size.width, size.height);
layeredPane.add(rateLabel, new Integer(0));
layeredPane.add(imageLabel, new Integer(1));
layeredPane.add(label, new Integer(2));
layeredPane.add(startCustomBtn, new Integer(1), 0);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(layeredPane);
}
Strange - I tried the layout with null, FlowLayout, but couldn't see anything. When tried with BoxLayout, components showed up.
REsult :
Main screen has a JPanel with Gridlayout(2, 3) and in each cell this JPanel (MyPanel) is added. When I come out from 1 cell (i.e. MyPanel) the button of that panel should be hidden which is not happening with the above code. What can be the reason ? I also added revalidate() & also repaint() but nothing works. ????
What I want - in mouseEntered, the button should show on the label
itself (let it be overlap) and I should be able to click on the
button. This all should happen very smoothly without screen
flickering. Similarly in mouseExited, the button should be removed.
As JLabel extends from JComponent you can add componentes to label itself, just need to set a LayoutManager first. This fact is well explained in this question.
Sample Code
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class Demo {
private void initGUI(){
final JButton button = new JButton("Hello!");
button.setVisible(false);
final JLabel testLabel = new JLabel("Welcome!");
testLabel.setPreferredSize(new Dimension(200, 30));
testLabel.setBorder(new LineBorder(Color.GRAY, 1));
testLabel.setLayout(new BorderLayout());
testLabel.add(button, BorderLayout.EAST);
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseExited(MouseEvent e) {
Point mousePosition = MouseInfo.getPointerInfo().getLocation();
if(testLabel.contains(mousePosition)){
testLabel.dispatchEvent(new MouseEvent(testLabel, MouseEvent.MOUSE_ENTERED, System.currentTimeMillis(), 0, mousePosition.x, mousePosition.y, 0, false));
} else {
testLabel.dispatchEvent(new MouseEvent(testLabel, MouseEvent.MOUSE_EXITED, System.currentTimeMillis(), 0, mousePosition.x, mousePosition.y, 0, false));
}
}
});
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "The button was pressed!");
Point mousePosition = MouseInfo.getPointerInfo().getLocation();
testLabel.dispatchEvent(new MouseEvent(testLabel, MouseEvent.MOUSE_EXITED, System.currentTimeMillis(), 0, mousePosition.x, mousePosition.y, 0, false));
}
});
testLabel.addMouseListener(new MouseAdapter(){
#Override
public void mouseEntered(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
label.setText("Here is the Button!");
button.setVisible(true);
}
#Override
public void mouseExited(MouseEvent e) {
Point point = e.getPoint();
point.setLocation(point.x - button.getX(), point.y - button.getY()); //make the point relative to the button's location
if(!button.contains(point)) {
JLabel label = (JLabel) e.getSource();
label.setText("The button is gone!");
button.setVisible(false);
}
}
});
JPanel content = new JPanel(new FlowLayout());
content.setPreferredSize(new Dimension(300,100));
content.add(testLabel);
JFrame frame = new JFrame("Demo");
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().initGUI();
}
});
}
}
Output
Update
As #nIcEcOw pointed out (thanks!), there's an annoying flickering generated by mouse events' transition. I improved the example fixing this and another untreated aspects like "what happens when mouse exits from JButton?"
Questions like this are kind of frustrating. There is almost enough information to describe what you want, or what the problem is, but not quite.
It seems that you want label-label-label until the mouse enters the panel, then you want the appearance to be label-button-label. It's hard to imagine me wanting a UI to act like this.
Is there something about the appearance of the button you don't like, that you want it only to appear on mouse-over-panel? Can the button's appearance be altered so that it looks the way you want it to look, without all this hocus-pocus with the middle label and the button?
I don't have any idea why you mention a timer -- nothing that you describe is being timed, as near as I can tell. In addition, you should be able to boil down what you have to a small runnable example and post it, so that someone can see what you've got and what it does.