how to add labels without them overlapping each other - java

I wanted to add 2 labels in my JDialog; one label will have animated gif ; other will have text. How to add these two so that they dont overlap? I don't want to hardcode their positions. I want the program to make the inherent adjustments.
Thanks in Advance
code:
JLabel l2=new JLabel("");
try {
Image img = ImageIO.read(getClass().getResource("resources/wait_animated.gif"));
ImageIcon imgnew=new ImageIcon("G:\\my java\\DesktopApplication1\\src\\desktopapplication1\\resources\\wait_animated.gif");
l2.setIcon(imgnew);
imgnew.setImageObserver(l2);
}
catch (IOException ex) {
}
l2.setLocation(300,300);
JDialog d=new JDialog();
JLabel l=new JLabel("Please Wait While Processing is Done... ");
JDesktopPane dp=new JDesktopPane();
dp.setPreferredSize(new Dimension(300,50));
l.setPreferredSize(new Dimension(250,50));
l2.setPreferredSize(new Dimension(20,20));
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.setTitle("Wait dialog");
d.add(l);
d.add(l2);

Use a LayoutManager (such as FlowLayout) to arrange your labels. It’s hard to say without any more details.

You do realize that one label can have both text and an image, right? E.G.
import javax.swing.*;
import java.net.URL;
class AnimatedGifInLabelWithText {
public static void main(String[] args) throws Exception {
final URL url = new URL("http://pscode.org/media/starzoom-thumb.gif");
Runnable r = new Runnable() {
public void run() {
ImageIcon ii = new ImageIcon(url);
JLabel label = new JLabel("Zoom!", ii, SwingConstants.CENTER);
JOptionPane.showMessageDialog(null, label);
}
};
SwingUtilities.invokeLater(r);
}
}

Related

How do I use a gif file in a Java program?

