JComboBox popup cell height wrong after call to setSelectedItem() - java

I want a drop-down compobox where the selected element is one-line when its not selected, but when I choose from the drop-down each cell is taller and shows some extra information
This is achieved by the following code:
import java.awt.Component;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
public class ComboJFrame extends javax.swing.JFrame {
private boolean popup;
private javax.swing.JComboBox jComboBox1;
public ComboJFrame() {
initComponents();
}
private void initComponents() {
jComboBox1 = new javax.swing.JComboBox();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new java.awt.FlowLayout());
DefaultComboBoxModel model = new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3",
"Long Long Item 4" });
jComboBox1.setModel(model);
jComboBox1.setRenderer(new DefaultListCellRenderer() {
#Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
System.out.println("rend = " + value);
// if popup is showing we need to make elements tall
if (popup) this.setText("<html>" + value.toString().replaceAll(" ", "<br/>\n"));
return this;
}
;
});
jComboBox1.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
popup = false;
System.out.println("popup = " + popup);
}
public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
popup = false;
System.out.println("popup = " + popup);
}
public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
popup = true;
jComboBox1.invalidate();
System.out.println("popup = " + popup);
}
});
getContentPane().add(jComboBox1);
pack();
model.setSelectedItem("Item 3"); // THIS GIVES THE PROBLEM
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ComboJFrame().setVisible(true);
}
});
}
}
The problem is what if I programatically select an item, like
model.setSelectedItem("Item 3");
then the JCombobox gets the cell height wrong and displays
This is only happening on when selecting items programatically. If I select an item by manually clicking with the mouse and then opens the popup againd then it goes away.
Ive seen this on Ubuntu Linux 14.04 using Java 7 and Java 8.
I'd like to get it fixed, and to know whether Windows and Mac has the same problem.
Strange thing is, that if I add items to the model in a ways such that setSelectedItem is never called, like:
model.removeAllElements();
model.addElement("Item 3");
model.insertElementAt("Item 2",0);
model.insertElementAt("Item 1",0);
model.addElement("Long Item 4");
then the problem doesen't appear
Another workaround seems to be to select the item and then re-set the model:
model.setSelectedItem("Item 3");
jComboBox1.setModel(new DefaultComboBoxModel());
jComboBox1.setModel(model);
The above is test code, the real application is for Apertium machine translation, and the combobox looks like this:

Related

Java JCombobox Update issue

I am trying to change JCombobox items list (towns) depending on the value of the other JCombobox (city). When I change the value in the city list, it changes the items in the towns list. But there are 2 issues.
The updated list (towns) shows double of the items but when click on it then it shows the correct number of items as shown in the first screenshot.
The updated list doesn't allow me to choose one of the item, it only select the first item
here is my code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Testing extends JFrame implements ActionListener {
public static void main(String[] args )
{
new Testing();
}
JComboBox cb,cb1,cb2;
JFrame f;
JLabel label1,label2;
JButton b1;
JTextField name,ID,birth;
Testing(){
f=new JFrame("Information Example");
label1 = new JLabel("Please input your information below");
label1.setBounds(10, 20, 260, 30);
f.add(label1);
String question[]={"Calculate my Age","When do I drive","When do I vote"};
String city[]={"Asimah","Ahmadi","Hawalli"};
name= new JTextField("NAME");
name.setBounds(10,50,264,25);
f.add(name);
ID= new JTextField("CIVIL ID");
ID.setBounds(10,80,264,25);
f.add(ID);
birth= new JTextField("DATE OF BIRTH");
birth.setBounds(10,110,264,25);
f.add(birth);
cb=new JComboBox(question);
cb.setBounds(50, 150,180,20);
f.add(cb);
b1= new JButton("Get");
b1.setBounds(100,250,60,20);
f.add(b1);
cb1=new JComboBox(city);
cb1.setBounds(10, 200,120,20);
f.add(cb1);
cb2=new JComboBox();
cb2.setBounds(150, 200,120,20);
f.add(cb2);
f.setLayout(null);
f.setSize(300,400);
f.setVisible(true);
cb.addActionListener(this);
cb1.addActionListener(this);
cb2.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent event)
{
if(cb1.getSelectedIndex() == 0)
{
cb2.removeAllItems();
cb2.addItem("Rawdhah");
cb2.addItem("Abdahll");
}
else if(cb1.getSelectedIndex() == 1)
{
cb2.removeAllItems();
cb2.addItem("Siddiq");
cb2.addItem("Aljabryha");
}
else
{
cb2.removeAllItems();
cb2.addItem("Fintas");
cb2.addItem("Abdahll");
}
}
}
So, basically, the combination of removeAllItems and addItem is causing the JComboBox to generate a ActionEvent, but only for the first new item added.
You should isolate your functionality to only perform certain actions based on the source of the event, for example...
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == cb1) {
if (cb1.getSelectedIndex() == 0) {
cb2.removeAllItems();
System.out.println(cb2.getItemCount());
cb2.addItem("Rawdhah");
cb2.addItem("Abdahll");
} else if (cb1.getSelectedIndex() == 1) {
cb2.removeAllItems();
cb2.addItem("Siddiq");
cb2.addItem("Aljabryha");
} else {
cb2.removeAllItems();
cb2.addItem("Fintas");
cb2.addItem("Abdahll");
}
}
}
You could also make use of the actionCommand property, but the above is the simpler, immediate solution

