label.setText - change with another textarea? - java

Having an issue with some bits of my code.
label1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
label1.setText(-Here i want the button to open up a new "update window, and it will update the label to the text i'll provide in a seperate window);
}
});
Is there any way to do it without without an additional form? Just wanted to add that i have several labels, and i'm not sure on how to start with it.

One approach is to return a result from your update dialog which you can then use to update the text in label1. Here's an example which updates the label text based on the result return from a JOptionPane
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setMinimumSize(new Dimension(200, 85));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label = new JLabel("Original Text");
frame.add(label);
JButton button = new JButton("Click Me");
frame.add(button);
// to demonstrate, a JOptionPane will be used, but this could be replaced with a custom dialog or other control
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(frame, "Should I update the label?", "Test", JOptionPane.OK_CANCEL_OPTION );
// if the user selected 'Ok' then updated the label text
if(result == JOptionPane.OK_OPTION) {
label.setText("Updated text");
}
}
});
frame.setVisible(true);
}
});
}
}
Another approach would be to use an Observer and Observable which would listen for updates and change the label text accordingly. For more on the Observer, take a look at this question: When should we use Observer and Observable

Related

Updating JComboBox while app is running

Using
list0.setModel(new DefaultComboBoxModel(toTable.data));
I can update the whole JComboBox (list0)... but I want to add a few lines to it (need to have few different positions to choose from on my list). When I'm using this command, it makes an update but everytime in first line of JComboBox. That means I will have only one position in my JComboBox in the end.
I tried
list0.setModel(new DefaultComboBoxModel(toTable.data[x]));
but it's not working. Any ideas?
(x-number of line)
I'm, not exactly sure what you're asking, but it seems like you just want to add elements dynamically to a JComboBox. You seem to have the right idea, using the DefaultComboBoxModel. To add a new element the list, use
model.addElement(E object)
See DefaulComboBoxModel for more methods.
Here's a simple example. Just type something in the text field, and hit enter. Here's the important code I used
#Override
public void actionPerformed(ActionEvent ae) {
String text = textField.getText();
model.addElement(text);
comboBox.setSelectedItem(text);
textField.setText("");
}
Here the complete program
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.*;
public class CBoxModelDemo {
public CBoxModelDemo() {
JFrame frame = new JFrame("Combo Box Model");
String[] list = {"Hello 1", "Hello 2", "Hello 3", "Hello 4"};
final DefaultComboBoxModel model = new DefaultComboBoxModel(list);
final JComboBox comboBox = new JComboBox(model);
frame.add(comboBox, BorderLayout.NORTH);
final JTextField textField = new JTextField(30);
frame.add(textField, BorderLayout.SOUTH);
frame.add(new JLabel("Type something, then press enter", JLabel.CENTER));
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
String text = textField.getText();
model.addElement(text);
comboBox.setSelectedItem(text);
textField.setText("");
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CBoxModelDemo();
}
});
}
}

Swing persistent popup

