How get info of the input table in the NOdeDialog?

Hi, i'm Raf, i'm a new member of this community.
I'm sorry if my english is not perfect, but i'm an italian boy that don't speak and write english very well

I have a question for you:
i need to use same information about Input table in NodeDialog.
For example, i must create a number of DialogComponentColumnNameSelection that is equal to number of colums of the Input table

How i transport this information from NodeModel to NodeDialog?

Thanks in advance for answers

Hi,

please have look into the tutorial "nodedialog" which nicely explains how to use the default dialog components: http://knime.org/extension.html#nodedialog

Regards,
Thomas

Hi gabriel, thanks for the reply...

I see the tutorial a few days ago. I understand how create and use the defaul dialog components, only I not understand how I can take information about the Input Table (for example number of columns).

However I will give another look at tutorials, maybe i missed something....

Hi, the DataTableSpec passed as an argument through the #loadXXX methods contains all information about the structure of the incoming DataTable for each port, but not the data itself. E.g., the spec holds the column names, types, possibles values, min/max bounds, etc. Let me know if you need more details.
Regards, Thomas

You have to overwrite the method loadAdditionalSettingsFrom in the DefaultNodeSettingsPane in order to have access to the DataTableSpec passed as an argument...
Hope that helps :wink:

I try to add loadAdditionalSettingsFrom, but the problem persist... When I link the input port to File Reader and I click Configure on my Node, The dialog is empty. What's wrong?

This is my implementation for NodeDialog

public class Prova_dialogNodeDialog extends DefaultNodeSettingsPane {
private final SettingsModelInteger num_col=new SettingsModelInteger(Prova_dialogNodeModel.CFG_KEY_NR_OF_COL,0);

 /**
 * New pane for configuring the Prova_dialog node.
 */
protected Prova_dialogNodeDialog() {
	
  	DialogComponentColumnNameSelection[] DCCS_group=new DialogComponentColumnNameSelection[num_col.getIntValue()];
	for(int i=0;i<num_col.getIntValue();i++){
		DCCS_group[i]=new DialogComponentColumnNameSelection(new SettingsModelString("SMS"+i,"Select a column"),"Selezionare un classificatore",0,DoubleValue.class);
	}

}

public void loadAdditionalSettingsFrom(NodeSettingsRO settings, DataTableSpec[] specs){
	try{
		num_col.setIntValue(specs[0].getNumColumns());
		System.out.println(num_col.getIntValue());
	}catch(Exception e){}
}    

}


and, this is my implementation for NodeModel
public class Prova_dialogNodeModel extends NodeModel {
public static final String CFG_KEY_NR_OF_COL="NumeroDiColonne";

private final SettingsModelInteger num_col=new SettingsModelInteger(Prova_dialogNodeModel.CFG_KEY_NR_OF_COL,0);

/**
 * Constructor for the node model.
 */
protected Prova_dialogNodeModel() {

    // TODO: Specify the amount of input and output ports needed.
    super(1, 1);
}

/**
 * {@inheritDoc}
 */
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
        final ExecutionContext exec) throws Exception {
	
	DataTableSpec DTS=inData[0].getDataTableSpec();
	num_col.setIntValue(DTS.getNumColumns());
	 	
    // TODO: Return a BufferedDataTable for each output port 
    return new BufferedDataTable[]{};
}

/**
 * {@inheritDoc}
 */
@Override
protected void reset() {
    // TODO: generated method stub
}

/**
 * {@inheritDoc}
 */
@Override
protected DataTableSpec[] configure(final DataTableSpec[] inSpecs)
        throws InvalidSettingsException {

    // TODO: generated method stub
    return new DataTableSpec[]{null};
}

/**
 * {@inheritDoc}
 */
@Override
protected void saveSettingsTo(final NodeSettingsWO settings) {
     // TODO: generated method stub
	
	num_col.saveSettingsTo(settings);
}

/**
 * {@inheritDoc}
 */
