I have one JLabel and one button, the JLabel displays the number of times the button has been pressed, however, I cant figure how to update the JLabel displaying the number of button presses.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class SimpleGui {
private JFrame f = new JFrame("Basic GUI"); // create Frame
int pressed = 0; // tracks number of button presses.
JLabel label1 = new JLabel("You have pressed button " + pressed + "times.");
private JButton start = new JButton("Click To Start!");
public SimpleGui() {
// Setup Main Frame
f.getContentPane().setLayout(new GridLayout(0, 1));
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
calculate();
}
});
// Add components
f.add(label1);
f.add(start);
// Allows the Swing App to be closed
f.addWindowListener(new ListenCloseWdw());
}
public class ListenMenuQuit implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
public class ListenCloseWdw extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public void launchFrame() {
// Display Frame
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack(); // Adjusts panel to components for display
f.setVisible(true);
}
public static void main(String args[]) {
PrimeTime gui = new PrimeTime();
gui.launchFrame();
}
public void calculate() {
pressed++;
label1 = new JLabel("You have pressed button " + pressed + "times.");
// update the GUI with new jLabel
f.repaint();
}
}
The issue is that you are creating a new, different JLabel that is not show in the panel.
do
public void calculate(){
pressed++;
this.label1.setText("You have pressed button " + pressed + "times.");
}
Change label1 = new JLabel("You have pressed button " + pressed + "times."); to label1.setText("You have pressed button " + pressed + "times.");
You only call calculate() when the button start is clicked. So you can move that method into the ActionListener for the button. And by calling setText on the JLabel, you don't have to call repaint. Normally you don't have to call repaint in Swing. E.g. change your code to something like this instead:
final JLabel label1 = new JLabel("You have pressed button " + pressed + "times.");
private JButton start = new JButton(new AbstractAction("Click To Start!") {
public void actionPerformed(ActionEvent e) {
pressed++;
label1.setText("You have pressed button " + pressed + "times.");
}
});
Try and understand this code, here i use an icon to set the label's image and the getIcon method of Label's to change the icon of previous label using setIcon method.
Icon picLabelicon new ImageIcon(img); /* setting the icon initially */
JLabel picLabel = new JLabel();
picLabel.setIcon(picLabelicon);
Now you have set the icon initially now lets change it dynamically
JLabel modify = new JLabel(new ImageIcon(newimg)); /* new label you wanted to use */
picLabelicon=modify.getIcon();
picLabel.setIcon(picLabelicon);
revalidate();
repaint();
Related
I tried searching for some sort of interactive JLabel. I want it to look like this:
I'm not sure what this is called or where I could find info on displaying this. I want it to print a refreshed number when the +/- is pressed. I have it working to print on the eclipse console but am unsure how to get it to print to the JFrame.
Here is some of the code:
String input = JOptionPane.showInputDialog("Please enter the number of laps.");
numLaps = Integer.parseInt(input);
//frame creation
JFrame f = new JFrame("Number of Laps");
f.setSize(550, 450);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(null);
// label creation
JLabel label = new JLabel("You entered " + numLaps + " laps. Press + to add a lap. Press - to subtract a lap.", SwingConstants.CENTER);
label.setBounds(0,0,500,300);
f.add(label);
//display window
f.setVisible(true);
//button creation add
JButton add = new JButton ("+");
add.setBounds(350,250,50,50);
add.setPreferredSize(new Dimension(50,50));
add.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
// what happens when button is pressed
//numLaps++;
addToLap();
System.out.println(numLaps);
}
});
f.add(add);
//button creation subtract
JButton sub = new JButton ("-");
sub.setBounds(100,250,50,50);
sub.setPreferredSize(new Dimension(50,50));
sub.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
// what happens when button is pressed
//numLaps--;
subToLap();
System.out.println(numLaps);
}
});
f.add(sub);
& the add/sub methods:
private static void addToLap() {
// TODO Auto-generated method stub
numLaps++;
}
private static void subToLap() {
// TODO Auto-generated method stub
numLaps--;
}
You could try the following:
private int numLaps = 0 // Or the number you want initialize with
Then in your methods should assing the numLaps value to the JLabel like this:
this.myLabel.setText(String.valueOf(numLaps));
I hope it helps.
I am writing a GUI program in Java. The GUI consists of 9 buttons titled H. In run mode, when the mouse clicks on any button, that button should change the heading to T. I have a MouseListener code watching out for the clicks. But I have no way of finding out based on the mouse clicks that I need to change that particular button. Any help is appreciated.
Below is my code.
package flippingcoins;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FlippingCoins extends JFrame
{
public FlippingCoins()
{
JPanel p = new JPanel();
p.setLayout(new GridLayout(3,3,1,1));
JButton jbt1=new JButton("H");
p.add(jbt1);
JButton jbt2=new JButton("H");
p.add(jbt2);
JButton jbt3=new JButton("H");
p.add(jbt3);
JButton jbt4=new JButton("H");
p.add(jbt4);
JButton jbt5=new JButton("H");
p.add(jbt5);
JButton jbt6=new JButton("H");
p.add(jbt6);
JButton jbt7=new JButton("H");
p.add(jbt7);
JButton jbt8=new JButton("H");
p.add(jbt8);
JButton jbt9=new JButton("H");
p.add(jbt9);
add(p);
}
public static void main(String[] args) //Main program begins here.
{
FlippingCoins frame = new FlippingCoins();//Instantiating an object.
frame.setTitle("Head or Tails");//Setting the frame title.
frame.setSize(300,300);//Setting the size.
frame.setLocationRelativeTo(null);//Setting the location.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Default closing options.
frame.setVisible(true);//Setting visibility to true.
}//End of main program.
static class ChangeTiles extends JPanel
{
public ChangeTiles()
{
addMouseListener(new MouseAdapter()//Creating a listener
{
public void mouseClicked(MouseEvent e)//When the mouse is clicked.
{
int x=e.getX();
int y=e.getY();
System.out.println("x= "+ x + "y= "+y);
}
}
);
}
}
That's not the good strategy. Instead, add an ActionListener to every button. Not only will it be much easier, but users will then also be able to use their keyboard to click the buttons.
Also, consider using an array or list of buttons. That will allow using loops instead of copying and pasting the same code 9 times.
public FlippingCoins() {
final JPanel p = new JPanel();
p.setLayout(new GridLayout(3, 3, 1, 1));
for (int i = 0; i < 9; i++) {
final JButton jbt = new JButton("H");
jbt.setName("" + i);
jbt.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
jbt.setText("T");
System.out.println(jbt.getName());
}
});
p.add(jbt);
}
setContentPane(p);
}
Some notes:
use loops for repetitive tasks
listeners have to be added to the widget they should listen to
do not use MouseListeners for JButton, there is ActionListener
Alternative for JLabel:
public FlippingCoins2() {
final JPanel p = new JPanel();
p.setLayout(new GridLayout(3, 3, 1, 1));
for (int i = 0; i < 9; i++) {
final JLabel jlb = new JLabel("H", SwingConstants.CENTER);
jlb.setBorder(BorderFactory.createLineBorder(Color.blue));
jlb.setName("" + i);
jlb.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
jlb.setText("T");
System.out.println(jlb.getName());
}
});
p.add(jlb);
}
setContentPane(p);
}
This is how you should do it:
JButton jbt1=new JButton("H");
jbt1.addActionListener(new ButtonListener());
//add ButtonListener to all of the other buttons
//Somewhere in your code:
public class ButtonListener extends ActionListener {
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
source.setText("T");
}
}
This will be easy if you add an ActionListener. Inside the actionPerformed code you can make it print out which button was clicked.
getSource()
Returns: The object on which the Event initially occurred.
you can call getSource() on the ActionEvent generated by the ActionPerformed method. I haven't tried this but sounds like you can easily find out which button was clicked.
I have a JComboBox with 12 different selections, and depending on what is selected I want the question (JLabel) to change matching the selection. I've tried an if statement to see what is selected and if it matches what should be selected, then the question changes accordingly, but the JLabel never really changes under an circumstance.
Code
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Window extends JFrame{
private static final long serialVersionUID = 1L;
public Window(){
super("Area Finder v1.0");
BufferedImage image = null;
try {
image = ImageIO.read(getClass().getClassLoader().getResource("images/areafinder.png"));
} catch (IOException e) {
e.printStackTrace();
}
super.setIconImage(image);
setSize(400, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel();
JLabel Instr = new JLabel("What would kind of area would you like to find?");
String[] areaChoices = {"Circle", "Square", "Rectangle", "Triangle", "Trapezoid", "Parallelogram", "Hexagon", "Rhombus", "Pentagon", "Polygon", "Ellipse", "Sector"};
final JComboBox<?> choiceBox = new JComboBox(areaChoices);
final Object isSelected = choiceBox.getSelectedItem();
choiceBox.setToolTipText("Select which one you want to find the area of!");
choiceBox.setSelectedIndex(0);
final JLabel q = new JLabel("");
final JTextField inputFromUser = new JTextField("");
JButton findArea = new JButton("Find Area");
/* Question Changer*/
/*End of Question Changer*/
findArea.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0){
if(isSelected == "Circle"){
double radius = Double.parseDouble(inputFromUser.getText());
double area = 3.14 * (radius * radius);
JOptionPane.showMessageDialog(null, "Your Area is " + area);
}else if(isSelected == "Square"){
}
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(15,15,15,15);
panel.add(Instr);
panel.add(choiceBox);
panel.add(findArea);
panel.add(q);
panel.add(inputFromUser);
add(panel);
}
}
EDIT: So I did a few tests with System.out.println(); and I figured out it's calling all the items at once, but the one that's selected is being called first.
Example:
choiceBox.addItemListener(new ItemListener(){
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getItem() == "Circle"){
System.out.println("Circle selected");
}else if(e.getItem() == "Square"){
System.out.println("Square selected");
}
}
});
Prints out "Circle Selected Square Selected" if you select circle, but "Square Selected Circle Selected" if you select Square.
Add an ItemListener to the JComboBox to react when the selection changes.
Also, when you do this:
Object isSelected = choiceBox.getSelectedItem();
... you are just getting the selected value at that time; you aren't magically binding the isSelected variable to update whenever the combobox updates. You need to call getSelectedItem() again if you want the new value.
try adding an action listener to the JComboBox
choiceBox.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//put the code here
}
});
Change the text of the JLabel
label.setText("Changed text");
Tell the container to relayout.
frame.invalidate();
frame.repaint();
This makes sure that the frame is redrawn to show the changed label. To know when the combo box has changed it's selection, add an ActionListener like this.
combo.addActionListener (new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
label.setText(combo.getText());
frame.invalidate();
}
});
I have created a frame in Java which has some textfields and buttons in it. Assuming that user wants more textfields (for example to add more data), I want to put a button and when a user clicks the button, then a new textfield should appear. then user can fill data in it and again by clicking that button another textfield should appear.
How can I do this ? What code I need to write for the button to show more and more text fields by clicking button?
Thank you !
It would be wise that instead of adding components to your JFrame directly, you add them to a JPanel. Though related to your problem, have a look at this small example, hopefully might be able to give you some hint, else ask me what is out of bounds.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JFrameExample
{
private JFrame frame;
private JButton button;
private JTextField tfield;
private String nameTField;
private int count;
public JFrameExample()
{
nameTField = "tField";
count = 0;
}
private void displayGUI()
{
frame = new JFrame("JFrame Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1, 2, 2));
button = new JButton("Add JTextField");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
tfield = new JTextField();
tfield.setName(nameTField + count);
count++;
frame.add(tfield);
frame.revalidate(); // For JDK 1.7 or above.
//frame.getContentPane().revalidate(); // For JDK 1.6 or below.
frame.repaint();
}
});
frame.add(button);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new JFrameExample().displayGUI();
}
});
}
}
Supposing that you have a main container called panel and a button variable button which is already added to panel, you can do:
// handle the button action event
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// create the new text field
JTextField newTextField = new JTextField();
// add it to the container
panel.add(newTextField);
panel.validate();
panel.repaint();
}
});
When adding the new text field, you may need to mention some layout related characteristics, depending on the layout manager you are using (for instance if you use GridBagLayout, you will need to specify the constraints).
I have in my app a chat component which has a JTextArea on it.
Now, how can I add an ActionListener-like event for a specific text (like student://xxxx)?
So when I click on that text (student://xxxx) something will happen.
Thank you.
Here try this small program, try to click at the start of student://, that will pop up a message Dialog
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TextAreaExample extends JFrame
{
private JTextArea tarea = new JTextArea(10, 10);
private JTextField tfield = new JTextField(10);
private void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tarea.setText("Hello there\n");
tarea.append("Hello student://");
JScrollPane scroll = new JScrollPane(tarea);
tfield.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
tarea.append(tfield.getText() + "\n");
}
});
tarea.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent me)
{
int x = me.getX();
int y = me.getY();
System.out.println("X : " + x);
System.out.println("Y : " + y);
int startOffset = tarea.viewToModel(new Point(x, y));
System.out.println("Start Offset : " + startOffset);
String text = tarea.getText();
int searchLocation = text.indexOf("student://", startOffset);
System.out.println("Search Location : " + searchLocation);
if (searchLocation == startOffset)
JOptionPane.showMessageDialog(TextAreaExample.this, "BINGO you found me.");
}
});
getContentPane().add(scroll, BorderLayout.CENTER);
getContentPane().add(tfield, BorderLayout.PAGE_END);
pack();
setLocationByPlatform(true);
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TextAreaExample().createAndDisplayGUI();
}
});
}
}
No, don't even consider this since ActionListeners are for JButtons or anything else derived from AbstractButton but not for JTextComponents (except for JTextFields). Perhaps you want a MouseListener.
Having said this, perhaps you'll be better off with two text components, a JTextArea to display all responses, including the user's, and right below this in a BorderLayout.SOUTH type of position, a JTextField to allow the user to enter text into the chat. Then give that JTextField an ActionListener (this is legal) so that "enter" will actuate the listener.
Edit 1
You state:
Well I have that jtextfield , the text in it is being sent to the server and server sends the message to all clients which appears in the JTextArea. But my problem is here: I want to popup a window when someone clicks on a student://id text .
Yeah, looking at your comments, my vote is for you to display the chats not in a JTextArea but rather in a JList, one with a SelectionListener. You can then respond easily to mouse click events, and will more easily get useful information from the "line" clicked on (if you fill the JList with smart objects). You will need to write a custom cell renderer that allows multiple lines of text to be displayed, probably one that shows a JTextArea, but the tutorial on JLists will get you started on this.
Is hitting ENTER instead of mouse-click ok?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class StudentID extends JFrame implements ActionListener
{
private static final String progname = "StudentID 0.1";
private JTextField student;
private JTextArea feedback;
private JButton exit;
public StudentID ()
{
super (progname);
JPanel mainpanel = new JPanel ();
mainpanel.setLayout (new BorderLayout ());
this.getContentPane ().add (mainpanel);
student = new JTextField ("student://");
exit = new JButton ("exit");
student.addActionListener (this);
exit.addActionListener (this);
feedback = new JTextArea ();
mainpanel.add (student, BorderLayout.NORTH);
mainpanel.add (feedback, BorderLayout.CENTER);
mainpanel.add (exit, BorderLayout.SOUTH);
setSize (400, 400);
setLocation (100, 100);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
setVisible (true);
}
public void actionPerformed (final ActionEvent e)
{
SwingWorker worker = new SwingWorker ()
{
protected String doInBackground () throws InterruptedException
{
String cmd = e.getActionCommand ();
if (cmd.equals ("exit"))
{
System.exit (0);
}
else if (cmd.matches ("student://[0-9]+"))
{
feedback.setText ("student found: " + cmd.replaceAll ("student://([0-9]+)", "$1"));
}
else
{
feedback.setText ("cmd: " + cmd);
}
return "done";
}
protected void done ()
{
feedback.setText (feedback.getText () + "\ndone");
}
};
worker.execute ();
}
public static void main (final String args[])
{
Runnable runner = new Runnable ()
{
public void run ()
{
new StudentID ();
}
};
EventQueue.invokeLater (runner);
}
}