Find components in Java's GUI hierarchy - java

With this code I am able to find what tab is selected but I need to do stuff with what is inside the tab. How do I work with the hierarchy?
EditPane.addChangeListener(new ChangeListener() {
// This method is called whenever the selected tab changes
public void stateChanged(ChangeEvent evt) {
JTabbedPane pane = (JTabbedPane)evt.getSource();
// Gets current tab
int sel = pane.getSelectedIndex();
}
});
The component that is inside the tab is a JScrollPane.

You don't need the index of the pane, you need the component selected underneath.
use getSelectedComponent() - e.g.
JTabbedPane pane = (JTabbedPane)evt.getSource();
JComponent myComponent = pane.getSelectedComponent();
To clarify your original goal, you want to manipulate the client object living in the JScrollPane. You're missing some objects.
in your JScrollPane you need to invoke getViewport().getViewportView() from the ScrollPane. (Source: http://download.oracle.com/javase/tutorial/uiswing/components/scrollpane.html )

# Dasdasd
I already checked it out but it only returns ViewPorts and ScrollBars
yes that correct, (probalby there you put JPanel) then you have to repeats your steps again, until as you will not find JPanel into ViewPort, that's possible get JComponents another way(s), but this is very good lesson for Hierarchy of JComponents
Component[] components = xxx.getComponents();
for (int i = 0, l = components.length; i < l; i++) {
if (components[i] instanceof JScrollPane) {
JScrollPane scr = (JScrollPane) components[i];
Component[] components1 = scr.getComponents();n

Related

How to control a panel nested in JtabbedPane ?

I have a MainJtabbedPane which contains multiple JtabbedPanes each of the JtabbedPanes contain multiple pannels.
I need to be able to access the pannels from the MainJtabbedPane.
JTabbedPane[] components = (JTabbedPane[]) Main_Tabbed_Panel.getComponents();
for(int i=0; i<components.length;i++)
{
for(int j=0;j<components[i].getTabCount();j++)
{
.....
}
}
Giving an error java.awt.component cannot be cast to javax.swing.JtabbedPane
JTabbedPane[] components = (JTabbedPane[]) Main_Tabbed_Panel.getComponents();
The getComponents() method returns an array of Components. You can't just cast them to a JTabbedPane even if you know all the components will be an instance of JTabbedPane. You need to structure your code something like:
for(Component component: main_Tabbed_Panel.getComponents())
{
if (component instanceof JTabbedPane)
{
JTabbedPane tabbePane = (JTabbedPane)component;
// do something with the tabbed pane
}
}
Also, follow Java naming conventions. Variable name should NOT start with an upper case character. (ie. "Main_Tabbed_Pane does not follow conventions).
Switch the (JTabbedPane[]) cast to (Component[]). If you hover over the getComponents() method, you'll see it returns Component[]
If you want to convert that Component[] to JTabbedPane[], you need to do it manually, as well as making sure to check for mistakes along the way (making sure its a JTabbedPane before adding it to a JTabbedPane[])
JTabbedPane[] panes = convertComponents(getComponents());
private JTabbedPane[] convertComponents(Component[] comps) {
JTabbedPane[] panes = comps.length > 0? new JTabbedPane[comps.length] : null;
if(panes != null)
for(int i = 0; i < panes.length; i++) {
if(comps[i] instanceof JTabbedPane)
panes[i] = (JTabbedPane) comps[i];
}
return panes;
}
Although this isn't the most efficient, because for each item that isn't a JTabbedPane in getComponents(), there will be an empty spot in your JTabbedPane array, which you then have to clean up.
JTabbedPane[] panes = comps.length > 0? new JTabbedPane[comps.length] : null;
This first checks if the Component[] passed through the parameters has 1 or more spaces. If not, dont bother initializing with an instance.
if(panes != null)
Since theres a chance panes could initialize as null, we much check before trying to use it
for(int i = 0; i < panes.length-1; i++) {
Since Component[] comps and JTabbedPane[] panes have the same size, it doesn't matter which length you use, as long as we know how many times to loop.
if(comps[i] instanceof JTabbedPane)
This is what I meant where I said "if the component isn't a JTabbedPane, you will have a null space in your array". This will check if it's a JTabbedPane before putting it in our panes array. If not, it's ignored completely, and that space in panes is left as null
After the loop is complete, it will return the array we just made.

Get shown component in JScrollPane

I have a JScrollPane containing a JPanel. I fill this JPanel with many buttons.
Is there any possibility to get the currently shown buttons?
I know I can access the children of a JPanel via jpanel.getComponents() but those are all components in this pane; I want only the ones that are currently on screen.
As already commented to #mKorbel's answer:
it's correct that you need the child bounds
it's correct that you need to intersect those bounds with "something"
it's wrong that you need the containing viewport (nor the scrollpane)
JComponents have an API to get their currently visible part independently of how/where exactly they are currently shown, so the "something" is the JComponent's visibleRect:
Rectangle visibleRect = myPanel.getVisibleRect();
for (Component child : myPanel.getComponents()) {
Rectangle childBounds = child.getBounds();
if (childBounds.intersects(visibleRect)) {
// do stuff
}
}
I assume that this container is already visible on the screen, then I suggest
1) to extract JViewPort from JScrollPane,
2) addChangeListener to JViewPort
3) each visible JComponent(s) returns Rectangle
4) and Rectangle#intersects returns Boolean value if is JComponent(s) visible or not in JViewPort
How about asking the components if they're visible:
for ( Component component : jpanel.getComponents() ) {
if ( component instanceof JButton && component.isShowing() ) {
// We've found a button that is showing...
}
}
Component#isShowing()
scrollPane.getViewport().getView()
scrollPane.getViewport().getViewRect()

Update component position at run time

I'm currently stuck with the following problem:
I need to dynamically update component positioning at run time. I'm making a form editor for an external application. I use wrapper-classes for standard Swing components, currently JPanel and JLabel. Panels are using TableLayout. I'm storing each component position in a field for each component. When something is changed, I need to recursively update all positions. Here is my method for updating positions:
public void updatePositioning() {
Component[] comps = getComponents();
removeAll();
for (Component comp:comps) {
System.out.println("Moving component "+comp + " to x="+pos.get(comp).getX()
+" to y="+pos.get(comp).getY());
c = new TableLayoutConstraints(String.valueOf(pos.get(comp).getX())+","
+String.valueOf(pos.get(comp).getY()));
add(comp, c);
if (comp instanceof EditPanel) ((EditPanel)comp).updatePositioning();
}
repaint();
revalidate();
}
I know, it's rough, but it's not working. All the components are seems to belong to 0,0 grid cell. X's and Y's are correct, as I've seen through debugger. Here is how I add components to my panel:
public void addComponent(TableLayouted comp, int x, int y) {
c = new TableLayoutConstraints(String.valueOf(x)+","+String.valueOf(y));
add((JComponent) comp, c);
//saving position of the component
pos.put((Component) comp, comp.getTablePositon());
System.out.println("Component "+comp+"added to x="+x+"y="+y);
}
Any suggestions?
Any suggestions?
JComponent.getTopLevelAncestor().validate()
I have finally solved it with the following code:
Component[] comps = getComponents();
removeAll();
layout = new TableLayout();
layout.setColumn(columns);
layout.setRow(rows);
setLayout(layout);
Which means, fully re-creating all layouts is working. Thanks everyone for help!

JScrollPane always clears my Panel

Hy.. I have a JPanel, and in this contentPanel I added some other custom panels and give them locations etc. So now I added a JScrollPane to the contentPanel and always when I scroll down it clears my contentPanel, but the panels are still there but not visible...
How can I make them visible again?
That's my code to add the Panel into the contentPanel. The x,y,j are some settingsstuff for the location because I have an fixed window.
private void reloadContentPanel() {
int x = -200, y = 0, j = 1, row = 4;
EventPanel panel = null;
int i;
for(i=0; i < this.images.size();i++)
{
panel = new EventPanel(this.images.get(i).getAbsolutePath(),
this.images.get(i).getName());
panel.setLocation(x+(j*200), y);
j++;
if(i == row) {
x = -200;
y += 205;
j = 1;
row += 5;
}
this.contentPanel.add(panel);
}
this.repaint();
}
Thanks
it sounds like you are not using a LayoutManager correctly.
after creating your JFrame (i'm guessing within your constructor) add the following (for example):
this.setLayout(new FlowLayout());
this will certainly not be the best layout manager for what you are trying to do but will stop the add calls from overriding the displayed component.
you will need to read further about LayoutManagers
besides this, it's not really advisable to extend JFrame. It's better practice to treat JFrame as a member of your class just like all the other components.
I have the answer! :)
I use a GridLayout not a FlowLayout, so it's fine and it automatically refreshes the panels =)

how to hide a text area in java swing form?

i used textarea1.setVisible(false); but still i can see the border of the text area at run time. i want the textarea to be completely invisible
Can anyone help in this issue?
It sounds like you have a Panel around your text area since setVisible(false) should definitely hide the entire component. If so, make the panel invisible. Care to post some code so we can examine and help?
You have to hide the scroll pane which your text area is sitting in. If for some reason you have no direct access to it here is the way to get it:
public static final JScrollPane getScrollPane( JComponent component ) {
Container p = component .getParent();
if (p instanceof JViewport) {
Container gp = p.getParent();
if (gp instanceof JScrollPane) {
return (JScrollPane)gp;
}
}
return null;
}
Find your textarea scrollpane, then set the visibility to false, like this:
jScrollPane4.setVisible(false);

Categories