I'm trying to add a .gif image to a JButton, but can't seem to get the image to load when i run the code. I've included a screenshot. Included is the frame that's created. I'd really appreciate any help that can be provided. Stack is telling me I can't enter images yet, so it created a link for it. I'm also going to enclose the actual code here:
package java21days;
import javax.swing.*;
import java.awt.*;
public class ButtonsIcons extends JFrame {
JButton load, save, subscribe, unsubscribe;
public ButtonsIcons() {
super("Icon Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
//Icons
ImageIcon loadIcon = new ImageIcon("load.gif");
ImageIcon saveIcon = new ImageIcon("save.gif");
ImageIcon subscribeIcon = new ImageIcon("subscribe.gif");
ImageIcon unsubscribeIcon = new ImageIcon("unsubscribe.gif");
//Buttons
load = new JButton("Load", loadIcon);
save = new JButton("Save", saveIcon);
subscribe = new JButton("Subscribe", subscribeIcon);
unsubscribe = new JButton("Unsubscribe", unsubscribeIcon);
//Buttons To Panel
panel.add(load);
panel.add(save);
panel.add(subscribe);
panel.add(unsubscribe);
//Panel To A Frame
add(panel);
pack();
setVisible(true);
} //end ButtonsIcon Constructor
public static void main(String[] arguments) {
ButtonsIcons ike = new ButtonsIcons();
}
} //end ButtonsIcon Class
enter image description here
The easiest way is.
Label or Jbutton and what ever else supports HTML 3.5
JLabel a = new JLabel("");
add that to your container.
Haven't figured out how to enter code sorry

How to Add text to JTextArea

Im creating a programme using java. I want the user to enter some text, then push the button so the text entered shows in the label. However, I have 2 problems. First, the text are isn´t displaying when I execute the app. Second, I don´t know how to allow the user to type in the area. Im new in java so that´s why Im asking. Here is the code. Thank you.
import javax.swing.*;
import java.awt.event.*;
class Boton extends JFrame implements ActionListener {
JButton boton;
JTextArea textArea = new JTextArea();
JLabel etiqueta = new JLabel();
public Boton() {
setLayout(null);
boton = new JButton("Escribir");
boton.setBounds(100, 150, 100, 30);
boton.addActionListener(this);
add(boton);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == boton) {
try {
String texto = textArea.getText();
etiqueta.setText(texto);
Thread.sleep(3000);
System.exit(0);
} catch (Exception excep) {
System.exit(0);
}
}
}
}
public class Main{
public static void main(String[] ar) {
Boton boton1 =new Boton();
boton1.setBounds(0,0,450,350);
boton1.setVisible(true);
boton1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Problems:
You never add the JTextArea into your GUI, and if it doesn't show, a user cannot directly interact with it.
You are calling Thread.sleep on the Swing event thread, and this will put the entire application to sleep, meaning the text that you added will not show.
Other issues include use of null layouts and setBounds -- avoid doing this.
Solutions:
Set the JTextArea's column and row properties so that it sizes well.
Since your JTextArea's text is going into a JLabel, a component that only allows a single line of text, I wonder if you should be using a JTextArea at all. Perhaps a JTextField would work better since it allows user input but only one line of text.
Add the JTextArea to a JScrollPane (its viewport actually) and add that to your GUI. Then the user can interact directly with it. This is most easily done by passing the JTextArea into a JScrollPane's constructor.
Get rid of the Thread.sleep and instead, if you want to use a delay, use a Swing Timer. check out the tutorial here
For example:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Main2 {
public static void main(String[] args) {
// create GUI in a thread-safe manner
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
BotonExample mainPanel = new BotonExample();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class BotonExample extends JPanel {
private JLabel etiqueta = new JLabel(" ");
private JButton boton = new JButton("Escribir");
// jtext area rows and column properties
private int rows = 5;
private int columns = 30;
private JTextArea textArea = new JTextArea(rows, columns);
public BotonExample() {
// alt-e will activate button
boton.setMnemonic(KeyEvent.VK_E);
boton.addActionListener(e -> {
boton.setEnabled(false); // prevent button from re-activating
String text = textArea.getText();
etiqueta.setText(text);
// delay for timer
int delay = 3000;
Timer timer = new Timer(delay, e2 -> {
// get current window and dispose ofit
Window window = SwingUtilities.getWindowAncestor(boton);
window.dispose();
});
timer.setRepeats(false);
timer.start(); // start timer
});
// create JPanels to add to GUI
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
topPanel.add(new JLabel("Etiqueta:"));
topPanel.add(etiqueta);
JPanel bottomPanel = new JPanel();
bottomPanel.add(boton);
JScrollPane scrollPane = new JScrollPane(textArea);
// use layout manager and add components
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
}
textarea.setText("Text"); // this will insert text into the text area
textarea.setVisable(true); // this will display the text area so you can type in it
textarea.setSize(500,500); // set size of the textarea so it actually shows
The user should be able to type in the TA when it is displayed and just do a getText to pull the text

unable to create new JLabel with html in method

I am trying to make a fix-width label in Java, which I find a solution here.
But I fail whenever I put any inside a label -- while the label is create inside a method.
my code is here :
public class testingGui
JFrame myframe = new JFrame("Some title here");
Container pane_ctn = myframe.getContentPane();
public static void main(String[] args){
testingGui gui = new testingGui();
gui.init();
}
private void init(){
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myframe.setSize(320, 480);
myframe.setVisible(true);
pane_ctn.setLayout(new BoxLayout(pane_ctn, BoxLayout.PAGE_AXIS));
JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
pane_ctn.add(lable);
}
}
The line JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>"); will never run. (and making pane_ctn into blank even if there's other UI element added)
However I found that it works while the label is create as a field, like this :
public class testingGui {
JFrame myframe = new JFrame("Some title here");
Container pane_ctn = myframe.getContentPane();
JLabel lable = new JLabel("<html>Java is a general-purpose computer programming language</html>");
// I just cut the whole line and paste here, nothing else has changed.
/* ... */
}
So here is my question :
How is the correct way to create a label with html inside a method call ? I need it created on the fly. Thank you.
Edit :
Thank you ybanen giving me a good answer, and others helpers, too.
Now I can creating Label that looking good.
It happens because you try to modify the GUI after it has been displayed. In your case, the best is to create the whole GUI and then to show the frame:
public class TestingGui {
public static void main(final String[] args) {
final JLabel label = new JLabel("<html>Java is a general-purpose computer programming language</html>");
final JFrame frame = new JFrame("Test");
final Container contentPane = frame.getContentPane();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
frame.getContentPane().add(label);
frame.setSize(320, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
However, if you really need to add the label after the GUI has been displayed, you have to follow several rules:
Any modification of the GUI must be done in the Event Dispatching Thread (EDT).
After a container has been displayed, it has been laid out. So if you want to add a new component inside, you have to force a layout of its content (using revalidate() and then repaint()).
I need it created on the fly.
Why? Or rather, why not create and add the label at start-up, then set the text when needed?
My example is a To-Do list, I have a array to store the data, the label is create inside a for loop.
Use a JList!
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class EditableList {
private JComponent ui = null;
String[] items = {
"Do 100 push ups.",
"Buy a book.",
"Find a cat.",
"Java is a general purpose computer language that is concurrent, "
+ "class based, object oriented and specifically designed to have "
+ "as few implementation dependencies as possible.",
"Conquer the world."
};
EditableList() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
JList<String> list = new JList<String>(items);
list.setCellRenderer(new ToDoListRenderer());
list.getSelectionModel().setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
ui.add(new JScrollPane(list));
JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER));
controls.add(new JButton("Edit Selected"));
controls.add(new JButton("Delete Selected"));
ui.add(controls, BorderLayout.PAGE_END);
}
class ToDoListRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(
JList<? extends Object> list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
JLabel l = (JLabel)c;
l.setText("<HTML><body style='width: 250px;'>" + value.toString());
return l;
}
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
EditableList o = new EditableList();
JFrame f = new JFrame("To Do List");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}

How to change image of a JLabel in another thread

I want to make a Swing version TimeBomber, which means when time is counted down to 1 the Bomb will blow up! I have two images, images.png for a bomb in normal state, bomber.jpg for a bomb that has blown up. Apparently I need to change the images.png(which is already in an JLabel) to bomber.jpg when i==1; But I have no idea of how to change the pic location content in ImageIcon and as the change happens in anonymous inner class, so change value became difficult as final type var is not modifiable unless you call function.
public class TimeBomber {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
//create Jframe
JFrame app = new JFrame("Time Bomber");
//create JPanel
final JPanel panel = new JPanel();
//JLabel with first Picture
JLabel pic = new JLabel(new ImageIcon("images.png"));
pic.setSize(100, 100);
//Label for displaying time digit
final JLabel label = new JLabel("");
label.setLocation(200, 250);
//create another thread
Thread time = new Thread(){
public void run(){
for(int i=10; i>0; i--){
if(i==1){
JLabel picSecond = new JLabel(new ImageIcon("Bomber.jpg"));
//<--Fact is I dont want to create another JLabel, I want to modify the pic location content in JLabel pic.
picSecond.setSize(100, 100);
panel.add(picSecond);
}
label.setText("Time: "+i);
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
//add every component to where it belongs
panel.add(pic);
panel.add(label);
app.add(panel);
app.setSize(300, 400);
app.setVisible(true);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
time.start();
}
}
Wrap the code in SwingUtilities.invokeAndWait() (or SwingUtilities.invokeLater())
if(i==1){
JLabel picSecond = new JLabel(new ImageIcon("Bomber.jpg"));//<--Fact is I dont want to create another JLabel, I want to modify the pic location content in JLabel pic.
picSecond.setSize(100, 100);
panel.add(picSecond);
}
label.setText("Time: "+i);
TO avoid recreation of the JLabel make it the class' field and add to panel just once. Then use picSecond.setIcon() to update the image.
BTW it's better to have kind of images cache to avoid image recreation on each step.

Using multiple classes with the same JFrame

I've been in a bit of a pickle here. I've been ripping my hair out over how to accomplish such a task. For my International Bacc I have to fill out certain criteria for my Program dossier and one of them is using inheritance and passing parameters etc. I'm in the stage of making my prototype and wanted to achieve the effect of using multiple JPanels within the same JFrame. I've achieved this rather crudely with setVisivble() and adding both panels to the JFrame. I understand that I can use the CardLayout for this and will probably implement it as soon as possible.
All in all what I'm trying to achieve is that I have a login button the loads the other jpanel, is there a way of doing this in separate classes? Because when I seem to use the myframe.add(new mypanelClass()) it creates an entirely new JFrame! Essentially the miniclass I have in this file I want to separate out into another class. Also how can I make a logout button on the other panel bring me back to the login screen from another class? Thanks in advance for any help.
Here's my code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
class Menu extends JFrame
{
JFrame container = new JFrame();
JPanel screen = new JPanel();
JPanel screenBase = new JPanel();
Image ProgramIcon = Toolkit.getDefaultToolkit().getImage("imageIco.png");
ImageIcon logo = new ImageIcon ("Logo.png");
JLabel icon = new JLabel(logo);
JLabel username = new JLabel("Username");
JLabel password = new JLabel("Password");
JTextField user = new JTextField(18);
JPasswordField pass = new JPasswordField(18);
JButton login = new JButton("Login");
JLabel errorInfo = new JLabel("");
int WIDTH = 800;
int HEIGHT = 500;
JPanel screen2 = new JPanel();
JButton logout = new JButton("Logout");
ImageIcon title = new ImageIcon("title.png");
JLabel header = new JLabel(title);
public static void main(String[] args)
{
try {UIManager.setLookAndFeel("com.nilo.plaf.nimrod.NimRODLookAndFeel");}
catch (UnsupportedLookAndFeelException e){ JOptionPane.showMessageDialog(null, "GUI Load Error: Unsupported");}
catch (ClassNotFoundException e) { JOptionPane.showMessageDialog(null, "GUI Load Error: NimROD Missing");}
catch (InstantiationException e) { JOptionPane.showMessageDialog(null, "GUI Load Error: Instantiation Missing");}
catch (IllegalAccessException e) { JOptionPane.showMessageDialog(null, "GUI Load Error: Illegal Access"); }
Menu admin = new Menu();
}
public Menu()
{
container.setIconImage(ProgramIcon);
container.setTitle("Login");
container.setSize(WIDTH,HEIGHT);
container.setResizable(false);
container.setVisible(true);
container.add(screen);
container.setDefaultCloseOperation(EXIT_ON_CLOSE);
screen.add(username);
screen.add(password);
screen.add(user);
screen.add(pass);
screen.add(login);
screen.add(icon);
screen.setLayout(null);
Dimension iconSize = icon.getPreferredSize();
Dimension usernameSize = username.getPreferredSize();
Dimension passwordSize = password.getPreferredSize();
Dimension loginSize = login.getPreferredSize();
Dimension userSize = user.getPreferredSize();
Dimension passSize = pass.getPreferredSize();
username.setBounds(252,170,usernameSize.width,usernameSize.height);
password.setBounds(495,170,passwordSize.width,passwordSize.height);
user.setBounds(180,200,userSize.width,userSize.height);
pass.setBounds(420,200,passSize.width,passSize.height);
login.setBounds(375,250,loginSize.width,loginSize.height);
icon.setBounds(250,50,iconSize.width,iconSize.height);
ButtonHandler handle = new ButtonHandler();
login.addActionListener(handle);
new BaseScreen();
}
public class BaseScreen
{
public BaseScreen()
{
container.add(screen2);
screen2.setLayout(null);
screen2.add(logout);
screen2.add(header);
screen2.setVisible(false);
Dimension headerSize = header.getPreferredSize();
Dimension logoutSize = logout.getPreferredSize();
logout.setBounds(720,440,logoutSize.width,logoutSize.height);
header.setBounds(0,0,headerSize.width,headerSize.height);
setDefaultCloseOperation(EXIT_ON_CLOSE);
ButtonHandler handle = new ButtonHandler();
logout.addActionListener(handle);
}
}
public class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == login)
{
if((user.getText().equals("")) && (pass.getText().equals("")))
{
errorInfo.setText("Please enter username and password");
screen.add(errorInfo);
errorInfo.setForeground(Color.RED);
Dimension errorInfoSize = errorInfo.getPreferredSize();
errorInfo.setBounds(300,300,errorInfoSize.width,errorInfoSize.height);
}
if((user.getText().equals("admin"))&&(pass.getText().equals("password")))
{
screen.setVisible(false);
screen2.setVisible(true);
container.setTitle("Menu");
user.setText("");
pass.setText("");
}
}
if (event.getSource() == logout)
{
screen2.setVisible(false);
screen.setVisible(true);
container.setTitle("Login");
}
}
}
}
You'll need to stop instantiating a JFrame within that class that extends JFrame, that's 2 JFrames right there. Write JFrame container = this; then use your IDE's inline feature to inline the container field.
If BaseScreen needs access to the JFrame 'this' you can pass that value into BaseScreen's constructor and BaseScreen can store that value as a field. There's no magic 'linking the classes together', you tell one object about another one by passing values around. If what I'm saying is unfamiliar you'll need to visit the constructors section of the Java tutorial - http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

Categories