change value of a dynamically created JLabel (Java) - java

I want to create a number of labels dynamically, so I found this code:
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panel.add(new JLabel("Label"));
panel.validate();
}
});
It works great, but I can't change the text it's showing because I can't call it. For example like: label.setText("Labeltext Changed!");
So my question is: How can I give each dynamically created label a name, so I can change their values?

Store your labels in a List<JLabel>.
private List<JLabel> labels = new ArrayList<>();
...
public void yourMethod() {
...
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JLabel newLabel = new JLabel("Label");
labels.add(newLabel);
panel.add(newLabel);
panel.validate();
}
});
...
}
Then to get it just do something like labels.get(0).setText("my text");.
Note that you can shorten the ActionListener code with a lambda expression:
button.addActionListener(arg0 -> {
JLabel newLabel = new JLabel("Label");
labels.add(newLabel);
panel.add(newLabel);
panel.validate();
});

Related

Why is my showMessageDialog displaying twice?

I am working on a simple counter swing app. I'm trying to make it so when you click the check box, it will stay on the top and display a message dialog being "On Top" or "Not On Top".
However, when I click the checkbox after compiling and running, both of the messages display, and after clicking OK on both messages, the checkbox isn't even enabled. If I were to remove the showMessageDialog, it would still function properly, but I want to learn how to appropriately implement this.
Thank you in advance. Here is all of the code for the program:
public Class Counter {
JFrame frame;
JPanel panel;
JButton button, clear;
JTextField textC;
JLabel label;
JCheckBox cbox;
boolean topC = false;
int icount = 0;
String scount;
String topStatus = "";
public Counter() {
gui();
setActions();
}
public void gui() {
frame = new JFrame("Counter Program");
panel = new JPanel();
label = new JLabel("Counter");
textC = new JTextField();
textC.setPreferredSize(new Dimension(72,28));
textC.setEditable(false);
button = new JButton("Click");
clear = new JButton("Clear");
cbox = new JCheckBox("Top");
frame.setSize(350,80);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(panel);
panel.add(label);
panel.add(textC);
panel.add(button);
panel.add(clear);
panel.add(cbox);
frame.setVisible(true);
}
public void setActions() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
icount++;
scount = Integer.toString(icount);
textC.setText(scount);
}
});
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
icount = 0;
textC.setText("");
}
});
cbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
topC = !topC;
if (topC) {
topStatus = "Top";
}
else topStatus = "Not Top";
frame.setAlwaysOnTop(topC);
JOptionPane.showMessageDialog(frame, topStatus, "Top Setting", 1);
}
});
}
public static void main(String[]args) {
new Counter();
}
}
An ItemListener generates two events, one for the selection and one for the unselection (and vice versa). Read the section from the Swing tutorial on How to Write an ItemListener for more information and working exmaples if you really want to use an ItemListener.
Otherwise, use an ActionListener instead, it will only generate a single event.

Understanding How to Add A JButton to a JTable

I am trying to implement some buttons in my JTable. I have been looking at
this example.
What I don't understand is this constructor:
public ButtonEditor(JCheckBox checkBox) {
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
What does the JCheckBox have to do with anything? There is no JCheckBox displayed anywhere nor does it seem it is even relevant to the example. TIA.
The DefaultCellEditor usage here is more of a hack for using Buttons as it accepts only JCheckBox, JComboBox and JTextField.
If you really want to implement for JButton, you can also do like,
class ButtonEditor extends AbstractCellEditor
implements javax.swing.table.TableCellEditor,
javax.swing.tree.TreeCellEditor
Else you can update your implementation for using a constructor with JButton as parameter or default constructor,
Approach 1
public ButtonEditor() {
super(new JCheckBox());
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
and can be accessed as,
table.getColumn("Button").setCellEditor(
new ButtonEditor());
Approach 2
public ButtonEditor(JButton button) {
super(new JCheckBox());
this.button = button;
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
This approach provides better clarity and usage of button component outside the cell editor too,
JButton button=new JButton();
table.getColumn("Button").setCellEditor(
new ButtonEditor(button));
It is because class ButtonEditor extends DefaultCellEditor, and constructor of DefaultCellEditor in your example looks like this DefaultCellEditor​(JCheckBox checkBox)

Disabling a Jbutton in java when another Jbutton is pressed

My code is:
public FactoryWindow()
{
getPreferredSize();
setTitle("Bounce");
JPanel buttonPanel = new JPanel();
add(comp, BorderLayout.CENTER);
addButton(buttonPanel, "Circle", new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
comp.addShape();
}
});
addButton(buttonPanel, "Machine", new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
comp.addMachine();
}
});
addButton(buttonPanel, "Close", new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
});
add(buttonPanel, BorderLayout.SOUTH);
pack();
}
This is a constructor. the class extends JFrame
public void addButton(Container c, String title, ActionListener listener)
{
JButton button = new JButton(title);
c.add(button);
button.addActionListener(listener);
}
I want to be able to disable the Shape button when I press the machine button
How would I go about doing that?
I know there is Something like buttonName.setEnabled(false); but I cannot figure out how to use it in this context.
You will need a reference to the button you are trying to disable, this will require you to change your code slightly...
First, you need your addButton method to return the button it created...
public JButton addButton(Container c, String title, ActionListener listener) {
JButton button = new JButton(title);
c.add(button);
button.addActionListener(listener);
return button;
}
Then you need to assign the result to a variable...
JButton cirlce = null;
JButton machine = null;
cirlce = addButton(buttonPanel, "Circle", new ActionListener() {
public void actionPerformed(ActionEvent event) {
comp.addShape();
}
});
Then you can access it from your ActionListener...
machine = addButton(buttonPanel, "Machine", new ActionListener() {
public void actionPerformed(ActionEvent event) {
comp.addMachine();
circle.setEnabled(false);
}
});
Now, if you're using Java 6 (and I think Java 7), it will complain that the button should be final, but this won't work based on the way you have your code set up. Instead, you will need to make circle and machine instance fields in order to be able to access them from within the ActionListener context

