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();
}
});
}
}
Related
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
I'm trying to use the JButton count to count the number of characters entered into the JTextField t. I'm new to Java and GUIs but here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 extends Frame implements ActionListener{
TextField t;
Button count;
int a;
Choice choice;
public GUI1(){
this.t = new TextField("", 30);
this.count = new Button("count");
this.count.addActionListener(this);
JTextField x = new JTextField();
x.setEditable(false);
this.setTitle("Character count");
this.setLayout(new FlowLayout());
this.add(x);
this.add(t);
this.add(count);
this.pack();
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()== this.count)
t.setText(choice.getSelectedItem()+ " " +a);
}
I'm also trying to enter the value in another uneditable JTextField x. Any help is appreciated.
Add this to your code
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
a = t.getText().length();
}
});
OR
You can use lambda expression like this
count.addActionListener(e -> a = t.getText().length());
For More
http://docs.oracle.com/javase/7/docs/api/java/awt/event/ActionListener.html
You need to add a listener
TextField t = new TextField();
Button b = new Button("Count");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
}
});
You can read more about here
http://www.tutorialspoint.com/awt/awt_button.htm
First of all, I recommend you not to use AWT elements, since it brings tons of problems and it has little to no support, instead you can try using Swing components which are a replacement/fix for AWT. You can read more about here. You might also want to read AWT vs Swing (Pros and Cons).
Now going into your problem:
You should avoid extending from JFrame, I might recommend you to create a new JFrame object instead. Here's the reason to why. That being said, you can also remove all your this.t and other calls with this.
I'm glad you're using a Layout Manager!
And now to count the number of characters on your JTextField and set text to your other JTextField you should use this code:
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
Also I fixed your code, I changed AWT elements to Swing ones and added number of cols to your second JTextField so it would appear.
So, here's a running example that I made from your code (And removed Choice choice line since you didn't posted that code):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 {
JTextField t;
JButton count;
int a;
JFrame frame;
public GUI1(){
frame = new JFrame();
t = new JTextField("", 15);
count = new JButton("count");
JTextField x = new JTextField("", 15);
x.setEditable(false);
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
frame.setTitle("Character count");
frame.setLayout(new FlowLayout());
frame.add(x);
frame.add(t);
frame.add(count);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main (String args[]) {
new GUI1();
}
}
When you click on a button you should
String str = t.getText(); // get string from jtextfield
To save the text from the texfield. Then you can use something like:
a = str..length(); // get length of string
x.setText(str + " " + a); //set it to the field
To set it to the JTextField.
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.
I was making a simple text editor where you can set font style,font size, clear all etc. To set font size I added JComboBox and implemented ItemListener. Here is my MainWindow class:
import javax.swing.*;
public class MainWindow extends JFrame{
Editor e = new Editor();
public MainWindow(){
super(".:My Text Editor:.");
getContentPane().add(e);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new MainWindow();
}
});
}
}
Here is my Editor class:
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class Editor extends JPanel{
JPanel optionPanel = new JPanel();
JTextArea editArea = new JTextArea();
JButton boldBtn = new JButton("Bold");
JButton italicBtn = new JButton("Italic");
JButton plainBtn = new JButton("Plain");
JButton clearBtn = new JButton("Clear all");
String [] fontSizes = {"10","11","12","13","14","15","16","17","18","19","20"};
int fontSize;
JComboBox combo = new JComboBox(fontSizes);
public Editor(){
createUI();
addEvents();
}
public void createUI(){
optionPanel.add(boldBtn);
optionPanel.add(italicBtn);
optionPanel.add(plainBtn);
optionPanel.add(combo);
optionPanel.add(clearBtn);
setLayout(new BorderLayout());
add(optionPanel,BorderLayout.NORTH);
add(new JScrollPane(editArea),BorderLayout.CENTER);
setPreferredSize(new Dimension(640,480));
}
public void addEvents(){
boldBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
editArea.setFont(new Font("Sans Serif",Font.BOLD,fontSize));
}
});
italicBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
editArea.setFont(new Font("Sans Serif",Font.ITALIC,fontSize));
}
});
plainBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
editArea.setFont(new Font("Sans Serif",Font.PLAIN,fontSize));
}
});
combo.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
int ind = combo.getSelectedIndex();
System.out.println(ind);
fontSize = Integer.parseInt(fontSizes[ind]);
editArea.setFont(new Font("Sans Serif",Font.PLAIN,fontSize));
}
});
clearBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
editArea.setText("");
}
});
}
}
Now, weird thing what happened is when I put System.out.println(ind); line just to see what index the getSelectedIndex() method returns me. Depending on which item I click, it returns me this:
1
1
0
0
2
2
3
3
Why is this happening? Shouldn't return me just 1 0 2 3? Thanks in advance.
JCombobox fire itemStateChanged twice for SELECTED and DESELECTED that you differentiate with ItemEvent.getStateChanged(). So wrap your code in an if like this:
public void itemStateChanged( ItemEvent event ) {
if( event.getStateChanged() == ItemEvent.SELECTED ) {
// code here
}
}
Whenever you change the selection in a JComboBox, the itemStateChanged event is triggered twice, once for DESELECT of the old selected item and once for SELECT for the new selected item.
If you only want your code to be executed once, just do:
if (e.getStateChange() == ItemEvent.SELECTED) {
...
}
Seems that itemStateChanged is triggered twice. I think that the ItemEvent parameter is not the same each time. Perhaps you should check the event type before doing something.
Sorry I can't check now, but I will do it later if you still need help.
I have a JComboBox shown in the code below. When the program starts its actionPerformed event fires up immediately causing some null pointer exceptions so I want to start with none of the elements selected. However, for some reason it does not work (it always start with displaying "USD/TRY" whatever I do). Anyone has any idea ?
JComboBox comboBox = new JComboBox(new String[]{"USD/TRY", "EUR/TRY", "GBP/TRY"});
comboBox.setSelectedIndex(-1); // doesnt change anything
comboBox.setSelectedIndex(2); // doesnt change anything
comboBox.setSelectedItem(null); // doesnt change anything
UPDATE: Building the combo box like below doesnt change anything either
JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
Here is the SSCCE:
public class MainFrame {
private final JTextArea textArea = new JTextArea();
private IExchangeSource s;
public MainFrame(final IExchangeSource s) {
//build gui
final JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
comboBox.setSelectedIndex(-1); // doesnt change anything
//comboBox.setSelectedIndex(2); // doesnt change anything
JFrame f = new JFrame("Currency Converter");
JPanel p = new JPanel(new BorderLayout());
textArea.setName("textarea");
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
this.s = s;
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String exchange = (String) comboBox.getSelectedItem();
s.getData(exchange);
}
});
p.add(comboBox, BorderLayout.NORTH);
p.add(textArea, BorderLayout.CENTER);
f.setPreferredSize(new Dimension(300, 300));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.add(p);
comboBox.setSelectedIndex(0);
f.setVisible(true);
}
}
Your (incomplete) example invokes
comboBox.setSelectedIndex(0);
right before becoming visible, canceling any previous setting. Set the desired initial index before adding the listener, and don't neglect to start on the EDT, as shown in the sscce below.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class MainFrame {
private final JTextArea textArea = new JTextArea();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MainFrame();
}
});
}
public MainFrame() {
//build gui
final JComboBox comboBox = new JComboBox();
comboBox.addItem("USD/TRY");
comboBox.addItem("EUR/TRY");
comboBox.addItem("GBP/TRY");
JFrame f = new JFrame("Currency Converter");
JPanel p = new JPanel(new BorderLayout());
textArea.setName("textarea");
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
comboBox.setSelectedIndex(-1);
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(comboBox.getSelectedItem() + ": " + e);
}
});
p.add(comboBox, BorderLayout.NORTH);
p.add(textArea, BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setSize(new Dimension(300, 300));
f.add(p);
f.setVisible(true);
}
}
1) add ItemListener instead of ActionListener, but this ItemListener always fired twice events SELECTED and DESELECTED,
myComboBox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
//some stuff
}
}
});
2) your GUI maybe is or isn't created on EventDispashThread, but in this case doesn't matter, you have to delay this method by wraping into invokeLater(), for example
public class MainFrame {
.
.
.
f.setPreferredSize(new Dimension(300, 300));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.add(p);
comboBox.setSelectedIndex(0);
f.setVisible(true);
selectDesiredItem();
}
private void selectDesiredItem() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
comboBox.setSelectedIndex(-1);
}
});
}
3) better would be implements AutoCompete JComboBox / JTextField for Currency Pairs
4) maybe not important but CcyPairs have got four sides by default
Buy BaseCcy
Sell BaseCcy
Buy VariableCcy
Sell VariableCcy
The suggestions so far are good. But sometimes, when things are really convoluted on how Components get constructed, a more direct fix is needed:
subclass the JComboBox (or whatever Swing class is firing the events, JList, etc...)
add a field, private boolean fireEvents = false; Consider making it volatile.
override the relevant fireXXX() methods to check the status of fireEvents
only set fireEvents = true after all construction and initialization is complete
if a "major overhaul" is later called for, such as on loading a new file, new settings, you can set fireEvents back to false while rebuilding everything.