DialogComponentButton and setEnabled

Hello all

Firstly, let me congratulate the developers on a great job. Knime is very useful, and even with no prior knowledge of java, the documentation allows one to put together a custom knime node in next to no time.

I have a simple question, though. I’ve used ChangeListeners to enable/disable components through their SettingsModel, but I also need to enable/disable a DialogComponentButton, which is not associated with any SettingsModel, just an ActionListener.

If I call setEnabled directly on the DialogComponentButton it works as I intended, but eclipse says it’s deprecated (I’m still using knime 1.3.5).

What’s the right way of doing this?

Thanks in advance,
Miguel

Hi Miguel,
simply call yourDialogComponentButton.getModel().setEnabled(boolean).
Best, Thomas

Hello Thomas, thanks for your response.

I guess that makes sense, if there is an associated SettingsModel despite not being used in the constructor, but it doesn’t work for me. To be more specific, the following works (read button is initially disabled):

// enable or disable reading workflow from file final DialogComponentButton read_button = new DialogComponentButton("Read"); // initial state read_button.setEnabled(Boolean.False); addDialogComponent(read_button);

but the following doesn’t (write button is initially enabled)

// enabled and disable writing workflow to file final DialogComponentButton write_button = new DialogComponentButton("Write"); // initial state write_button.getModel().setEnabled(Boolean.False); addDialogComponent(write_button);

What am I doing wrong?

Miguel

Did you already have a look into the referring documentation about disabling components and the related SettingsModelListener?

Hello Fabian,

I did follow that documentation to implement my listeners, but I might have misunderstood it. I think you are refering to keeping the state consistent in the NodeModel - I use factory methods for every SettingsModel that set the initial state to enabled/disabled, and call this factory both from the NodeModel and NodeDialog. For any DialogComponent other than a Button, this seems to be working fine.

I’m sure I’m missing something trivial, but my problem is only with the DialogComponentButton (which defines no settings, so there’s nothing related to it in the NodeModel).

Also, it’s not that the state is inconsistent - with myDialogComponentButton.setEnable(), I can change its state, with myDialogComponentButton.getModel().setEnable(), nothing happens.

Anyway, it’s probably not that important - even if these buttons are always enabled, they are “mostly harmless” :slight_smile:

Cheers,
Miguel

Seems that this is a problem especially related to the button because - as you suspected correctly - it has no settings. I would suggest to use the deprecated method - and its up to us to find a solution for this problem. However, thank you very much for reporting it.

Ok, I’ll keep with the deprecated method, and I’m glad that this thread was of some use to you. Keep up the good work! :slight_smile:

Still related with this issue (but now regarding only the visual effect) , if I disable a DialogComponentBoolean or a DialogComponentButton, the label is also greyed-out, which is good since it facilitates user interaction, but on other components the label does not change.

This is the case of a DialogComponentString, where only the border of the text box is greyed-out, and the DialogComponentFileChooser, where the selection box and the browse button are greyed-out but not the label.

I don’t know if this is a feature or a bug, but at least for my use cases it would be best if the labels were always greyed-out when a component is disabled - is there anything I can do?

Hi Miguel,
There is no good solution to that. I can only think of a hack to get what you want:
In your listener, which is invoked when the SettingsModel changes, recursively traverse the components panel (DialogComponent#getComponentPanel()) and en/disable any JLabel in there.

  • Peter

I got an error when I try to disable a button.

DialogComponentButton test = new DialogComponentButton("test"); 
test.getModel().setEnabled(false); 
or 
test.setEnabled(false);

This is very strange behavior because on another installation the same code worked for me. (same KNIME version)

!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.AssertionError
	at org.knime.core.node.defaultnodesettings.DialogComponent$EmptySettingsModel.setEnabled(DialogComponent.java:413)
	at de.helmholtz_muenchen.ibis.utils.abstractNodes.FileSelector.FileSelectorNodeDialog.<init>(FileSelectorNodeDialog.java:74)
	at de.helmholtz_muenchen.ibis.ngs.fastaSelector.FastaSelectorNodeDialog.<init>(FastaSelectorNodeDialog.java:22)
	at de.helmholtz_muenchen.ibis.ngs.fastaSelector.FastaSelectorNodeFactory.createNodeDialogPane(FastaSelectorNodeFactory.java:52)
	at org.knime.core.node.Node$1.run(Node.java:1901)
	at org.knime.core.node.util.ViewUtils$3.run(ViewUtils.java:309)
	at org.knime.core.node.util.ViewUtils$2.run(ViewUtils.java:130)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
	at java.awt.EventQueue.access$200(EventQueue.java:103)
	at java.awt.EventQueue$3.run(EventQueue.java:682)
	at java.awt.EventQueue$3.run(EventQueue.java:680)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

 

I guess the difference in the -ea parameter for the JVM.

1 Like

According the source code
protected static final class EmptySettingsModel extends SettingsModel {

    /**
     * Creates an empty settings model, that will not hold any value.
     */
    public EmptySettingsModel() {

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return getClass().getSimpleName() + " ('EMPTYMODELID')";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void addChangeListener(final ChangeListener l) {
        // don't listen to me.
        assert false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void prependChangeListener(final ChangeListener l) {
        // not listening
        assert false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void notifyChangeListeners() {
        // I have nothing to say.
        assert false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeChangeListener(final ChangeListener l) {
        // nobody is listening
        assert false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isEnabled() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setEnabled(final boolean enabled) {
        // I don't care.
        assert false;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    protected EmptySettingsModel createClone() {
        return new EmptySettingsModel();
    }

can not call setEnabled method on emptySettingModel. So i want to know how to disable a button?

Hi @lou,
in case of DialogComponentButton you need to call the deprecated disable method on the component itself.
best,
Gabriel

1 Like

get same error

    ENTRY org.eclipse.ui 4 0 2019-09-11 09:06:59.526
   !MESSAGE Unhandled event loop exception
   !STACK 0
   java.lang.AssertionError
at 
   org.knime.core.node.defaultnodesettings.DialogComponent$EmptySettingsModel.
  setEnabled(DialogComponent.java:410)
at org.knime.core.node.defaultnodesettings.DialogComponent.setEnabled(DialogComponent.java:253)
at com.gw.knime.connector.tsdb.TSDBNodeDialog.createTSDBQueryParamTab(TSDBNodeDialog.java:86)
at com.gw.knime.connector.tsdb.TSDBNodeDialog.<init>(TSDBNodeDialog.java:48)

DialogComponentButton varButton = new DialogComponentButton("变量");
	varButton.setEnabled(false);
	addDialogComponent(varButton);

I don’t see anywhere in your code or in the stack trace you calling the method he told you to call.

varButton.setEnabled(false);

remove above code,application run correct.

A: “you need to call the deprecated disable method on the component itself.”
B: “check, setEnabled it is then… i got this.”

sorry,What do you want me to debug?

   !MESSAGE Unhandled event loop exception

the above exception caused by call setEnabled() method on DialogComponentButton