Java Swing Components Drawing Over Multiple Panels

I'm having an issue that I've been trying to solve all day. I have two panels inside a frame and in one panel I've added components. The components, however, seem to have an equal hierarchy value as the panel and as such treat the Frame as the parent instead, ignoring where the panels are located. Basically the components are added to one panel but display on top of both across the whole frame. (Unfortunately I can't post a picture at this time, please up vote the question to allow me to if needed). What is causing this and how can I fix it?
The relevant code:
JFrame arranFrame = new JFrame("Edit Arrangement");
arranFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel grid = new JPanel();
JPanel tools = new JPanel();
grid.setSize(700, 600);
tools.setSize(200, 600);
JLabel widthLabel = new JLabel("Width");
JLabel depthLabel = new JLabel("Depth");
JLabel columnLabel = new JLabel("Columns");
final JTextField rowWidthInput = new JTextField(30);
final JTextField rowsInput = new JTextField(30);
final JTextField columnInput = new JTextField(30);
rowWidthInput.setSize(40, 30);
rowsInput.setSize(40, 30);
columnInput.setSize(40, 30);
rowWidthInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartWidth = Integer.parseInt(rowWidthInput.getText());
}
});
rowsInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartRows = Integer.parseInt(rowsInput.getText());
}
});
columnInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartColumns = Integer.parseInt(columnInput.getText());
}
});
//Enter button for grid modifying creation and setup
JButton enterButton = new JButton("Enter");
enterButton.setSize(180, 50);
enterButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
chartWidth = Integer.parseInt(rowWidthInput.getText());
chartRows = Integer.parseInt(rowsInput.getText());
chartColumns = Integer.parseInt(columnInput.getText());
}
});
//Save Arrangement button creation and setup
JButton saveButton = new JButton("Save Arrangement");
saveButton.setSize(180, 50);
saveButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SaveArrangement(userDocuments + "\\TSA Seating Chart\\Arrangements\\Period" + period + ".txt");
}
});
tools.setBackground(Color.RED); //Temp for visualization where the panes are
tools.add(widthLabel);
tools.add(rowWidthInput);
tools.add(depthLabel);
tools.add(rowsInput);
tools.add(columnLabel);
tools.add(columnInput);
tools.add(enterButton);
tools.add(saveButton);
arranFrame.getContentPane().add(grid);
arranFrame.getContentPane().add(tools);
//Finalize the GUI
arranFrame.pack(); //Pack all the content together
arranFrame.setSize(900, 600); //Set the size of the window
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
arranFrame.setLocation(dim.width/2-arranFrame.getSize().width/2, dim.height/2-arranFrame.getSize().height/2);
arranFrame.setVisible(true); //Display the seatingFrame

Default button in JFrame is not firing when the enter key is being pressed

I have a JFrame with three JButtons on it. I have set txtSearch (a JTextField component) to have the focus when JFrame loads. One of the buttons is set as the default button. This is my code:
private void formWindowOpened(java.awt.event.WindowEvent evt)
{
// btnRefresh.setMnemonic(KeyEvent.VK_R); // Even if this line
// is not commented, but
// still the event wouldn't fire.
this.getRootPane().setDefaultButton(btnRefresh);
}
When it loads, the button is just selected, but it did nothing when the Enter key was being pressed. How do I correctly implement it?
btnRefresh.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnRefreshActionPerformed(evt);
}
});
private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {
JOptionPane.showMessageDialog(this, "Pressed!");
// Other codes here (Replace by JOptionPane)
}
What component has focus when the JFrame comes up? I ask because some components "eat" the Enter key event. For example, a JEditorPane will do that.
Also, when you assign an ActionListener to JTextField, the ActionListener will be called instead of the DefaultButton for the root pane. You must choose either to have an ActionListener or a DefaultButton, but you can't have both fire for the same JTextField. I'm sure this applies to other components as well.
I don't see what you are doing incorrectly from what is posted. Here is a short example that works. Perhaps it will reveal something useful to you.
import java.awt.BorderLayout;
public class ExampleFrame extends JFrame
{
private JPanel m_contentPane;
private JTextField m_textField;
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
ExampleFrame frame = new ExampleFrame();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ExampleFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
m_contentPane = new JPanel();
m_contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
m_contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(m_contentPane);
m_textField = new JTextField();
m_contentPane.add(m_textField, BorderLayout.NORTH);
m_textField.setColumns(10);
JButton btnNewButton = new JButton("Default");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(ExampleFrame.this, "Default.");
}
});
m_contentPane.add(btnNewButton, BorderLayout.CENTER);
JButton btnNewButton_1 = new JButton("Not default");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(ExampleFrame.this, "Not default.");
}
});
m_contentPane.add(btnNewButton_1, BorderLayout.WEST);
m_textField.requestFocus();
getRootPane().setDefaultButton(btnNewButton);
}
}

Categories