Java combo box model and get selected item - java

The code below shows a problem I'm having with combo actions. The getSelectedItem() is fired multiple times instead of just at selection. Simply loading the frame calls the method 3 times. Each click on the combo box is a call, even if its just for the dropdown and not the actual selection. Clicking inside the editable text area also triggers the getSelectedItem() method. Is there a way to filter this event?, or an alternate way to validate data on the box model level?
public class SSCCE {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame aframe = new JFrame();
Combo _combo = new Combo();
_combo.addElement("This");
_combo.addElement("That");
JComboBox _box = new JComboBox(new Combo());
_box.setEditable(true);
aframe.add(_box);
aframe.setVisible(true);
}
static class Combo extends DefaultComboBoxModel{
public Combo(){
}
int i = 0;
#Override
public Object getSelectedItem() {
System.out.println("Get selected Item" + i);
i++;
return super.getSelectedItem();
}
}
}

See this tutorial on how to use JComboBox, specifically the section on handling events. You should add an ActionListener to your combobox. It will be triggered when the user actually makes a gesture indicating that their selection is confirmed.

You have look at ItemListener or ActionListener added to the JComboBox

getSelectedItem() indeed fires multiple times, as well as the action event. For an editable combo box the action fires once for comboboxchanged, and once for comboboxedited. I've set up the validation that is not specific to end item in the getSelectedItem, and moved the rest into a filtered action event for comboboxchanged. I've completely ignored comboboxedited event.

Related

Object won't display in JTable from event in another class

I'm a little ignorant when it comes to events in Java, so I'm working on a project to help rectify that. As such, I am working on a project that is basically a pizzeria POS program. There's the main GUI, with the pre-configured "meal" options. I click on those, and their price and names are displayed in the JTable correctly. However, when I try doing that with a button in a different class, I get no errors and no entries into the JTable.
I'm using NetBeans GUI Builder btw.
This is currently what I have for the MainGUI class:
public class MainGUI extends javax.swing.JFrame {
public void getItems(String extName, double extPrice) {
itemName = extName; //instance variables
itemPrice = extPrice;
getTotal(itemPrice); //displays the total sum of items in textfield
orderTab.setValueAt(itemName, arrayCount, 0); //JTable.
orderTab.setValueAt(itemPrice, arrayCount, 1);
arrayCount++; //so next items clicked can displayed on next row
}
}
and for the other class
public class BuildPizzaGUI extends javax.swing.JFrame {
private void addButtonClick(java.awt.event.ActionEvent evt) {
MainGUI exporter = new MainGUI();
exporter.getItems(custName, custPrice);
setVisible(false); //closes window
}
}
I don't get any errors messages. I want the item name and price to be displayed, but currently, I don't get anything other than a closed window. Thanks.
MainGUI exporter = new MainGUI();
You can't keep creating a new instance of the MainGUI every time you click a button. If you do it means with every item you try to add you create a new JFrame.
Instead you need to pass a reference to the existing MainGUI class when you create your BuildPizzaGUI. Then when you click the button you reference this variable which will allow you to update the JTable in that class.

JList value changes when clicked