How to change selected index in JComboBox when refreshing panel?

I am making a simple sudoku and when I want to start a new game, I reload the panel. I first remove it and then add it to the frame. The problem is that I can choose the difficulty for new game, but it always selects the first "Easy" dificulty, not selected. So if I change it in JComboBox to "medium", when page is reloaded it will load the game with "Easy", not "medium".
What should I do so my refreshed panel will accept changed difficulty?
Here are methods that are used for this in my program:
JComboBox difficulty = new JComboBox();
DefaultComboBoxModel difficultyModel = new DefaultComboBoxModel();
difficultyModel.addElement("Easy");
difficultyModel.addElement("Medium");
difficultyModel.addElement("Hard");
difficulty.setModel(tezavnostModel);
difficulty.setSelectedIndex(0);
difficulty.setPreferredSize(new Dimension(100, 25));
newGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainFrame.reloadSudokuBoard();
sudokuBoard.pickDifficulty(getDifficulty()));
}
});
public String getDifficulty() {
return (String)difficulty.getSelectedItem();
}
public void board(int[][] numbers, int zeros) {
int numberZeros = setDifficulty(sudokuForm.getDifficulty());
int[][] boardNumbers = gameNumbers();
public void reloadSudokuBoard() {
String newDifficulty = (sudokuForm.getDifficulty());
remove(sudokuBoard);
sudokuBoard.board(sudokuBoard.gameNumbers(), sudokuBoard.setDifficulty(newDifficulty ));
add(sudokuBoard, BorderLayout.WEST);
SwingUtilities.updateComponentTreeUI(sudokuBoard);
}
Hope this helps.
public void reloadSudokuBoard() {
int index = difficulty.getSelectedIndex();
String newDifficulty = (sudokuForm.getDifficulty());
remove(sudokuBoard);
sudokuBoard.board(sudokuBoard.gameNumbers(), sudokuBoard.setDifficulty(newDifficulty ));
add(sudokuBoard, BorderLayout.WEST);
SwingUtilities.updateComponentTreeUI(sudokuBoard);
difficulty.setSelectedIndex(index);
}
Before removing components, you can use the getSelectedIndex to get the index that was selected. After the element have been added, the setSelectedIndex will fix it

how to get selected row when click on combobox in table

I have a table and at each row i have a combox of operator from which we can choose any operator and value1 field value 2 field. COMBO BOX DEFAULT OPERATOR IS " EQUAL TO".so my question is when u click on combobox in any row i should get the value of the selected row and get the operator which i am selecting such that i can perform some operation based on selected operator....
Or else if i change the combobox operator from in between to equal to i should get clear the value 2 field....
Help me get out of this..
You should have an event to know item in the combo is clicked.
Like this:
combo.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
//doSomething();
}
});
You have three methods to get current item selected:
Will get the index of the item is order number.
int selectedIndex = myComboBox.getSelectedIndex();
-or-
Will get item selected with Object. You can do many method contains in this Object.
Object selectedObject = myComboBox.getSelectedValue();
-or-
Will get real values of item selected with string type.
String selectedValue = myComboBox.getSelectedValue().toString();
You can see full example code at here (from #secario member):
import java.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;
public class MyWind extends JFrame{
public MyWind() {
initialize();
}
private void initialize() {
setSize(300, 300);
setLayout(new FlowLayout(FlowLayout.LEFT));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTextField field = new JTextField();
field.setSize(200, 50);
field.setText(" ");
JComboBox comboBox = new JComboBox();
comboBox.setEditable(true);
comboBox.addItem("item1");
comboBox.addItem("item2");
//
// Create an ActionListener for the JComboBox component.
//
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
//
// Get the source of the component, which is our combo
// box.
//
JComboBox comboBox = (JComboBox) event.getSource();
Object selected = comboBox.getSelectedItem();
if(selected.toString().equals("item1"))
field.setText("30");
else if(selected.toString().equals("item2"))
field.setText("40");
}
});
getContentPane().add(comboBox);
getContentPane().add(field);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MyWind().setVisible(true);
}
});
}
}