I need to display a swing popup with my custom component. The popup should stay visible, until I hide it myself, but shouldn't get focus.
I have a code written by some other developer that does it in the following way:
popupMenu = new JPopupMenu();
popupMenu.add(myCustomComponent, BorderLayout.CENTER);
popupMenu.setFocusable(false);
popupMenu.setVisible(true);
popupMenu.show(parentComponent, x, y);
This seems to work, but has a bug - when the popup is visible, first mouse click outside the component is consumed by the popup. So I need to click twice to set focus to another component.
How can I fix it? Or what is correct way to make the popup?
UPDATE
At last I've managed to reproduce my problem in short code fragment. Thanks to Guillaume Polet for giving me a starting point.
Here's the code:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TestJPopup {
protected void initUI() {
JFrame frame = new JFrame(TestJPopup.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTextField textField = new JTextField("Some text field");
frame.add(textField, BorderLayout.WEST);
final JButton buttonToHit = new JButton("Hit me");
buttonToHit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(buttonToHit, "You hit the button successfully");
}
});
frame.add(buttonToHit);
frame.setSize(200, 100);
frame.setVisible(true);
final JPopupMenu popup = new JPopupMenu();
popup.add(new JLabel("<html>Hey!<br>I'm the popup window!</html>"),
BorderLayout.NORTH);
popup.setFocusable(false);
popup.setVisible(true);
popup.show(textField, 60, 60);
// I want to activate popup when user clicks in the text field
textField.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (popup != null) {
popup.show(textField, 60, 60);
}
}
});
}
public static void main(String[] args) throws Exception {
Class lnfClass = Class.forName("com.sun.java.swing.plaf.windows.WindowsLookAndFeel", true,
Thread.currentThread().getContextClassLoader());
LookAndFeel feel = (LookAndFeel) lnfClass.newInstance();
UIManager.setLookAndFeel(feel);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestJPopup().initUI();
}
});
}
}
Two critical moments:
Windows look and feel used (with default not reproducible)
Mouse listener attached to text field in main frame
Not an answer, but just an example SSCCE in which I can't currently reproduce the behaviour you described. Maybe start from this code, try to reproduce the error and the edit your post with modified non-working code.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestJPopup {
protected void initUI() {
JFrame frame = new JFrame(TestJPopup.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel leftLabel = new JLabel("Left");
frame.add(leftLabel, BorderLayout.WEST);
final JButton buttonToHit = new JButton("Hit me");
buttonToHit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(buttonToHit, "You hit the button successfully");
}
});
frame.add(buttonToHit);
frame.setSize(500, 400);
frame.setVisible(true);
JPopupMenu popupMenu = new JPopupMenu();
popupMenu.add(new JLabel("<html>A Custom<br>component<br>made to<br> simulate <br>your custom component</html>"),
BorderLayout.NORTH);
JTextField textfield = new JTextField(30);
popupMenu.add(textfield);
popupMenu.setFocusable(false);
popupMenu.setVisible(true);
popupMenu.show(leftLabel, 20, 20);
// Let's force the focus to be in a component in the popupMenu
textfield.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestJPopup().initUI();
}
});
}
}
Not a solution, but:
Looks like a bug to me, even a plain componentPopup exhibits the same mis-behaviour (in winLAF and Nimbus, not in Metal):
JTextField field = new JTextField("some popup owner");
JPopupMenu menu = new JPopupMenu();
menu.add("dummy");
field.setComponentPopupMenu(menu);
Action action = new AbstractAction("hit me!") {
#Override
public void actionPerformed(ActionEvent e) {
LOG.info("got hit!");
}
};
JComponent content = new JPanel();
content.add(new JButton(action));
content.add(field);
for quick research and/or for future readers,
this issue is reproducible and presented for,
a) JPopup
b) JMenu
tested on jdk1.6.0_25 and jdk1.7.0_04,
same issue on WinXp and Win7,
for Look and Feel to SystemLookAndFeel / WindowsLookAndFeel,
Here's a possible workaround with JWindow instead of JPopupMenu, that was proposed by mKorbel in comments:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestJPopup {
protected void initUI() {
final JFrame frame = new JFrame(TestJPopup.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTextField textField = new JTextField("Some text field");
frame.add(textField, BorderLayout.WEST);
final JButton buttonToHit = new JButton("Hit me");
buttonToHit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(buttonToHit, "You hit the button successfully");
}
});
frame.add(buttonToHit);
frame.setSize(200, 70);
frame.setVisible(true);
final JWindow popup = new JWindow();
popup.getContentPane().add(new JLabel("<html>Hey!<br>I'm the popup window!</html>"),
BorderLayout.NORTH);
popup.setLocation(frame.getLocation().x + 60, frame.getLocation().y + 60);
popup.pack();
popup.setFocusable(false);
popup.setVisible(true);
// I want to activate popup when user clicks in the text field
textField.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
if (popup != null) {
popup.setVisible(true);
popup.setLocation(frame.getLocation().x + 60, frame.getLocation().y + 60);
popup.toFront();
}
}
});
textField.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
if (popup != null) {
popup.setVisible(false);
}
}
});
}
public static void main(String[] args) throws Exception {
Class lnfClass = Class.forName("com.sun.java.swing.plaf.windows.WindowsLookAndFeel", true,
Thread.currentThread().getContextClassLoader());
LookAndFeel feel = (LookAndFeel) lnfClass.newInstance();
UIManager.setLookAndFeel(feel);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestJPopup().initUI();
}
});
}
}
Here is the magic line that fixes the problem:
UIManager.put("PopupMenu.consumeEventOnClose", Boolean.FALSE);
I found this after looking into the source code for the BasicPopupMenuUI class. Apparently this behaviour is a deliberate design choice according to the following comments in the code, but it sure feels like a bug to me.
// Ask UIManager about should we consume event that closes
// popup. This made to match native apps behaviour.
By the way, it happens in Java 5 and 6 too.