New to the forum and to Java. I am trying to have my JList respond when double-clicked, which I have accomplished. The JList is being populated by a SQL query which is ran when a button in the GUI is pressed. Based on the SQL query, the JList is populated, this is also working.
The issue comes about if I try to update the JList by clicking the button to query SQL again. When I click that, the change initially shows up in the JList, however when I click on that option in the JList it immediately switches back to what it was initially. When I double-click on what appears to be the incorrect name, the value that I have printing in the console reports correctly. So it has the value correct in the console but the rendering in the JList is not correct.
I appreciate any responses, I have combed the forums without any luck. I am new to Java so I'm sure there is quite a bit that isn't perfect with my code. Code is below please let me know if you need more. Thank you.
public JPanel results(StringBuilder message)
{
StringBuilder[] options = {message};
showOption = new JList(options);
showOption.setLocation(300, 50);
showOption.setSize(140,100);
showOption.setVisibleRowCount(10);
textPanel.add(showOption);
showOption.revalidate();
showOption.repaint();
MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
//JList showOption = (JList) mouseEvent.getSource();
if (e.getClickCount() == 2) {
int index = showOption.locationToIndex(e.getPoint());
Object o = showOption.getModel().getElementAt(index);
System.out.println("Double-clicked on: " + o.toString());
}
}
};
showOption.addMouseListener(mouseListener);
return totalGUI;
}
public static void main ( String args[] )
{
//JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JTextField of Dreams [=]");
GUI_TextField demo = new GUI_TextField();
frame.setContentPane(demo.createContentPane());
//frame.setContentPane(demo.results(message));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(510, 400);
frame.setVisible(true);
}
Three things jump out at me immediately.
You're creating a new JList each time
You're manually setting the size and position of the JList
You're not removing the previous JList
For example...
public JPanel results(StringBuilder message)
{
StringBuilder[] options = {message};
// Create new JList
showOption = new JList(options);
// This is ill advised
showOption.setLocation(300, 50);
showOption.setSize(140,100);
showOption.setVisibleRowCount(10);
// What about the last JList?
textPanel.add(showOption);
This raises a number of possibilities, the likely one is that you are covering over the previous list, which is being brought to the front when textPanel is validated and painted.
Swing follows (loosly) the MVC paradigm (and for more details)
So instead of re-creating the view each time, you should simply re-create the model, for example...
public JPanel results(StringBuilder message)
{
DefaultListModel model = new DefaultListModel();
model.addElement(message);
showOption.setModel(model);
If showOption isn't created initially before this method is called, you should consider putting in a if statement to detect when showOption is null and initialise it appropriately.
You should also avoid using setLocation and setSize. Swing has being designed to operate with the use of layout managers, these make it possible to define workflow and general layout that can be used across multiple platforms.
Take a look at How to use lists and Laying Out Components Within a Container

How to add a function in jTable that sorts the column?

I know that by using JTable the column is sorted when we click on the column heading, but what I want is that, when I right-click on the column name a function name 'sort' should be displayed. Any suggestion in doing it?
Start by adding a MouseListener to the table. See How to write mouse listeners
You will need to translate the click point to a column, see JTable#columnAtPoint.
You will then need to update the SortKey for the table. Check out Sorting and Filtering for an example
If I understand you correctly, you want to sort by some explicit action (triggered f.i. in a popup) instead of by the normal left-click.
If so, the tricky part is to force the ui-delegate to do nothing. There are two options:
hook into the default mouse listener installed by the ui delegate, as described in a recent QA
let the ui do its stuff, but fool it by a sorter implementation that doesn't follow the rules (beware: that's as dirty as the first approach!)
The mis-behaving sorter:
public class MyTableRowSorter extends TableRowSorter {
public MyTableRowSorter(TableModel model) {
super(model);
}
/**
* Implemented to do nothing to fool tableHeader internals.
*/
#Override
public void toggleSortOrder(int column) {
}
/**
* The method that really toggles, called from custom code.
*
* #param column
*/
public void realToggleSortOrder(int column) {
super.toggleSortOrder(column);
}
}
// usage
final JTable table = new JXTable(new AncientSwingTeam());
table.setRowSorter(new MyTableRowSorter(table.getModel()));
Action toggle = new AbstractAction("toggleSort") {
#Override
public void actionPerformed(ActionEvent e) {
JXTableHeader header = SwingXUtilities.getAncestor(
JXTableHeader.class, (Component) e.getSource());
Point trigger = header.getPopupTriggerLocation();
int column = trigger != null ? header.columnAtPoint(trigger) : -1;
if (column < 0) return;
int modelColumn = header.getTable().convertColumnIndexToModel(column);
((MyTableRowSorter) header.getTable().getRowSorter())
.realToggleSortOrder(modelColumn);
}
};
JPopupMenu menu = new JPopupMenu();
menu.add(toggle);
table.getTableHeader().setComponentPopupMenu(menu);
Yeah, couldn't resist throwing in some SwingX api, lazy me :-) With plain Swing, you'll have to write some lines more but the basics are the same: install the tricksy sorter and use its custom toggle sort to really sort whereever needed, f.i. in a mouseListener.

Java Gui Menubars

I'm practicing my gui skills with Java and I have been doing menus and menu bars.
They make sense to me just fine but I have a question about where I can learn more about them.
The basic menus I have done, the ActionListener function actionPerformed has to be in the same class as the menu, and the item that the menu is changing also has to be in the class as the menu.
What If I want to have a menu that affects a JPanel that is created by a constructor from another class and placed in my frame.. I'm not sure how the menu can change components of it.
Any tips, hints or sites you guys have found helpful would be great, thanks in advance.
I find it useful to wrap menubar actions in an Action object. This encapsulates:
The name and icon of the action
If it is enabled or disabled
(for a checkbox action) if it is selected
The keyboard shortcut for the action
The implementation of the action listener
You would define a subclass of AbstractAction in the class whose data that action acts on. Then define a getter for that action so that your menu building code can get it. You can add the Action directly to a menu - a MenuItem is constructed automatically for it.
The other advantage of actions is that that same action can be used in a button, toolbar, etc.
class ModelClass {
int value;
Action incAction = new AbstractAction("Increment") {
public void actionPerformed() {
value++;
setEnabled(value < 10);
}
};
public Action getIncAction() {
return incAction;
}
}
class UIClass {
void buildMenu() {
JMenu menu = new JMenu("Model");
menu.add(model.getIncAction());
}
}

How to handle multiple jLists with one ListSelectionEvent

I have three jLists in my class frmMain. I have created a class called ListActions. The code below is working for one jList. It returns the value clicked for one jList.
How do I distinguish between the three other jList? Or do I need to create a seperate class for each listener?
I need to perform an action based on which jList was clicked. I attempted to see if I could access the variable name of the jList that was clicked, but couldn't find a way to do this...
class ListActions implements ListSelectionListener {
public void valueChanged(ListSelectionEvent evt) {
if (!evt.getValueIsAdjusting()) {
JList list = (JList) evt.getSource();
int iSelectedDatabase = list.getSelectedIndex();
Object objSelectedDatabase = list.getModel().getElementAt(iSelectedDatabase);
String sSelectedDatabase = objSelectedDatabase.toString();
JOptionPane.showConfirmDialog(null, sSelectedDatabase);
}
}
}
Thanks,
- Jason
JList inherits from Component.
Therefore, you can use the getName() method to get the name of your Component and know which one has been called.

Categories