I have a JPanel with a bunch of different check boxes and text fields, I have a button that's disabled, and needs to be enabled when specific configurations are setup.
What I need is a listener on the the whole JPanel looking for events, whenever anything changes.
I believe I need an action listener but I can't find anything to bridge the action Listener with the JPanel
JPanel Window = new JPanel();
Window.addActionListener(new ActionListener(){
//Check if configurations is good
}
I figure I can copy and paste my code a bunch of times into every listener in the panel, but that seems like bad coding practice to me.
First off as #Sage mention in his comment a JPanel is rather a container than a component which do action. So you can't attach an ActionListener to a JPanel.
I figure I can copy and paste my code a bunch of times into every
listener in the panel, but that seems like bad coding practice to me.
You're totally right about that, it's not a good practice at all (see DRY principle). Instead of that you can define just a single ActionListener and attach it to your JCheckBoxes like this:
final JCheckBox check1 = new JCheckBox("Check1");
final JCheckBox check2 = new JCheckBox("Check2");
final JCheckBox check3 = new JCheckBox("Check3");
final JButton buttonToBeEnabled = new JButton("Submit");
buttonToBeEnabled.setEnabled(false);
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean enable = check1.isSelected() && check3.isSelected();
buttonToBeEnabled.setEnabled(enable);
}
};
check1.addActionListener(actionListener);
check2.addActionListener(actionListener);
check3.addActionListener(actionListener);
This means: if check1 and check3 are both selected, then the button must be enabled, otherwise must be disabled. Of course only you know what combination of check boxes should be selected in order to set the button enabled.
Take a look to How to Use Buttons, Check Boxes, and Radio Buttons tutorial.
A suggestion could be to derive a class from each of the components you're using and add an ActionListener that bubbles up the Container tree and looks for the first Container that implements a custom interface like this:
public interface MyCommandProcessor {
void execute(String actionCommand);
}
public class MyButton extends JButton {
public MyButton(string actionCommand) {
setActionCommand(actionCommand);
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
Container traverser = MyButton.this;
while (traverser != null && !(traverser instanceof MyCommandProcessor))
traverser = traverser.getParent();
if (traverser != null)
((CommandListener)traverser).execute(ae.getActionCommand());
}
});
}
}
public class MyApp extends JFrame implements MyCommandListener {
public MyApp() {
JPanel panel = new Panel();
panel.add(new MyButton("MyButton got pressed"));
}
public void execute(String actionCommand) {
System.out.println(actionCommand);
}
}
You need to create custom component listener. Look here:
Create a custom event in Java
Creating Custom Listeners In Java
http://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html
I do it throw the standard ActionListener
Example
public class MyPanel extends JPanel {
private final JComboBox<String> combo1;
private final JButton btn2;
.......
//catch the actions of inside components
btn2.addActionListener(new MyPanelComponentsActionListener());
........
//assign actionlistener to panel class
public void addActionListener(ActionListener l) {
listenerList.add(ActionListener.class, l);
}
public void removeActionListener(ActionListener l) {
listenerList.remove(ActionListener.class, l);
}
//handle registered listeners from components used MyPanel class
protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
if(actionCommand == null) {
actionCommand = "FontChanged";
}
e = new ActionEvent(FontChooserPanel.this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
}
// here registered listener executing
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
//!!! here your event generator
class MyPanelComponentsActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//do something usefull
//.....
fireActionPerformed(e);
}
}
....
}
Related
How to check from a class ModalDialog extends JDialog implements ActionListener if actionPerformed(ActionEvent e) method ocurred in another class (Connect extends JFrame implements ActionListener)? And one step further, how to check which of two buttons that I have in ModalDialog fired ActionPerformed method? (I know about event.getSource, but I need to check it from another class).
public ModalDialog()
{
btn8 = new Button("human");
btn8.setMaximumSize(new Dimension(60,40));
btn8.addActionListener(this);
btn9 = new Button("robot");
btn9.setMaximumSize(new Dimension(60,40));
btn9.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
}
class Connect extends JFrame implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
ModalDialog md = new ModalDialog();
if(md.ActionPerformed(e)....)...something like that...
}
}
How to check from a class ModalDialog extends JDialog implements ActionListener if actionPerformed(ActionEvent e)
This is a basic problem of how to return information from one class to another. The simple answer is to provide a getter method, which returns the selected value.
Start by defining the value to be returned, here I used a enum, as it clearly defines what could be returned
public enum Option {
HUMAN, ROBOT;
}
Update your ModalDialog to provide a getter to return the selected value
public class ModalDialog extends JDialog implements ActionListener {
private Option selection;
public ModalDialog() {
setModal(true);
Button btn8 = new Button("human");
btn8.addActionListener(this);
Button btn9 = new Button("robot");
btn9.addActionListener(this);
setLayout(new GridBagLayout());
add(btn8);
add(btn9);
pack();
}
public Option getSelection() {
return selection;
}
public void actionPerformed(ActionEvent e) {
//...
}
}
When the dialog is closed, the caller can now call getSelection to get the selected value (or null if the user closed the dialog via the [X] button
And one step further, how to check which of two buttons that I have in ModalDialog fired ActionPerformed method?
This is not an uncommon problem, and there a number of ways you might implement it. Since you've already implemented ActionListener at the class level, you could just make use of the actionCommand support available in buttons, which defaults to the text of the button
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
switch (cmd) {
case "human":
selection = Option.HUMAN;
break;
case "robot":
selection = Option.ROBOT;
break;
}
setVisible(false);
}
So now, when the dialog is closed, you can just request the selected value...
ModalDialog dialog = new ModalDialog();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
Option selection = dialog.getSelection();
System.out.println("You choose " + selection);
How would I call an Action from another class in Java? I got a CloseTabButton class online that allows a simple close tab button on each JTabbedPane, but when the tab is closed, I would like a dialog to pop up based on information (if file is not saved, ask to save it, etc.). This is the file:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class CloseTabButton extends JPanel implements ActionListener {
private JTabbedPane pane;
public CloseTabButton(JTabbedPane pane, int index) {
this.pane = pane;
setOpaque(false);
// CloseIcon class just had a button with an x painted on it
Icon closeIcon = new CloseIcon();
JButton close = new JButton(closeIcon);
close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
close.addActionListener(this);
add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
add(close);
pane.setTabComponentAt(index, this);
}
#Override
public void actionPerformed(ActionEvent e) {
int i = pane.indexOfTabComponent(this);
String fileName = pane.getToolTipTextAt(i);
// Where I want to ask if user wants to save, etc.
if (fileName == "Untitled") {
// Do stuff
}
pane.remove(i); // Removes the tab
// If tab count < 1, then disable the save and save as buttons on menu
if (pane.getTabCount() < 1) {
JFrame frame = (JFrame) pane.getParent().getParent().getParent().getParent().getParent(); // Yes, there is that many in my code to get the parent JFrame
int menuCount = frame.getJMenuBar().getMenuCount();
for (int a = 0; a < menuCount; a++) {
int itemCount = frame.getJMenuBar().getMenu(a).getItemCount();
for (int b = 0; b < itemCount; b++) {
Component component = frame.getJMenuBar().getMenu(a).getMenuComponent(b);
if (!(component instanceof JSeparator)) {
// Not a seperator
String itemName = frame.getJMenuBar().getMenu(a).getItem(b).getAccessibleContext().getAccessibleName();
if (itemName == "Save As..") {
frame.getJMenuBar().getMenu(a).getItem(b).setEnabled(false);
}
}
}
}
}
}
}
In my main class I have actions listed like this:
static Action Close = new AbstractAction("Close") {
public void actionPerformed(ActionEvent e) {
closeCurrentWindow(); // function that will close tab
}
}
The other menu items are Actions as well, and as you can see, what I'm currently doing in the CloseTabButton class is quite frustrating, and most likely the wrong way to code it. Is there a much simpler way to do what I'm doing?
The first thing I might do is provide ActionListener support to the CloseTabButton, for example...
public class CloseTabButton extends JPanel {
private JTabbedPane pane;
public CloseTabButton(JTabbedPane pane, int index) {
this.pane = pane;
setOpaque(false);
// CloseIcon class just had a button with an x painted on it
Icon closeIcon = new CloseIcon();
JButton close = new JButton(closeIcon);
close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fireActionPerformed();
}
});
add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
add(close);
pane.setTabComponentAt(index, this);
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "You could provide you own action command for each tab here");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
Basically, this now allows you to register your own ActionListeners to the CloseTabButton
Next, this, fileName == "Untitled", is not how you compare Strings in Java, you should be using something more like "Untitled".equals(fileName)
If you're menus are based on actual Actions, then you can simply disable the Actions themselves. This would require a little bit of work, but a lot less of "guess" work then you're doing now.
Basically, you would monitor the JTabbedPane itself, monitoring for changes to the selected tab and updating the states of the individual Actions themselves
There a number of ways you could do this, like passing a reference of the JTabbedPane to the Actions so they can perform there own monitoring (but I'd use some kind of management interface which could more easily provide information to the Actions and decouple the code and the reliance on JTabbedPane directly, then you could be free to use JInternalFrames instead).
You could have a "menu manager" which did a similar job, monitoring changes to the document container and changing the state of the menu Actions based on the current state, as an example
Updated
If you're making use of the Action API (which I would recommend), then you could simply do something like...
public class CloseTabButton extends JPanel {
private JTabbedPane pane;
public CloseTabButton(JTabbedPane pane, Action action, int index) {
this.pane = pane;
setOpaque(false);
// CloseIcon class just had a button with an x painted on it
Icon closeIcon = new CloseIcon();
JButton close = new JButton(action);
close.setIcon(closeIcon);
close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
add(close);
pane.setTabComponentAt(index, this);
}
}
Passing in the Action for the close operation, then use the same action for both the JMenuItem and JTabbedPane.
The "core" issue would be how you would identify the "current" tab and document in a uniform manner
I dont need an outright answer for this. just a suggestion on how this problem could be fixed. I am trying to add an action listener to MyButton so that i can call the action performed method in my main class
this is the buttons constructed. they show up and everything works on them minus the actionlistener.
upButton = new MyButton(upStaticImageLocation, upRolledImageLocation, upClickedImageLocation);
upButton.addActionListener(this);
downButton = new MyButton(downStaticImageLocation, downRolledImageLocation, downClickedImageLocation);
downButton.addActionListener(this);
this is the MyButton class with action listener method.
public class MyButton extends JComponent implements MouseListener {
private Dimension size = new Dimension(32, 32);
private Image staticImage;
private Image rolledImage;
private Image clickedImage;
private ArrayList<ActionListener> listeners = new ArrayList<ActionListener>();
public MyButton(String staticImage, String rolledImage, String clickedImage) {
super();
this.staticImage = new ImageIcon(staticImage).getImage();
this.rolledImage = new ImageIcon(rolledImage).getImage();
this.clickedImage = new ImageIcon(clickedImage).getImage();
enableInputMethods(true);
addMouseListener(this);
setSize(size.width, size.height);
setFocusable(true);
}
This seems like a lot of work which has already been done...see How to Use Buttons, Check Boxes, and Radio Buttons for more details.
However, JComponent already provides access to an EventListenerList, so you don't need your listeners List, for example...
public class MyButton extends JComponent implements MouseListener {
//private ArrayList<ActionListener> listeners = new ArrayList<ActionListener>();
public MyButton(String staticImage, String rolledImage, String clickedImage) {
//...
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
Okay, but how do you trigger the event?
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
if (listeners != null) {
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Awesome button action");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
So whenever you want to send an ActionPerformed event, you simply call the fireActionPerformed method within your button
I am not sure if I understand you correctly but think that instead of :
downButton.addActionListener(this);
you must use:
downButton.addActionListener(downButton);
since you are trying to add action listener somewhere outside MyButton so 'this' does not point to instance of MyButton and MyButton must implement ActionListener ie this method:
#Override public void actionPerformed(ActionEvent e)
{
// doo your woodoo here
}
Thought I should post the method that fixed the action listeners and made the whole thing work. Thanks to madProgrammer for his answer.
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
if (listeners != null) {
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Awesome button action");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
public void mouseClicked(MouseEvent e) {
fireActionPerformed();
}
just needed the call on fireActionPerformed when the mouse was clicked.
I have a Java Swing interface with multiple JTextArea's and I am implementing an "Edit" menu with various different functions like "Find", "Copy", "Paste", etc. When I click on the JMenuItem I need to know which JTextArea had the focus which is achievable through a TextAction (I haven't gone down the route of a FocusListener and keeping track of what last had the focus):
JMenuItem miFind = new JMenuItem(new EditHandler("Find"));
class EditHandler extends TextAction {
private String s = null;
public EditHandler(String vs) {
super(vs);
s = vs;
}
#Override
public void actionPerformed(ActionEvent e) {
JTextComponent c = getFocusedComponent();
if (s.equals("Find")) {
showFindDialog(c);
}
}
}
This works well and good but I want to be able to disable the "Find" JMenuItem under certain contexts (i.e. if the specific JTextArea is disabled or is empty. I can implement an ActionListener on a JMenu but I can't use getFocusedComponent() to identify what JTextArea has the focus.
According to the Java docs the JMenu constructor takes an Action (like a JMenuItem) and I have tried the following:
mEdit = new JMenu(new EditHandler("Edit"));
However, although the constructor fires, the actionPerformed() event isn't firing within my EditHandler for the JMenu. If I can get it to fire then I was planning to either enable or disable my "Find" JMenuItem.
The best way for you is using of actions map of the text component to place the corresponding action. In this case you can disable it for some text components.
#Override
public void actionPerformed(ActionEvent e) {
JTextComponent c = getFocusedComponent();
if (s.equals("Find")) {
Action a = c.getActionMap().get("Find");
if (a.isEnabled()) {
// generate new event to modify the source (menu item -> text component)
ActionEvent ae = new ActionEvent(c, e.getID(), e.getCommand());
a.actionPerformed(ae);
}
}
}
For each your text component you must provide an action and register it using the action map of the component.
public class UniversalFindAction extends AbstractAction {
public void actionPerformed(ActionEvent ae) {
JTextComponent c = (JTextComponent) ae.getSource();
showFindDialog(c);
}
}
// registering of action
JTextComponent comp = new JTextArea();
comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK), "Find");
comp.getActionMap().put("Find", new UniversalFindAction());
Thanks to #sergiy-medvynskyy I have implemented a Global Focus Listener to keep track of the last JTextArea to be focused:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
#Override
public void propertyChange(final PropertyChangeEvent e) {
if (e.getNewValue() instanceof JTextArea) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
tFocused = (JTextArea)e.getNewValue();
}
});
}
}
});
I then check the tFocused object using a MenuListener on my JMenu to verify what JTextArea currently has the focus. I can then call setEnabled() on my respective JMenuItem's depending on the context.
I have made a multiple input dialog by building a JPanel with the fields I want and adding it to a JOption pane
JMainPanel mainPanel = new JMainPanel(mensaje, parametros, mgr);
int i = JOptionPane.showOptionDialog(null, mainPanel, "Sirena",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
new String[] {"Aceptar", "Cancelar"}, "Aceptar");
However I'm having trouble with the buttons, because some of the fields are required. How can I make the "Ok" button to be enabled once every required field is up, or making the click on the button to make the validations and do not close the pane until every required field is filled?
From the Java API, I found this:
options - an array of objects indicating the possible choices the user
can make; if the objects are components, they are rendered properly;
non-String objects are rendered using their toString methods; if this
parameter is null, the options are determined by the Look and Feel
So, can't I pass custom buttons as parameter?
Looks like I will have to make my own JDialog? for which case, I don't know how to make it return an int just like JOptionPane does, any recommended tutorial?
In the example options is {"Aceptar", "Cancelar"} which are the displayed buttons,
PS. I have full controll over the fields I added to the JPanel.
This is a screenshot of the JOptionPane:
I don't think that you can de-activate a JOptionPane's selections buttons, but one way to still use the JOptionPane is to simply re-display it if the required fields have not been set. You could display an error message JOptionPane first describing the error, and then display a new JOptionPane that holds the same JPanel as its second parameter -- so that the data already entered has not been lost. Otherwise, you may want to create your own JDialog which by the way isn't that hard to do.
Edit
I'm wrong. You can enable and disable the dialog buttons if you use a little recursion.
For example:
import java.awt.Component;
import java.awt.Container;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;
import javax.swing.*;
public class Foo extends JPanel {
private static final String[] DIALOG_BUTTON_TITLES = new String[] { "Aceptar", "Cancelar" };
private JCheckBox checkBox = new JCheckBox("Buttons Enabled", true);
private Set<AbstractButton> exemptButtons = new HashSet<AbstractButton>();
public Foo() {
JButton exemptBtn = new JButton("Exempt Button");
JButton nonExemptBtn = new JButton("Non-Exempt Button");
add(checkBox);
add(exemptBtn);
add(nonExemptBtn);
exemptButtons.add(checkBox);
exemptButtons.add(exemptBtn);
checkBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
allBtnsSetEnabled(checkBox.isSelected());
}
});
}
private void allBtnsSetEnabled(boolean enabled) {
JRootPane rootPane = SwingUtilities.getRootPane(checkBox);
if (rootPane != null) {
Container container = rootPane.getContentPane();
recursiveBtnEnable(enabled, container);
}
}
private void recursiveBtnEnable(boolean enabled, Container container) {
Component[] components = container.getComponents();
for (Component component : components) {
if (component instanceof AbstractButton && !exemptButtons.contains(component)) {
((AbstractButton) component).setEnabled(enabled);
} else if (component instanceof Container) {
recursiveBtnEnable(enabled, (Container) component);
}
}
}
public int showDialog() {
return JOptionPane.showOptionDialog(null, this, "Sirena",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
DIALOG_BUTTON_TITLES, "Aceptar");
}
private static void createAndShowGui() {
Foo foo = new Foo();
int result = foo.showDialog();
System.out.println(DIALOG_BUTTON_TITLES[result]);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This code uses listeners to check the state of a JCheckBox, but you can have listeners (DocumentListeners) listening to text field documents if you desire to know if they have data or not. The code then gets the JRootPane that holds the JCheckBox, then the root pane's contentPane, and all components of the dialog are held by this. It then recurses through all the components held by the dialog. If a component is a Container, it recurses through that container. If the component is an AbstractButton (such any JButton or checkbox), it enables or disables -- except for buttons held in the exempt buttons set.
A better example with document listeners
import java.awt.*;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Foo2 extends JPanel {
private static final String[] DIALOG_BUTTON_TITLES = new String[] {
"Aceptar", "Cancelar" };
private static final int FIELD_COUNT = 10;
private Set<AbstractButton> exemptButtons = new HashSet<AbstractButton>();
private JTextField[] fields = new JTextField[FIELD_COUNT];
public Foo2() {
setLayout(new GridLayout(0, 5, 5, 5));
DocumentListener myDocListener = new MyDocumentListener();
for (int i = 0; i < fields.length; i++) {
fields[i] = new JTextField(10);
add(fields[i]);
fields[i].getDocument().addDocumentListener(myDocListener);
}
// cheating here
int timerDelay = 200;
Timer timer = new Timer(timerDelay , new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
checkDocsForText();
}
});
timer.setRepeats(false);
timer.setInitialDelay(timerDelay);
timer.start();
}
private void checkDocsForText() {
for (JTextField field : fields) {
if (field.getText().trim().isEmpty()) {
allBtnsSetEnabled(false);
return;
}
}
allBtnsSetEnabled(true);
}
private void allBtnsSetEnabled(boolean enabled) {
JRootPane rootPane = SwingUtilities.getRootPane(this);
if (rootPane != null) {
Container container = rootPane.getContentPane();
recursiveBtnEnable(enabled, container);
}
}
private void recursiveBtnEnable(boolean enabled, Container container) {
Component[] components = container.getComponents();
for (Component component : components) {
if (component instanceof AbstractButton && !exemptButtons.contains(component)) {
((AbstractButton) component).setEnabled(enabled);
} else if (component instanceof Container) {
recursiveBtnEnable(enabled, (Container) component);
}
}
}
public int showDialog() {
return JOptionPane.showOptionDialog(null, this, "Sirena",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
DIALOG_BUTTON_TITLES, "Aceptar");
}
private class MyDocumentListener implements DocumentListener {
public void removeUpdate(DocumentEvent arg0) {
checkDocsForText();
}
public void insertUpdate(DocumentEvent arg0) {
checkDocsForText();
}
public void changedUpdate(DocumentEvent arg0) {
checkDocsForText();
}
}
private static void createAndShowGui() {
Foo2 foo = new Foo2();
int result = foo.showDialog();
if (result >= 0) {
System.out.println(DIALOG_BUTTON_TITLES[result]);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I suggest you to define some properties into your JPanel extended class, and use PropertyChangeListener to listen the occured changes and enable/disable relative buttons.
Here's an article.
Another issue maybe finding the ok/cancel buttons in the hierarchy of components, since the JDialog is created through JOptionPane and you haven't a reference to the buttons. Here's a useful thread .
You can add a property to a JComponent using putClientProperty method.
When changes occurs to a given property a PropertyChanged event is raised.
So in your example you can define a boolean property indicating that required that are inserted into the JDialog. Then add a PropertyChangeListener that when is notified enable/disable the ok button.