Updating a JLabel within a JFrame - java

I've been searching around this site and the internet for hours trying to figure out how to fix this problem. I'm creating a game and it's my first time using graphics. I figured out how to create a JFrame, JPanel and JLabel, and the only problem I can't seem to get around is updating the JLabel. Let's say I start it out like this:
JLabel testing = new JLabel ("blah", JLabel.CENTER);
testing.setAlignmentX(0);
testing.setAlignmentY(0);
frame.add(testing);
I am able to change the text after a Thread.sleep(2500) by using testing.setText("hi");, but the previous state of the JLabel (which says blah) is still there. The "hi" just appears on top. I've tried testing.setVisible(false);, and so many other things but nothing is letting me display the JLabel, hide it, and then change it.
Any ideas what could be wrong?
Thanks

Don't sleep or otherwise block on the AWT Event Dispatch Thread (EDT).
Use javax.swing.Timer instead. Note: not any other class of the same name in a different package.
javax.swing.Timer timer =
new javax.swing.Timer(2500, event -> {
testing.setText("hi");
});
timer.setRepeats(false);
timer.start();

Related

Creating Dynamic JLabels for sort of a messenger app using Java

So I am trying to make a messenger sort of app with Java Drag and Drop in Netbeans.
I am fairly new at it. I initially want to take a string from the text area and display it in a JLabel in another panel. I tried to do it in the following process but it did not work.Can someone please help?
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
int i=0;
message = messageType.getText();
JLabel messageLabel = new JLabel();
messageLabel.setText(message);
messageLabel.setSize(100, 100);
messageLabel.setAlignmentX(0);
messageLabel.setAlignmentY(0);
JOptionPane.showMessageDialog(null, message);
clientPanel.add(messageLabel);
messageLabel.setVisible(true);
}
We have no idea what layout manager clientPanel is using and so do not know how well it will accept a JLabel being dropped into it, so as asked your direct question is unanswerable, other than to say you should always call revalidate() on a container (clientPanel) and then repaint() after adding or removing components so that the container re-lays out its components and then redraws them.
I advise against creating new JLabels for this. Much easier to set up the GUI including all necessary JLabels from the very beginning, give them text, empty spaces if need be, and then during the program set the text of an existing JLabel.
If on the other hand you wish to show multiple messages on the cientPanel, then consider using a JList<String> or a non-focusable JTextArea.

How to change JPanel using KeyListener? [duplicate]

I am developing a game, where you first get to the main screen, there are multiple selections to go, for example, Singleplayer, Twoplayer, Credits, etc.
I have one big problem. If I click a button in the menu, (not JButton) the JPanels switch, but the keyListener is lost. The Keylistener is in the same class as the game code, which implements JPanel. I tried everything to get the Keylistener to work, but it just won't.
Here is how the things are called: Main class --> Menu --> Game. I tried adding the keylistener to the main class, but it's not working.
So, JPanel switching is ok, but the Keylisteners are gone. I was developing the game before with new JFrames, so when I clicked a menu, a new frame was created. I didn't insert a code here, because it's too long (2000+ lines), and the KeyListener is working, but only when it is in a new JFrame. I set the mode int in the Menu class, by clicking a button.
This is currently my panel switch:
public void setJPanel() {
switch (mode) {
case 1:
getContentPane().add(s);
validate();
break;
case 2:
getContentPane().removeAll();
getContentPane().add(sp);
validate();
break;
}
}
Thanks for your help in advance!
Rather than use a KeyListener, have you given thought to or tried using Key Bindings? KeyListeners require that the component being listened to has focus, and focus may be lost for many reasons, especially when swapping views (are you using a CardLayout for this?). Key Bindings on the other hand can be set to be responsive even if the bound component doesn't have focus but when it is only held within a window that has focus. Tutorial: Using a CardLayout
Edit
I see that you're not using a CardLayout, and I suggest that you use this as it can make your view swapping cleaner and easier.
Edit 2
I agree that you don't want to post your entire 2000+ line program here as no one will have the time to read it, but consider condensing your question/problem into a single small class that is compilable and runnable by any and all of us, and demonstrates your problem. In other words, a Short, Self Contained, Compilable, Example or SSCCE .
Remember, the code should be compilable and runnable for many of us to be able to understand it fully.
Cardlayout actually is screwy while refocusing.
#op, try calling requestFocusInWindow() after the new jpanel was added
Try using myPanel.requsetFocusInWindow();
before using setVisible(true);

adding swing components at run time in netbeans [duplicate]

