I am trying to use some java gui in my matlab code.
I want to create a Jpanel containing lots of buttons , and add this Jpanel to a JscrollPane to be able to scroll up and down, right and left through the Jpanel.
I tried using JavaComponent() function as described in : http://undocumentedmatlab.com/blog/javacomponent
here is my code:
[jpanel1, hpanel1] = javacomponent('javax.swing.JPanel');
[jButton1, hButton1] = javacomponent('javax.swing.JButton');
[jscroll, hscroll] = javacomponent('javax.swing.JScrollPane');
jButton1.setText('Click again!');
set(hButton1,'position',[5 5 50 50])
set(hpanel1,'position',[50 50 500 500],'BackgroundColor','white');
jpanel1.add(jButton1);
jscroll.add(jpanel1);
The panel and button are created but I can't find the scrollpane, tried setting the jscroll to visible with no results.
WHat am I missing out??
You only need to use javacomponent once, to display the outer-most java container, i.e. JScrollPane in your case. Just assemble your components inside JPanel container and then pass that to JScrollPane constructor.
Note that it is safer to create your objects with javaObjectEDT so that subsequent method calls run on EDT - otherwise you could face a deadlock / race condition.
Finally, note how you can use getpixelposition and 'normalized' units for the container created by javacomponent to make your JScrollPane fill the entire parent drawing area, and behave better on resizing.
jButton1 = javaObjectEDT('javax.swing.JButton', 'Button 1');
jButton2 = javaObjectEDT('javax.swing.JButton', 'Button 2');
jPanel = javax.swing.JPanel();
jPanel.add(jButton1);
jPanel.add(jButton2);
jScrollPane = javax.swing.JScrollPane(jPanel);
hFig = figure();
hParent = uicontainer('Parent',hFig);
parentPixelPos = getpixelposition(hParent);
pos = [1,1,parentPixelPos(3),parentPixelPos(4)]; % fill the parent uicontainer completely
[~, hContainer] = javacomponent(jScrollPane, pos, hParent);
set(hContainer, 'Units', 'normalized'); % better behavior on resizing
jscroll.add(jpanel1);
You should never add components to a scroll pane. A JScrollPane has its own custom layout manager to display the scrollbars and the viewport.
So instead you need to add the panel to the viewport:
jscroll.setViewportView( jpanel1 );
However, this may still not work as the following code looks like it is trying to set the size/location of the component which implies a null layout is being used:
set(hButton1,'position',[5 5 50 50])
Normally it is the responsibility of the layout manager to determine the size/location of a component and the scrollbars of the scrollpane will only be displayed is the preferred size of the panel is greater than the size of the scrollpane.
I don't know that the benefit of using MatLab is. I suggest you just use normal Swing. See examples from the Swing tutorial on Using Layout Managers.
Related
I want to design my levels on a horizontal pane what i am doing is:
container = new Table(skin);
container.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
levelselect = new Table(skin);
levelselect.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
// list = new List(skin,"1");
scrollPane = new ScrollPane(levelselect);
scrollPane.layout();
levelselect.align(Align.left);
for(int i=1;i<20;i++){
levelnumber = new Label(" "+i,levelnumbertext);
levelselect.add(levelnumber);
}
container.align(Align.bottom);
container.add(scrollPane).width(400).height(400);
container.add(levelselect);
any suggestions?? thanks in advance.
Using a ScrollPane and Table for this sounds like a lot of unnecessary overhead, they have a lot going on in the background, dynamically calculating their own layouts etc, you might not need this if you just want a full screen side scroller. You might be best just positioning your Actors on the Stage, however far along they need to be and update the Camera position to suit. Stage has culling options which I think by default are enabled, so it won't be drawing any of your Actors that are off the screen.
I have this code which I don't understand:
JFrame jframe = new JFrame("Risultati protocolli cercati");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel body = new JPanel();
Container c = jframe.getContentPane();
body.setSize(100, 100);
body.setLayout(new GridLayout(1000, 1));
for (int i = 0; i < 1000; i++)
body.add(new JLabel("JLabel " + i));
JScrollPane jsp = new JScrollPane(body);
c.add(jsp);
jframe.setSize(100, 100);
//jframe.add(body);
jframe.setVisible(true);
If I leave the penultimate line commented then everything appears, both labels and scroll. Instead if I uncomment that line, I see nothing. Only the JFrame. Why does it happens? For the main window of my program I had to perform jframe.add(body)...
Instead if I uncomment that line, I see nothing. Why does it happens?
The below line
jframe.add(body);
internally calls
jframe.getContentPane().add(body);
JFrame by default uses BorderLayout and add(component) method directly add it in the center section, if you add again then last one is replaced with latest one.
You can use overloaded add() method of JFrame to add it in another section east, west, north and south as shown in below snapshot:
for e.g.:
frame.add(comp,BorderLayout.NORTH); // add in north section
frame.add(comp,BorderLayout.WEST); // add in west section
You can use other Layout Managers as well as per the design or your application:
It's worth reading How to Use BorderLayout
One more suggestion:
Use frame.pack() instead of frame.setSize() that fits the components as per component's preferred size.
Interesting problem caused by the layout managers.
A component can only have a single parent. First you add the "body" to the scrollpane but then the "body" gets removed from the scrollpane when you add it to the content pane of the frame (for the reasons mentioned by #braj). Not a big deal as it just means you won't see any scrollbars.
Since the component is directly added to the content pane you should still see the labels however they do not display and this is the confusing part. Change your code to use "100" for the GridLayout and the number of components you create in the loop. When the frame first displays the panel will be empty. Now, increase the height of the frame and you will see the components appear. What is happening is that you are trying to paint too many components in a small area and because of rounding issues the height of every component becomes 0, so there is nothing to paint. When you increase the height to at least 100 pixels every component can now be 1 pixel high so you get garbage.
The only solution is to keep the "body" panel in the scrollpane so that all components will be displayed at their preferred size. Then you can scroll through all the components as required.
A tip for when using a GridLayou. You can use:
body.setLayout(new GridLayout(0, 1));
Then means the grid will have unlimited rows and a single column.
I am building a Flex 4 application which uses a <s:Scroller> component to vertically scroll overflown content. Let me explain what happens before I ask my question:
The body of the page is loaded from a database
Once the information has loaded, the "body" of the application (in this case the list of items you see below) is constructed
Once the list is constructed, the entire encapsulating component is transitioned into view using TweenMax, like so:
myComponent.visible = true;
TweenMax.to(myComponent, 1, {
alpha : 1,
y -= 20 //Slides the component up 20px from its original location
});
Below is the result. Notice how the scrollbar is scrolled the whole way down, but you can see the tips of a few white letters that were cut off at the very bottom.
Using my custom menu, I can navigate away from the page, and come back to it, and Flex will correctly recalculate the range of the scroller so I can scroll down and see all of the desired content. This issue only happens if the initial URL that the user enters is a longer page like this one.
Any ideas on how I can force Flex to recalculate the range of the scroller?
Thank you for your time.
Ok, after many hours of researching, piecing together, and trial and error here is what I came up with.
What I was doing wrong:
When I first posted this question, the "component" that I had mentioned was already added as a child element of the <s:Scroller>, but collapsed and hidden away, like this:
<comp:MyComp alpha="0" height="0" visible="false"/>
When the data would be loaded and the component's visual appearance would be restored and transitioned into place, like this:
myComp.visible = true;
myComp.height = NaN;
myComp.invalidateSize();
myComp.height = myComp.measuredHeight;
TweenMax.to(myComp, 1, {
alpha : 1,
y -= 20 //Slides the component up 20px from its original location
});
This method of approach didn't force the <s:Scroller> to recalculate its proper size until later, sometimes not until myComp was transitioned away and another component was transitioned into place using the same method. Even then, the size of the scroller would fit the size of the previous component, not the one that is currently displaying.
Now, what I am doing correctly:
My research showed me that anytime the addElement() method is called, either directly within the <s:Scroller> itself or by any of its children, the scroller's measure() method is called, and properly re-sizes the scroller.
Instead of placing the components inside of the scroller and simply hiding them until I need them, I dynamically created them in ActionScript, set their properties, and added and removed them as needed using the addElement() and removeElement() methods respectively. Now, as old elements are transitioned away and new ones take their place, the scroller re-sizes itself correctly.
There was one final problem that I was faced with. If the very first page the user was viewing (i.e. there was no previous component that was transitioned away and destroyed) required a scroller, it wouldn't show up.
I corrected this final issue by adding an event listener that listened for when the new component had finished transitioning into place. Inside of the event handler, I explicitly set the height of the component using this code:
newComp.height = NaN;
newComp.invalidateSize();
newComp.height = newComp.measuredHeight;
Now that the component has an explicit height, the scroller now appears, even if it is the first page.
The scroller now works as expected in all cases, and does not cut off any content or disappear when it shouldn't.
I hope that it is helpful to someone.
I wrote a simple gui with DesignGridLayout as layout manager.
I have a 2 JTextFields, beneath them a JScrollPane containing a JTextArea, and right under it I have a button.
Upon maximizing the JFrame, everything is stretching out nicely to fill the screen.
The problem starts when I try to restore the Frame to it's original size. the JScrollFrame Vertical size remains too large, and the Button is not shown, since it is covered by the too big Jscrollpane.
The problem is the same for manual resizing. The JScrollPane sets a new value for it's vertical size according to how much I stretch it.
I tried overriding the getScrollableTracksViewportHeight() method from Scrollable interface, but it had no affect. In addition, I had this entire setting inside a Jpanel which I removed, but it's still the same.
Any insights would be appreciated.
edit: added samples of code.
This code creates most of the Gui:
DesignGridLayout layout = new DesignGridLayout(frame);
layout.row().grid().empty().add(new JLabel("someText1"), someText1);
layout.row().grid().empty().add(new JLabel("someText2"), someText2);
layout.emptyRow();
layout.row().grid().add(new JSeparator());
layout.row().grid().empty().add(titleLabel).empty();
layout.row().grid().add(textarea("",5,6));
layout.row().grid().empty().add(button).empty();
This code creates The JScrollPane:
private JScrollPane textarea(String content, int rows, int columns)
{
JTextArea textArea = new JTextArea(rows, columns);
JScrollPane scrollPane = new JScrollPane(textArea);
return scrollPane;
}
I am having a simple problem I guess, that u should know how to solve..
I am trying to do this:
I have a JFrame.
Then I create a JPanel and set his layout to GridLayout(5,5)
Finnaly I add this JPanel to the Container of my JFrame.
When I try to get the width of my panel it shouldnt give me 0 right?
I do this: System.out.println(mypanel.getSize().getWidth()); and it says that is zero :c
why ??
I wanna know the size so I can divide per 5 and know how much to paint for each label, this will be a grid of labels..
Thanks alot in advance...
public janela(){
window = new JFrame("teste");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(300,300);
contentor = window.getContentPane();
interior = new JPanel();
interior.setLayout(new GridLayout(5,5));
contentor.add(interior);
System.out.println(interior.getSize().getWidth()); //it says 0 ?!?! why??
}
thanks alot in advance guys!!!!
Panels are sized based on their layout. specifically when they are shown and doLayout() is called for you. doLayout() figures out what the appropriate size for your panel is based on the contents of the panel, and the layout manager in force. Since your panel has nothing in it, the appropriate size is 0, 0.
If you will never have anything in the panel, and want to circumvent this (0, 0) size, you can override getPreferredSize() of the panel to return a size that you want the panel to respect for layout.