Java- How to add more textfields by clicking a button?

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).

Detect removal of component

I create a Popup using the PopupFactory.getPopup method. According to the documentation, I am required to call the hide() method on the popup when it is no longer needed.
In my application, the popup is the child of a JLabel which may be removed from the current frame in a number of different situations. (Either the JLabel itself or one of its parent containers is removed.) Rather that calling hide() in every single place (and making the Popup object available in all these places) I would prefer to be able to detect the removal of the JLabel or one of its parent containers.
How can I detect the removal? I naively assumed that the removal of a component meant the removal/hiding of its children, but as the code below shows, the popup survives the removal of the JLabel.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Xyzzy extends JFrame {
static Xyzzy frame;
static JPanel panel;
static JLabel text1;
static JLabel text2;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame = new Xyzzy();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
frame.add(panel);
text1 = new JLabel("text1");
text2 = new JLabel("text2");
panel.add(text1);
frame.add(new JButton(new AbstractAction("Add popup") {
public void actionPerformed(ActionEvent e) {
PopupFactory factory = PopupFactory.getSharedInstance();
Popup popup = factory.getPopup(text1, new JLabel("POPUP"),frame.getX()+300,frame.getY()+300);
popup.show();
}
}));
frame.add(new JButton(new AbstractAction("New label") {
public void actionPerformed(ActionEvent e) {
panel.remove(text1);
panel.add(text2);
panel.revalidate();
}
}));
frame.setSize(600, 600);
frame.setVisible(true);
}
});
}
}
This code creates a JFrame displaying the text "text1" and two buttons. If you press the button labeled "Add popup", a Popup with the text "POPUP" appears in the window. This Popup is a child of text1. Press the "New label" button and "text1" is removed from the display, but the Popup survives.
I need to be able to detect when text1 or the containing panel is removed so that I can hide the popup. I want to avoid adding code where the actual remove() method is called.
You can use HierarchyListener:
public void actionPerformed(ActionEvent e) {
PopupFactory factory = PopupFactory.getSharedInstance();
final Popup popup = factory.getPopup(text1, new JLabel("POPUP"),frame.getX()+300,frame.getY()+300);
text1.addHierarchyListener(new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED
&& (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
popup.hide();
}
}
});
popup.show();
}

action listener to JDialog for clicked button