Unchecking checkbox does not undo command?

Its my first time programming checkboxes; I figured out how to make a checkbox appear, and do a command when checked. However, when the box is unchecked, instead of undoing the command, it instead does the command a second time. How can I undo the command when unchecking the box?
Code: (instantiation of checkboxes)
negA = new JCheckBox("Neg");
negA.addActionListener(this);
negA.setActionCommand("A-5");
tossupA = new JCheckBox("Tossup");
tossupA.addActionListener(this);
tossupA.setActionCommand("A10");
powerA = new JCheckBox("Power");
powerA.addActionListener(this);
powerA.setActionCommand("A05");
Command:
public void actionPerformed(ActionEvent e)
{
//get the String value from the button pressed
String result = e.getActionCommand();
char team = result.charAt(0);
//set text on screen to reflect new score
String screenText = "Team "+(team)+"'s total score for this tossup: ";
//add score to subtotal and show on screentext
if(team=='A'){
teamATempScore += Integer.parseInt(result.substring(1));
screenText += teamATempScore;
}
//and now for B
else if(team=='B'){
teamBTempScore += Integer.parseInt(result.substring(1));
screenText += teamBTempScore;
}
When the box is unchecked, I want the score to decrement by the amount that it was incremented, but instead the score just increments again :(
Thanks!
(yes, if you were wondering, this is a scorekeeping program for a game of Quizbowl) :D
The listener just checks to see if the checkBox was clicked -- It doesn't check if it went from unchecked to checked, or vice versa.
Use the .isSelected() method to determine whether the checkbox is checked or not after it becomes clicked.
For example:
if (negA.isSelected())
{
//the checkbox was checked after they clicked it, do something
}
else
{
//the checkbox was unchecked after they clicked it, do something else
}
You have to check the state of the control and then either increment or decrement. The compiler cannot auto generate the reverse of your code.
To check the state of the checkbox, you call the isSelected() method on it like in the example below.
import javax.swing.JOptionPane;
public class CheckboxExample extends javax.swing.JFrame {
private javax.swing.JCheckBox jCheckBox1;
public CheckboxExample() {
jCheckBox1 = new javax.swing.JCheckBox();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new java.awt.FlowLayout());
jCheckBox1.setText("CheckMe");
jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
jCheckBox1ActionPerformed(evt);
}
});
getContentPane().add(jCheckBox1);
pack();
}
// this will get called when the state of the checkbox changes
private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {
if(jCheckBox1.isSelected()) {
JOptionPane.showMessageDialog(this, "Checked", "Message",
JOptionPane.INFORMATION_MESSAGE);
}
else {
JOptionPane.showMessageDialog(this, "Unchecked", "Message",
JOptionPane.INFORMATION_MESSAGE);
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new CheckboxExample().setVisible(true);
}
});
}
}

How to keep the popup menu of a JComboBox open on populating it?

I have a JComboBox on my Panel. One of the popup menu items is 'More' and when I click that I fetch more menu items and add them to the existing list. After this, I wish to keep the popup menu open so that the user realizes that more items have been fetched however, the popup closes. The event handler code I am using is as follows
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == myCombo) {
JComboBox selectedBox = (JComboBox) e.getSource();
String item = (String) selectedBox.getSelectedItem();
if (item.toLowerCase().equals("more")) {
fetchItems(selectedBox);
}
selectedBox.showPopup();
selectedBox.setPopupVisible(true);
}
}
private void fetchItems(JComboBox box)
{
box.removeAllItems();
/* code to fetch items and store them in the Set<String> items */
for (String s : items) {
box.addItem(s);
}
}
I do not understand why the showPopup() and setPopupVisible() methods are not functioning as expected.
add the following line in the fetchItems method
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
box.showPopup();
}
}
If u call selectedBox.showPopup(); inside invokelater also it will work.
overwrite the JCombobox setPopupVisible metod
public void setPopupVisible(boolean v) {
if(v)
super.setPopupVisible(v);
}
jComboBox1 = new javax.swing.JComboBox(){
#Override
public void setPopupVisible(boolean v) {
super.setPopupVisible(true); //To change body of generated methods, choose Tools | Templates.
}
};
I found some simple solution to always keep popup open. It may be useful with some custom JComboBox'es, like the one I have in my project, but is a little hacky.
public class MyComboBox extends JComboBox
{
boolean keep_open_flag = false; //when that flag ==true, popup will stay open
public MyComboBox(){
keep_open_flag = true; //set that flag where you need
setRenderer(new MyComboBoxRenderer()); //our spesial render
}
class MyComboBoxRenderer extends BasicComboBoxRenderer {
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
if (index == -1){ //if popup hidden
if (keep_open_flag) showPopup(); //show it again
}
}
}
}

Categories

Resources