@Override
protected void loadValidatedSettingsFrom(final NodeSettingsRO settings)
        throws InvalidSettingsException {
    // TODO: generated method stub
	
	num_col.loadSettingsFrom(settings);
}

/**
 * {@inheritDoc}
 */
@Override
protected void validateSettings(final NodeSettingsRO settings)
        throws InvalidSettingsException {
    // TODO: generated method stub
	
	num_col.validateSettings(settings);
}

/**
 * {@inheritDoc}
 */
@Override
protected void loadInternals(final File internDir,
        final ExecutionMonitor exec) throws IOException,
        CanceledExecutionException {
    // TODO: generated method stub
}

/**
 * {@inheritDoc}
 */
@Override
protected void saveInternals(final File internDir,
        final ExecutionMonitor exec) throws IOException,
        CanceledExecutionException {
    // TODO: generated method stub
}

}


Note that the System.out.println that I insert in loadAdditionalSettingsFrom method print in console the correct number of columns
Please Help, i'm going in crazy...
I'm sorry for immense thread

Hi, it looks like if you just missed to add your components to the dialog within the for-loop in the constructor by calling super.addDialogComponent(DCCS_group[i]);
Regards, Thomas

:oops: , probably I delete it accidentally, however the problem persists. The problem is that the "for" don't run because in the Prova_dialogNodeDialog method num_col.getIntValue() returns 0.

Hi, the settings object does NOT hold the number of column at the time of initialization of this class. You need to dynamically create your components within the #loadAdditionalSettings() method by accessing the number of columns from the current DataTableSpec argument. (Just move the for-loop to the #loadAdditionalSettings() method). Make sure your remove all previously created components first, before you add the "new" components. (For example, you could use an ArrayList of type DialogComponentXXX.)
Regards, Thomas

I try to put the addDialodComponent in the loadAdditionalSettingsFrom, and the problem seems solved, but there's another problem. With this method, everytime I click on configure other components are added.
For example, if i create 2 dialogComponent in the loadAdditionalSettingsFrom, at first time that i click on configure appears 2 Component, at second time appears 4 Component and so on....

Howewer, maybe i find a solution... I acquire the necessary information in the configure method of NodeModel. Then, I pass this information to public static final SettingsModel that I declared in the NodeDialog, and use it for take the information about number of columns, etc... With this method seems to work well... There is only one problem, the DIalog don't update when i link another File Reader to Input port. I must delete my block e take it again... better than nothing

Howewer, Thanks you very much for your help

If you have other proposals, write , because I don't think that my solutions is very correct, even if it works.

Hi, within the #loadXXX() method you must remove all previously added components from your parent (super) panel, before you add the new ones. That's why I recommended a list of components added which you keeps the current set of components. You could also put a panel in between and then only remove this panel. Regarding the static field: This field should not be static, you can have a static method in the dialog which generates the SettingsModel which is used in the NodeModel and in the NodeDialogPane. Note that for each component a new SettingsModel need to be created. If you want, you could set me your source files and I will have a look at them.
Regards, Thomas

1 Like

How Can I remove all previously added components?

Hi, sorry this functionality is not offered by the default dialog implementation - as I thought. At this point, it's probably better if you directly derive from NodeDialogPane and do all the load and save by hand. It's relatively straight forward, you create your JComboBoxes, add them to your own panel, add the panel as an extra tab. During save and load, you need to call directly #addXXX() and #getXXX() on the NodeSettings object, the same in the NodeModel. Let me know, if you need an example.
Cheers, Thomas

If write me an example is better...

A look into the RenameNodeDialogPane will probably help you. It is a NodeDialog which adds components dependent on the number of input columns and derives from NodeDialogPane directly.
In the developer version of KNIME the sources are available. The short-cut Ctrl+Shift+T opens a dialog to locate java types. Type in "RenameNodeDialogPane", open and have a look into it.

That should help.

Ok, thank you very much ... I give a look to it, but I think that I'll use the solution that i found, because the use of objects Jxxx I feel a little more complex than the default ...

However , thank you very much for your help