I have main application where is table with values. Then, I click "Add" button, new CUSTOM (I made it myself) JDialog type popup comes up. There I can input value, make some ticks and click "Confirm". So I need to read that input from dialog, so I can add this value to table in main application.
How can I listen when "confirm" button is pressed, so I can read that value after that?
addISDialog = new AddISDialog();
addISDialog.setVisible(true);
addISDialog.setLocationRelativeTo(null);
//somekind of listener...
//after "Confirm" button in dialog was pressed, get value
value = addISDialog.ISName;
If the dialog will disappear after the user presses confirm:
and you wish to have the dialog behave as a modal JDialog, then it's easy, since you know where in the code your program will be as soon as the user is done dealing with the dialog -- it will be right after you call setVisible(true) on the dialog. So you simply query the dialog object for its state in the lines of code immediately after you call setVisible(true) on the dialog.
If you need to deal with a non-modal dialog, then you'll need to add a WindowListener to the dialog to be notified when the dialog's window has become invisible.
If the dialog is to stay open after the user presses confirm:
Then you should probably use a PropertyChangeListener as has been suggested above. Either that or give the dialog object a public method that allows outside classes the ability to add an ActionListener to the confirm button.
For more detail, please show us relevant bits of your code, or even better, an sscce.
For example to allow the JDialog class to accept outside listeners, you could give it a JTextField and a JButton:
class MyDialog extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
and a method that allows outside classes to add an ActionListener to the button:
public void addConfirmListener(ActionListener listener) {
confirmBtn.addActionListener(listener);
}
Then an outside class can simply call the `addConfirmListener(...) method to add its ActionListener to the confirmBtn.
For example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OutsideListener extends JFrame {
private JTextField textField = new JTextField(10);
private JButton showDialogBtn = new JButton("Show Dialog");
private MyDialog myDialog = new MyDialog(this, "My Dialog");
public OutsideListener(String title) {
super(title);
textField.setEditable(false);
showDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!myDialog.isVisible()) {
myDialog.setVisible(true);
}
}
});
// !! add a listener to the dialog's button
myDialog.addConfirmListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text = myDialog.getTextFieldText();
textField.setText(text);
}
});
JPanel panel = new JPanel();
panel.add(textField);
panel.add(showDialogBtn);
add(panel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static void createAndShowGui() {
JFrame frame = new OutsideListener("OutsideListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDialog extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
public MyDialog(JFrame frame, String title) {
super(frame, title, false);
JPanel panel = new JPanel();
panel.add(textfield);
panel.add(confirmBtn);
add(panel);
pack();
setLocationRelativeTo(frame);
}
public String getTextFieldText() {
return textfield.getText();
}
public void addConfirmListener(ActionListener listener) {
confirmBtn.addActionListener(listener);
}
}
Caveats though: I don't recommend subclassing JFrame or JDialog unless absolutely necessary. It was done here simply for the sake of brevity. I also myself prefer to use a modal dialog for solving this problem and just re-opening the dialog when needed.
Edit 2
An example of use of a Modal dialog:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OutsideListener2 extends JFrame {
private JTextField textField = new JTextField(10);
private JButton showDialogBtn = new JButton("Show Dialog");
private MyDialog2 myDialog = new MyDialog2(this, "My Dialog");
public OutsideListener2(String title) {
super(title);
textField.setEditable(false);
showDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!myDialog.isVisible()) {
myDialog.setVisible(true);
textField.setText(myDialog.getTextFieldText());
}
}
});
JPanel panel = new JPanel();
panel.add(textField);
panel.add(showDialogBtn);
add(panel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static void createAndShowGui() {
JFrame frame = new OutsideListener2("OutsideListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDialog2 extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
public MyDialog2(JFrame frame, String title) {
super(frame, title, true); // !!!!! made into a modal dialog
JPanel panel = new JPanel();
panel.add(new JLabel("Please enter a number between 1 and 100:"));
panel.add(textfield);
panel.add(confirmBtn);
add(panel);
pack();
setLocationRelativeTo(frame);
ActionListener confirmListener = new ConfirmListener();
confirmBtn.addActionListener(confirmListener); // add listener
textfield.addActionListener(confirmListener );
}
public String getTextFieldText() {
return textfield.getText();
}
private class ConfirmListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String text = textfield.getText();
if (isTextValid(text)) {
MyDialog2.this.setVisible(false);
} else {
// show warning
String warning = "Data entered, \"" + text +
"\", is invalid. Please enter a number between 1 and 100";
JOptionPane.showMessageDialog(confirmBtn,
warning,
"Invalid Input", JOptionPane.ERROR_MESSAGE);
textfield.setText("");
textfield.requestFocusInWindow();
}
}
}
// true if data is a number between 1 and 100
public boolean isTextValid(String text) {
try {
int number = Integer.parseInt(text);
if (number > 0 && number <= 100) {
return true;
}
} catch (NumberFormatException e) {
// one of the few times it's OK to ignore an exception
}
return false;
}
}
Why don't you check if your jDialog is visible?
yourJD.setVisible(true);
while(yourJD.isVisible())try{Thread.sleep(50);}catch(InterruptedException e){}
this works, also.
import javax.swing.JOptionPane;
or if you're already swinging
import javax.swing.*;
will have you covered.
After conditional trigger JOptionPane to send your warning or whatever modal message:
JOptionPane.showMessageDialog(
null,
"Your warning String: I can't do that John",
"Window Title",
JOptionPane.ERROR_MESSAGE);
check your options for JOptionPane.* to determine message type.

Categories

Resources