This question already has answers here:
Closed 10 years ago.
i have learnt core java and just started working with netbeans,but i am stuck at a point when i was trying to add the components like buttons,labels etc. at the run time in my project.I searched for it on google but the examples which i studied include some extra overhead of using panels in them,,,,but why can't i create the components at run time as i was creating them in the simple editor like notepad as follows
JButton b4=new JButton("ok");
add b4;
its not working.
To add Swing framework elements at runtime, you need to have a JFrame to add the elements to. A JFrame is just a window, like any other window you use (and just like NetBeans has), and it has a method called add(Component comp). The parameter is whichever Swing or AWT component you want to add to the JFrame. Here is some sample code to get you started:
// This line creates a new window to display the UI elements:
JFrame window = new JFrame("Window title goes here");
// Set a size for the window:
window.setSize(600, 400);
// Make the entire program close when the window closes:
// (Prevents unintentional background running)
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// This makes it so we can position elements freely:
window.setLayout(null);
// Create a new button:
JButton b4 = new JButton("ok");
// Set the location and size of the button:
b4.setLocation(10, 10);
b4.setSize(100, 26);
// Add the button to the window:
window.add(b4);
// Make the window visible (this is the only way to show the window):
window.setVisible(true);
Hopefully, this helps you out! I remember when I started Java, and I would highly recommend getting as good as possible at non-GUI related stuff first, but if you are ready for Swing, then the code above should work. Best of luck!

Get notified when the user finishes resizing a JFrame

I have a fractal generation component (a subclass of JPanel) inside a JFrame. When the user resizes the window, it takes quite a while to update the fractal to the new size.
I currently have a ComponentListener on the JPanel, but its componentResized event is called every time the user moves the mouse while dragging the window border. This means that the fractal is told to resize many times, and slowly (over the course of a few minutes) grows to the new size.
Is there a way to be notified when the user releases the mouse button, so that I can only change the fractal size when the user has finished resizing?
Others have reported this happening when the listener is attached to the JFrame instead, but this doesn't work for me (and others), for some reason.
Instead of starting the calculation each time you receive a receive-event, you can only start the calculation after you received the last event by using a timer, e.g. in pseudo-code (or at least code which I typed here directly and not in my IDE)
private Timer recalculateTimer = new Timer( 20, myRecalculateActionListener );
constructor(){
recalculateTimer.setRepeats( false );
}
#Override
public void componentResized(ComponentEvent e){
if ( recalculateTimer.isRunning() ){
recalculateTimer.restart();
} else {
recalculateTimer.start();
}
}
And you can still combine this with Andrews suggestion to use an image which you stretch until the calculation has actually finished.
you have look at HierarchyListener, where you can listening for HierarchyEvent with interface to HierarchyBoundsListener
basically nothing wrong with ComponentListener, but you have to wrapping expected events to the Swing Timer, in the case that events repeated, only to call Timer#restart(), output from Swing Timer should be Swing Action
It's a bit late, but it looks like no one found the correct answer. I found that when you call child.updateUI() inside a ComponentListener (componentResized block) of a window, this child resizes it self and updates its content. Using timers is unsafe.

Why setVisible doesn't work?

I have a swing GUI with border layout. in the NORTH I have added some component.
My label component which has GIF icon is invisible lblBusy.setVisible(false);
later a button make it visible like below. Why it does not show up?
btnDownload.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
lblBusy.setVisible(true);
btnCancel.setEnabled(true);
}
});
download = new Download(txtSource.getText(), new File(txtDestination.getText()), textAreaStatus);
download.start();
lblBusy.setVisible(false);
}
});
1) this is EventDispatchThread rellated issue, EDT quite guaranteed that all changes to the GUI would be done on one moment
2) you invoked ActionPerformed from JButton, and untill all events ended your GUI should be freeze or is unresponsible, same for JButton and JLabel in your case
3) better would be redirect reading for File contents to the Backgroung task e.g. SwingWorker or Runnable#Thread then JButton and JLabel will be changed and GUI would be during Background task responsible for Mouse or KeyBoard
or
4) dirty hack split to the two separated Action delayed by javax.swing.Timer, but in this case again untill all events ended your GUI will be freeze or is unresponsible
Most probably because the GUI was packed at a time the label was not visible, so no space was assigned to display it. For anything more definite, post an SSCCE.
It seems to me that you are writing lblBusy.setVisible(true); and after that lblBusy.setVisible(false); in the mouseClicked() method. Since you wanted to make it visible at the click of a button aren't you be using only lblBusy.setVisible(true);, instead of using both.
You can call lblBusy.setVisible(false); from the end of your Download Class though, once it's done doing what it does.
Regards

Categories