I'm new using Codename One. I'm doing an app which have a Form, that has a Tab component with 14 tabs inside, every tab has a gridlayout with 42 buttons, and I want to change a property in one button.
The problem is that I don't know how to reach that button.
tabG.getContentPane().components.get(index)
tabG is the tab component, and I can reach the tab that I need, but after that I don't know how to reach the button index I want to change.
I tried
tabG.getContentPane().components.get(index).components.get(indexbutton)
But even can't compile this code.
I'll apprecciate any help.
When you create the tab you need to prepare information to find the component later. E.g. if all tabs derive from the same class then just do something like:
MyBaseContainer cnt = (MyBaseContainer)tabs.getTabComponentAt(index);
Button theButtonINeed cnt.getMyImportantButton();
If this is more complicated you can use setName() or putClientProperty to prepare hints for you during form construction.
Related
I have a component with some tabs. Each tab selector loads its own datagrid. After a tab has been selected and its datagrid has been loaded, the datagrid should be essentially cached so that toggling away and back to the tab should simply write out the previous datagrid that was loaded/cached. The datagrid entity that gets loaded for each tab/entity essentially looks like this:
<MyDataGrid entity={entity} />
I've wrapped the datagrid component definition with the memo() function like this:
const MyDataGrid = memo((props: IncludeListProps): React.ReactElement => {
debugger;
});
However, the debugger breakpoint is getting hit within the component every time. What is the sequence of steps that you would use to go about troubleshooting something like this?
UPDATE
Providing some additional info based on comments below. A tab strip on top refreshes the display div underneath. So yes the props of MyDataGrid change (eg props.entity.id).
But what I need to do is figure out the best way to cache/memoize each MyDataGrid created per tab. I'm thinking maybe a div collection where each div will be reserved to hold MyDataGrid for a specific tab. Then divs will display inline/none based on the current tab selection. Does this seem like the most straightforward approach?
I'm new to reactJS, get confused when trying to create dynamic (antd) tab.
Basically, i have two layers in Application, the first one is Sidemenu Bar, located on left of the screen, and the second layer is content pages, which represented with Tabs.
The Sidemenu has some variable numbers of menu buttons (modules). When each button are pressed, then React will render that module (each module represent by individual JSfile) to the content layer, inside a new Tab panel. The module page itself, can be duplicated on the Tab.
To do that I created a sidemenu.js which contain a menu buttons (and its corresponding URL), and appPages.js to hold that Tabs that will render the specific module(s).
How to make it possible ? where I should write the routes (react-router-dom) ?
I search for this topic, and found it solved using the same js file, not the separated file or component.
Please check my sandbox here : https://codesandbox.io/s/dynamictabs-83mop
Thank you. Really appreciated for any help, and so sorry about my english.
On a given form, we replace one component with another.
The original component is a series of TextFields, and the new form is some informational text and a button. We hide the first one, and show the second one (the UI designer has both Containers within the form).
I tried using scrollRectToVisible with various values but it didn't seem to make any difference with the scrolling.
continueButtonContainer.setHidden(false);
f.forceRevalidate();
Button continueButton =
(Button)StateMachine.GetInstance().findByName("ButtonContinue", f);
f.scrollComponentToVisible(continueButtonContainer);
f.scrollComponentToVisible(continueButton);
I'm expecting the continue button to be near the top of the screen.
If the screen was scrolled before displaying the continue button, the button ends up right at the bottom of the screen (it was below the bottom of the screen before I put in the scrollComponentToVisible line(s).
After the user scrolls the screen, the button goes up to where it needs to be, and stays there.
If the screen is not scrolled, the button appears where it should be.
I know I can probably add some invisible containers underneath the button and force them onto the screen, but I would rather have a slightly more robust solution.
There are a few issues with this. First you are using forceRevalidate which should be used in very rare cases.
Second it seems that you are invoking this on a Form, this is a bit misleading. While it seems that:
f.add(myCmp);
Adds a component to the form it is really a synonym to:
f.getContentPane().add(myCmp);
That's important because you need to invoke the scrollComponentToVisible on the scrollable container which will actually do the work and ideally be the direct parent of said component. I'm assuming it's the content pane in your case but it depends on layout etc.
The last part is letting the layout do its job. If you are invoking this before the form is showing this might not work. Notice that doing it after a call to show is meaningless as the form might take time with transitions. You can use a show listener or override the laidOut callback method to perform things like this.
I tried this code:
FloatingActionButton badge = FloatingActionButton.createBadge("33");
badge.bindFabToContainer(tabs.getTabComponentAt(3), Component.RIGHT, Component.TOP);
However for some reason I get a
java.lang.IllegalArgumentException: Component is already contained in Container
exception.
I tried also:
tabs.getTabsContainer().getComponentAt(3)
without success.
Bind creates a new container that should be added instead of the component. This won't work for a case like tabs where the button be added when you add a tab component. You are also relying on internal behavior of looking up a specific tab which is pretty fragile to begin with.
You can use the approach listed here which shows how you can create a completely custom component to represent a tab.
Using CodenameOne,
I have a Form that the user needs to fill in. All of the components, however, are actually Containers that represent custom functionality. As an example, I would have a TextField alongside a Button on a Container, and I would use that Container as a "Component". This allows me to create more advanced functionality by combining existing Components.
A good example of where this is necessary is that of a custom date entry field existing out of 3 TextFields or a combination of TextFields and ComboBoxes.
I have a "Field" that has functionality for that of a Contact Component.
This all serves as a single "Unit" in order to allow the user to choose a contact or fill in their own. Buttons open Dialog popups, etc.
My problems comes with when the user uses the Android keyboard. Should this Contact Object be the second "Field" and the user presses the 'Next' button on the Android keyboard, the App does not know what field to give focus.
Furthermore, If one of the fields are a ComboBox or a Button and the user presses next to reach that Component, the keyboard doesn't close, and instead removes the 'Next' button, replacing it with a return button or an emoticon selector.
Below is an example situation:
The user would press on the first field, the Keyboard shows up, and when the user presses next, the keyboard's Next button dissapears, as the immediate next field happens to be a Button or ComboBox.
Is there a way to change the focusing index, or omit certain fields form ever gaining focus in this way? I tried making the entire thing a Component but that doesnt allow me to combine other Components. Even if it is possible to make the parent Container a Component, how would I solve this particular issue?
The default behavior is to use the "next focus down" for this functionality so just use setNextFocusDown(nextTextField) on each one of the components. Notice that a ComboBox won't work as expected although you might want to change that to an AutoCompleteTextField which would.