Im making a jframe with two components. A list and a button. The list starts at 0 and everytime i press the button it increases by 1. So if i press the button, the value in the jlist changes from 0 to 1.
My question is, how can I add an integer to a jlist? (i tried the setText method just in case - only works for Strings)
Thanks
EDIT: PART OF MY CODE (ActionListener)
increase.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
counter++;
System.out.println(counter);
listModel.addElement(counter);
// listModel.clear();
}
});
I'm assuming that you want to add an int item to the JList, meaning a new int pops up in the list's display each time the button is pushed. You can create a JList<Integer> and add Integers (or boxed ints) to the JList's model, usually using listModel.addElement(myInteger).
If you need to clear previous elements, do so before adding the element, not after. For example,
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Foo2 extends JPanel {
private DefaultListModel<Integer> dataModel = new DefaultListModel<>();
private JList<Integer> intJList = new JList<>(dataModel);
public Foo2() {
add(new JScrollPane(intJList));
intJList.setFocusable(false);
add(new JButton(new AbstractAction("Add Int") {
private int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
dataModel.clear(); // if you need to clear previous entries
dataModel.addElement(count);
count++;
}
}));
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Foo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Foo2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Related
I have made a program, which allows users to have as many text boxes as they want in which they can input a text string. I want to save each user input into different variables. I also want to print all of those variable or access the data stored in them when ever I want.
If you can help me that it would be really nice, thanks in advance. If you have any question please let me know in comment and I will answer them.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI
{
private JFrame frame;
private JButton button;
private JTextField tfield;
private String nameTField;
private int count;
public GUI()
{
nameTField = "tField";
count = 0;
}
private void displayGUI()
{
frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1, 2, 2));
button = new JButton("Add Another");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
tfield = new JTextField();
tfield.setName(nameTField + count);
count++;
frame.add(tfield);
frame.revalidate();
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 GUI().displayGUI();
}
});
}
}
What you're looking for is an ArrayList<String>.
Declare a private ArrayList<String> userStrings; where you have your private fields.
In your constructor, add userStrings = new ArrayList<String>();
And then when you receive a string, just add it into your list with userStrings.add(myNewString). (Use your String instead of myNewString)
ArrayLists are indexed like an array, but using a method get, so you can get the first item in your list by using userStrings.get(0).
This is my code:
package saaaaaaaaaa;
public class xd {
public static JFrame frame = new JFrame("Halo");
public static JLabel lab = new JLabel("learning ",JLabel.CENTER);
public static JButton but = new JButton("but");
public static JButton but1 = new JButton("butt");
public static CustomAct act = new CustomAct(lab);
public static void main(String[] args) {
but.addMouseListener(act);
but1.addMouseListener(act);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 480);
frame.setLayout(new BorderLayout());
frame.setResizable(false);
frame.add(lab, BorderLayout.CENTER);
frame.add(but, BorderLayout.SOUTH);
frame.add(but1, BorderLayout.NORTH);
}
}
This is extra class for mouse click, I need 2x mouse click for 2 buttons.
package saaaaaaaaaa;
public class CustomAct implements MouseListener {
private static final long serialVersionUID = 1L;
private String halo = "this is ";
private int getClickCount = 1;
private JLabel lab;
private JLabel lab1;
public CustomAct(JLabel lab) {
this.lab = lab;
}
public void mouseClicked(MouseEvent e) {
if(e.getSource()==but) {
lab.setText("cau"+getClickCount++);
}
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
}
How can I do a multiple buttons for each different mouse click action?
How can I get ID of button, which is used?
This is if(e.getSource()==but) --- but cannot be resolved to a variable
I really don't know how to do it.
First of all you don't use a MouseListener to listen for clicks on a button.
Instead you should be using an ActionListener.
If the Action for each button is unrelated, then you need to create a separate ActionListener for each button with each ActionListener containing the specific code for the button. For example the "Add" and "Subtract" methods of a simple calculator would require a separate Action.
If the Action is related, then you would create a generic ActionListener that can be shared by the buttons. For example, entering digits 0, 1, 2, ... could be a shared ActionListener. For a working example of this approach check out: How to add a shortcut key for a jbutton in java?
Also, you should NOT be using static variables. Instead you should be create a class that extends a JPanel where you define all your variables and Swing components. The ActionListeners would also be defined in that class so they can update the labels as required.
I've created an array of buttons, added them to my frame and (inefficiently) created action listeners for each of them which open a JOptionPane to take an input and add it to a String array, yet the text on the array button does not update after the popup is closed, while a button not part of an array updates its text fine.
The string array grabs the data from the JOptionPane fine, it just wont update the button's caption.
In my full program I'm writing ar_str_vals to a .xml file, and it can properly save and load the array, and surprisingly the array buttons properly set their text but only at the beginning of my program.
package wtf;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Wtf extends JFrame{
JButton[] ar_btn_vals = new JButton[2];
String[] ar_str_vals = new String[2];
public Wtf(){
super("Title");
setLayout(null);
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
constructor();
actionlisteners();
}
public void constructor(){
for (int x = 0;x<=1;x++){
ar_btn_vals[x] = new JButton();
ar_btn_vals[x].setText(ar_str_vals[x]);
ar_btn_vals[x].setBounds(5,(100 * x)+20, 100,40);
ar_btn_vals[x].setVisible(true);
add(ar_btn_vals[x]);
System.out.println(ar_str_vals[x]);
}
}
public void actionlisteners(){
for (int x=0;x<=1;x++){
switch (x){
case 0:
ar_btn_vals[0].addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ar_btn_vals0ActionPerformed(evt);
}
});
break;
case 1:
ar_btn_vals[1].addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ar_btn_vals1ActionPerformed(evt);
}
});
break;
}
}
}
private void ar_btn_vals0ActionPerformed(java.awt.event.ActionEvent evt) {
JFrame frm_val0change = new JFrame();
String newval = JOptionPane.showInputDialog(frm_val0change, "Enter new Button 1 Value");
ar_str_vals[0] = newval;
constructor();
}
private void ar_btn_vals1ActionPerformed(java.awt.event.ActionEvent evt) {
JFrame frm_val1change = new JFrame();
String newval = JOptionPane.showInputDialog(frm_val1change, "Enter new Button 2 Value");
ar_str_vals[1] = newval;
constructor();
}
public static void main(String[] args) {
Wtf frame = new Wtf();
}
}
I'm aware that this isn't as efficient as it could be, but I've got limited time to finish this and I have absolutely no idea why this isn't working properly.
This is also my first time asking a question, so please have mercy if I've formatted anything wrong.
As MadProgrammer said, all I had to do was update the button text in my action listener instead of calling the constructor again.
I am trying to do something similiar as cookie clicker, nevertheless it does not work. I have not managed to create a "counter" that shows the amount of clicks. This is what I got hitherto, any ideas?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Stocks implements ActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Stocks().createGui();
}
});
}
public void createGui() {
JFrame frame = new JFrame("Clicker");
frame.setSize(175, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
frame.add(panel);
frame.getContentPane().add(panel, BorderLayout.WEST);
GridBagConstraints c = new GridBagConstraints();
JButton button1 = new JButton("Click this");
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(40, 40, 40, 40);
panel.add(button1, c);
button1.addActionListener(this);
}
You can have a variable int cnt = 0; inside your Stocks class and everytime someone clicks on the button you increase cnt by one in the actionPerformed method.
As you said, your actionPerformed method is empty, meaning you coded your application to do nothing when the button is clicked.
This answer is assuming you only have one component using that class as ActionListener:
In earlier versions of Java, it would be:
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
Java 8, however, provides us with Lambda expressions, and allows this to be a lot easier (with less code).
button1.addActionListener(event -> counter++);
You don't need to create an implementation of ActionListener, Java 'll take care of this for you. If you write your code like this, it is even easier if you have more components using that class as ActionListener, since you won't be able to mix them up.
If you need them to call shared parts of code, you can still call methods from within the Lambda expression
button1.addActionListener(event -> {callSharedMethod(); counter++;});
In this example, first the shared method will be called. After that, the counter will be augmented, which will/might only be done from clicking this button.
You should first add a counter as a attribute of your class `Stock``
public class Stocks {
private int counter;
Initialize counter variable with 0:
public static void main(String[] args) {
this.counter = 0;
And then add the action listener to increase the variable:
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
});
I'm surprised nobody proposed resolving this by inheritance. The button you want is a JButton but slightly more specialized (it must count the number of clicks performed on itself).
public final class CountButton extends JButton {
private int counter = 0;
public CountButton(String text) {
super(text);
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
}
});
}
public final int getCounter() {
return counter;
}
}
I have a problem with the focus listener implemented by CustomTextField class. The focus listener is only called when another Swing component is getting the focus. But If I move the JFrame istelf by dragging it with the mouse, the focusLost() method is never called (in other words, it doesn´t seem that the focus is shifting from CustomTextField to JFrame).
EDIT: The solution of my question is below:
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class ScrollFocus extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ScrollFocus();
}
});
}
public ScrollFocus() {
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<String> values = new Vector<>();
values.add("a");
values.add("b");
values.add("c");
values.add("d");
values.add("e");
JComboBox<String> comboBox = new JComboBox<>(values);
JScrollPane scrollPane = new JScrollPane(comboBox);
this.add(scrollPane, BorderLayout.NORTH);
CustomTextField customTextField = new CustomTextField();
this.add(customTextField, BorderLayout.CENTER);
JButton button = new JButton("press");
final JPopupMenu menu = new JPopupMenu("Menu");
menu.add(new JMenuItem("Test"));
button.setComponentPopupMenu(menu);
this.add(button, BorderLayout.SOUTH);
pack();
setVisible(true);
}
class CustomTextField extends JTextField implements FocusListener {
private CustomPopup customPopup = new CustomPopup();
public CustomTextField() {
this.addFocusListener(this);
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "VK_UP");
this.getActionMap().put("VK_UP", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
setPopupSize();
customPopup.show(CustomTextField.this, CustomTextField.this.getX(), CustomTextField.this.getY() + CustomTextField.this.getHeight());
customPopup.setSelectedIndex(0);
}
});
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "VK_DOWN");
this.getActionMap().put("VK_DOWN", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
setPopupSize();
customPopup.show(CustomTextField.this, CustomTextField.this.getX(), CustomTextField.this.getY() + CustomTextField.this.getHeight());
customPopup.setSelectedIndex(0);
}
});
}
public void setPopupSize() {
customPopup.setPopupSize(new Dimension(this.getWidth(), 110));
}
#Override
public void focusGained(FocusEvent e) {
}
#Override
public void focusLost(FocusEvent e) {
}
class CustomPopup extends JPopupMenu {
String[] values = new String[]{"Value1", "Value2", "Value3", "Value4", "Value5", "Value6", "Value7",
"Value8","Value9", "Value10", "Value11", "Value12", "Value13", "Value14", "Value15", "Value16",};
JList<String> list = new JList<>(values);
JScrollPane scrollPane = new JScrollPane(list);
public int index = 0;
public CustomPopup() {
this.setLayout(new GridLayout(0,1));
this.add(scrollPane);
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
if(customPopup.index > 0)
customPopup.setSelectedIndex(--customPopup.index);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
if(customPopup.index < customPopup.getListSize()-1)
customPopup.setSelectedIndex(++customPopup.index);
}
}
});
this.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
index=0;
}
});
pack();
}
public void setSelectedIndex(int index) {
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
requestFocus();
}
public int getListSize() {
return values.length;
}
}
}
}
//customPopup.setVisible(true);
customPopup.show((JComponent)e.getSource(), 0, 20);
You should be using the show(...) method to show the popup. This must add some listeners to the popup so you will no longer need the FocusListener on the text field.
However, now this is a different problem. The text field loses focus so the Action never get invoked. That would be ok, but the JList never gains focus so it doesn't respond to the up/down keys unless you click on the list box first. I'm not sure what the problem is here.
Maybe you can try to make the popup, scrollpane and list all non-focusable so that focus remains on the text field?
'Focus', which is admittedly a slightly ambiguous term, generally applies to a component, not to an entire window. We think of the "window with focus", but I think what we really mean is "the current window, the one which contains the focus." I would not expect focus_lost to be called if I moved the window (aka JFrame) itself.
Another way to think of it; if I had a text field, clicked in it, and typed a letter or two, I would see those letters in that text field. If I then moved the window slightly and typed another letter or two, I would still expect those letters to appear in that field. It still has focus, and never lost it.