I'm new to Java and developing a small project. I'm making a program where the user has to register themselves. I have 3 different tabs on my Tabbed Pane. I want to be able to disable the next button on the first pane making it impossible for the user to continue to pane 2 unless all the text fields on pane 1 have been filled. I have been Searching online and found various examples but none of them would work in run time.
I am using Netbeans.
private void txtFirstNameActionPerformed(java.awt.event.ActionEvent evt) {
if(txtFirstName.getText().trim().length() > 0)
btnNext1.setEnabled(true);
else
btnNext1.setEnabled(false);
}
Create a List of all the text fields on your pane:
List<JTextField> list = new ArrayList<>();
Add all your text fields to that list.
Then, create a universal DocumentListener that listens for text change events, and every time a text update happens, scan through all your text fields to see if they have all been filled:
DocumentListener listener = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) { changedUpdate(e); }
#Override
public void insertUpdate(DocumentEvent e) { changedUpdate(e); }
#Override
public void changedUpdate(DocumentEvent e) {
boolean canEnable = true;
for (JTextField tf : list) {
if (tf.getText().isEmpty()) {
canEnable = false;
}
}
btnNext1.setEnabled(canEnable);
}
};
And add that listener to every text field you have in the list:
for (JTextField tf : list) {
tf.getDocument().addDocumentListener(piecesListener);
}
Related
private void createEvents()
{
menuFileExit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
////// Events on tree selection
jtStoryViewer.addTreeSelectionListener(new TreeSelectionListener()
{
public void valueChanged(TreeSelectionEvent arg0)
{
DefaultMutableTreeNode selection = (DefaultMutableTreeNode) jtStoryViewer.getLastSelectedPathComponent();
Object nodeObject = selection.getUserObject();
////// Checks if selected node is a String (only story title is a string)
if(selection.getUserObject().getClass().getName() == "java.lang.String" )
{
tfTitle.setText(nodeObject.toString());
////// Action listener for Change Button
btnChange.addActionListener(new ActionListener()
{
////// Title text swap
public void actionPerformed(ActionEvent arg0)
{
selection.setUserObject(tfTitle.getText());
((DefaultTreeModel)jtStoryViewer.getModel()).nodeChanged(selection);
}
});
}
///// checks if the object is a chapter object
if(selection.getUserObject().getClass().getName() == "ISW.common.Chapter")
{
Chapter chapter = (Chapter) selection.getUserObject();
tfTitle.setText(chapter.toString());
////// Action listener for Change Button
btnChange.addActionListener(new ActionListener()
{
////// Title text swap
public void actionPerformed(ActionEvent arg0)
{
chapter.setTitle(tfTitle.getText());
((DefaultTreeModel)jtStoryViewer.getModel()).nodeChanged(selection);
}
});
}
}
});
}
I am using JTree to display and modify some objects. I added a TreeSelectionListener to get the object data on selection. For now I want to be able to change the title of an object, it works fine on first selection on the tree , I change the value in the text box and the "Change" button works just fine, but when I move on to next objects, the change button also modifies the value of all previously selected objects.
I guess it is caused due to my improper usage of the ActionListeners but I can't tell for sure and at this point I'm stuck.
Will be grateful for any hints.
Don't keep adding an ActionListener to the btnChange JButton within the TreeSelectionListener#valueChanged method.
This will cause the button to call EVERY ActionListener you have previously
Instead, give the btnChange a single ActionListener, when clicked, can act on the currently selected node (by checking the JTree it self). You could have the TreeSelectionListener#valueChanged method enable or disable the btnChange based on the validity of the selection
Also, if(selection.getUserObject().getClass().getName() == "ISW.common.Chapter") isn't how String comparison is done in Java, instead you should use something more like if("ISW.common.Chapter".equals(selection.getUserObject().getClass().getName()))
I'm working on a task planning app. I have a 'new task' button to add a task. When clicked, this button makes a new instance of the TaskRowToDo class and adds this to the toDoList arraylist. This class contains a row with a text field and some buttons.
This is the 'new task' button code:
private void drawNewBtn(){
JButton btnNew = new JButton("Nieuwe taak");
btnNew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("New task added");
toDoList.add(new TaskRowToDo(toDoIndex+7, false, "new task", 2));
toDoList.get(toDoIndex).draw();
toDoIndex++;
frmPlanner.revalidate();
}
});
frmPlanner.getContentPane().add(btnNew, "cell 3 12");
}
At the end of the TaskRowToDo there is a 'remove' button. This button should remove the row from the toDoList and remove this row from the screen.
Below is the 'remove' button code:
btnRemoveToDo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("To Do removed");
toDoIndex--;
toDoList.remove(toDoIndex);
frmPlanner.revalidate();
}
});
The button removes the instance of TaskRowToDo from the toDoList, but it still shows up on screen and the components even work. So it's not really removed. I've tried using revalidate() and repaint() but to no avail. As a test I tried frmPlanner.removeAll() and even this doesn't clear the screen (however the components won't work anymore).
How do I remove this one row, including its components and clear this space on the screen?
toDoList is JList?
give same more code, on this time I suggest to setModel on JList.
I always prepare method setModel when I create JList and it works:
private void setModelForJList() {
toDoList.setModel(new ListModel<TaskRowToDo>() {
#Override
public int getSize() {
return toDoListEntityList.size();
}
#Override
public TaskRowToDogetElementAt(int index) {
return toDoListEntityList.get(index);
}
#Override
public void removeListDataListener(ListDataListener l) {
}
#Override
public void addListDataListener(ListDataListener l) {
}
});
toDoList.repaint();
}
when you delete object from JList, call this method, toDoListEntityList is list of object which you put in Jlist.
About JList some advices. Good practice is declare generic type of JList (in your case is JList<TaskRowToDo> toDoList= new JList<TaskRowToDo>
I made my JComboBox editable using:
myCombo.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
I encounter multible problems with the following task:
When writing into the combobox, the new content of the box should be taken and compared with a list and all entries starting with this text should be shown in the popupmenu.
So if i have a list with: "Aban" "Aben" "Aber" "Acen" "Aden"
and enter "Ab" into the box, then the pop-up should display the first 3 entries.
When clicking one of the entries (Either by keyboard selecting and pressing enter/tab or by clicking with a mouse) The ComboBox should get that value and the Popup should hide. I need to find this action as some of the elements have a note at the end (In backets which I require) but only when one of the entries is selected
Here are the most imporant parts of my code:
final JTextComponent tcA = (JTextComponent) myCombo.getEditor().getEditorComponent();
tcA.getDocument().addDocumentListener(new DocumentListener() {
public void methodUsedByinsertUpdateAndremoveUpdate(DocumentEvent e) {
String item = ((JTextComponent) myCombo.getEditor().getEditorComponent()).getText();
//Routine to get the new list in a vector, not pasted for readability
DefaultComboBoxModel newMyComboModel = new DefaultComboBoxModel(myVectorList);
myCombo.setModel(newMyComboModel);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myCombo.showPopup();
}
});
}
}
myCombo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(myCombo.getModel().getSize() == 1) {
//Special logic to find out if the selected item has a note
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myCombo.hidePopup();
}
});
}
}
With this, i have:
Trouble with the first character (Caret position not working correctly)
Popup not automatically shown and hides when entering new character into the field
Problems with Swing GUI not being actualised
If you require more information just ask
The Glazed List recommended by peeskillet did exactly what I wanted
So I have bunch of grids on my window and I have a JTextField, I want to write a number, say
20, in the text field and the 20 would change my grid size to 20 and so on.
Here you see I have set it to 30, I can set it to any number, but like I said I want to be
able to change/set the number when I type it in the text field after I run the program.
This is my Grids class and not the main class, In my main class I created the text field and
such. Also I have my actionPreformed in my main so what do I need in my actionPreformed
(if necessary)?
So my question is after running the program how to write in the text field a
number (10,20,30 any number) and be able to change my grid size based on the number I typed?
Also what do I need in my actionPreformed (if necessary)?
Grids class:
protected int gridSize = 30; // how many grids
public Grids( ghetto ttt )
{
setLayout( new GridLayout( gridSize, gridSize ) );
theSquares = new Marker[gridSize][gridSize];
for ( int i=0; i<gridSize; i++ )
{
for ( int j=0; j<gridSize; j++ )
{
theSquares[i][j] = new Marker(gridSize , this );
add(theSquares[i][j]);
}
}
}
I would use a JSpinner with a ChangeListener.
Read the section from the Swing tutorial on How to Use Spinners for more information and examples.
So an actionlistener probably won't work. That condenses click events into ActionEvents. What you can do is add a document listener. See Value Change Listener to JTextField.
In your main program where you would do
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// Whatever
}
});
you do
textField.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent arg0) {
//whatever
}
#Override
public void insertUpdate(DocumentEvent arg0) {
//whatever
}
#Override
public void changedUpdate(DocumentEvent arg0) {
//whatever
}
});
I have a JTextField for which I'm hoping to suggest results to match the user's input. I'm displaying these suggestions in a JList contained within a JPopupMenu.
However, when opening the popup menu programmatically via show(Component invoker, int x, int y), the focus is getting taken from the JTextField.
Strangely enough, if I call setVisible(true) instead, the focus is not stolen; but then the JPopupMenu is not attached to any panel, and when minimizing the application whilst the box is open, it stays painted on the window.
I've also tried to reset the focus to the JTextField using requestFocus(), but then I have to restore the caret position using SwingUtilities.invokeLater(), and the invoke later side of things is giving the user a slight margin to mess around with the existing contents / overwrite it / or do other unpredictable things.
The code I've got is effectively:
JTextField field = new JTextField();
JPopupMenu menu = new JPopupMenu();
field.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
JList list = getAListOfResults();
menu.add(list);
menu.show(field, 0, field.getHeight());
}
});
Can anyone suggest the best avenue to go down to show the JPopupMenu programmatically whilst preserving the focus on the JTextField?
The technical answer is to set the popup's focusable property to false:
popup.setFocusable(false);
The implication is that the textField has to take over all keyboard and mouse-triggered actions that are normally handled by the list itself, sosmething like:
final JList list = new JList(Locale.getAvailableLocales());
final JPopupMenu popup = new JPopupMenu();
popup.add(new JScrollPane(list));
popup.setFocusable(false);
final JTextField field = new JTextField(20);
Action down = new AbstractAction("nextElement") {
#Override
public void actionPerformed(ActionEvent e) {
int next = Math.min(list.getSelectedIndex() + 1,
list.getModel().getSize() - 1);
list.setSelectedIndex(next);
list.ensureIndexIsVisible(next);
}
};
field.getActionMap().put("nextElement", down);
field.getInputMap().put(
KeyStroke.getKeyStroke("DOWN"), "nextElement");
As your context is very similar to a JComboBox, you might consider having a look into the sources of BasicComboBoxUI and BasicComboPopup.
Edit
Just for fun, the following is not answering the focus question :-) Instead, it demonstrates how to use a sortable/filterable JXList to show only the options in the dropdown which correspond to the typed text (here with a starts-with rule)
// instantiate a sortable JXList
final JXList list = new JXList(Locale.getAvailableLocales(), true);
list.setSortOrder(SortOrder.ASCENDING);
final JPopupMenu popup = new JPopupMenu();
popup.add(new JScrollPane(list));
popup.setFocusable(false);
final JTextField field = new JTextField(20);
// instantiate a PatternModel to map text --> pattern
final PatternModel model = new PatternModel();
model.setMatchRule(PatternModel.MATCH_RULE_STARTSWITH);
// listener which to update the list's RowFilter on changes to the model's pattern property
PropertyChangeListener modelListener = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("pattern".equals(evt.getPropertyName())) {
updateFilter((Pattern) evt.getNewValue());
}
}
private void updateFilter(Pattern newValue) {
RowFilter<Object, Integer> filter = null;
if (newValue != null) {
filter = RowFilters.regexFilter(newValue);
}
list.setRowFilter(filter);
}
};
model.addPropertyChangeListener(modelListener);
// DocumentListener to update the model's rawtext property on changes to the field
DocumentListener documentListener = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
updateAfterDocumentChange();
}
#Override
public void insertUpdate(DocumentEvent e) {
updateAfterDocumentChange();
}
private void updateAfterDocumentChange() {
if (!popup.isVisible()) {
popup.show(field, 0, field.getHeight());
}
model.setRawText(field.getText());
}
#Override
public void changedUpdate(DocumentEvent e) {
}
};
field.getDocument().addDocumentListener(documentListener);
It looks straight forward to me. Add the following
field.requestFocus();
after
menu.add(list);
menu.show(field, 0, field.getHeight());
Of course, you will have to code for when to hide the popup etc based on what is going on with the JTextField.
i.e;
menu.show(field, field.getX(), field.getY()+field.getHeight());
menu.setVisible(true);
field.requestFocus();
You may take a look to JXSearchField, which is part of xswingx