Board index » jbuilder » jTabbedPane focus problem

jTabbedPane focus problem


2005-01-04 03:31:44 AM
jbuilder6
When a particular tab is selected, either with the mouse or
programmatically, I want focus to go to the top component on the
selected panel. So far I can't make this happen. I've googled and have
come up with possible solutions but no success yet.
The following almost works.
I added code to the jTabbedPane's stateChanged event to request focus
for the appropriate jPanel that will be shown for that tab.
That panel's focusGained event is successfully triggered.
In the panel's focusGained event I added code to request focus for the
component on the panel, but that does not work.
Someone suggested that the component may not be visible, so do
setVisible(true) for it. That doesn't help.
I've also tried the componentShown event instead of focusGained for the
panel, but no good.
Thanks
John
 
 

Re:jTabbedPane focus problem

Further information on what I just posted.
The component on the panel that is supposed to get focus does get focus,
but then loses it.
So now the question is, where did the focus go?
Also, to clarify, the component to get focus doesn't need to be the top
one on the panel. My earlier post may have been misleading on this
point. In the focusGained event for the panel, I'm specifying exactly
which component is to get focus.
Thanks
John
 

Re:jTabbedPane focus problem

Hi John,
I'm no expert on JTabbedPanes, but if I've understood what you are saying,
I've just knocked up a quick bit of code and calling this.validate() or
this.getContentPane().validate() seems to fix the problem you are describing
depending on whether you are using a frame or an applet.
Hence my code reads something like :-
void jTabbedPane1_mouseClicked(MouseEvent e)
{
if (jTabbedPane1.getSelectedIndex()==2)
{
this.getContentPane().validate();
jTextField3.requestFocus();
}
}
Arth
"John T. Dow" < XXXX@XXXXX.COM >wrote in message
Quote
Further information on what I just posted.

The component on the panel that is supposed to get focus does get focus,
but then loses it.

So now the question is, where did the focus go?

Also, to clarify, the component to get focus doesn't need to be the top
one on the panel. My earlier post may have been misleading on this point.
In the focusGained event for the panel, I'm specifying exactly which
component is to get focus.

Thanks

John

 

{smallsort}

Re:jTabbedPane focus problem

Arthur, your technique doesn't work for me, because
this.getContentPage() and validate() aren't defined. I've been working
with a state changed event, but I created a mouseClicked event as you
have and still no go.
The technique I've been trying is as follows. In the state changed
event, I request focus to the panel. When it gains focus, it requests
focus to the text field I want to ultimately have focus. I have output
statements that show this happening.
Thus, the text field gets focus, as I want.
But then it loses it. I have a focus lost event on the text field and
display getOppositeComponent and it goes to a text field that I haven't
defined. It doesn't display the name, only the coordinates and colors
etc, but the coordinates don't match anything I've created.
Except for focus going to this phantom jdbTextField, it works. But why
is it doing that, and what is the field?
I haven't trie the de{*word*81}, perhaps that will help.
John
Arthur Ore wrote:
Quote
Hi John,

I'm no expert on JTabbedPanes, but if I've understood what you are saying,
I've just knocked up a quick bit of code and calling this.validate() or
this.getContentPane().validate() seems to fix the problem you are describing
depending on whether you are using a frame or an applet.

Hence my code reads something like :-

void jTabbedPane1_mouseClicked(MouseEvent e)
{
if (jTabbedPane1.getSelectedIndex()==2)
{
this.getContentPane().validate();
jTextField3.requestFocus();
}

}

Arth


"John T. Dow" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>Further information on what I just posted.
>
>The component on the panel that is supposed to get focus does get focus,
>but then loses it.
>
>So now the question is, where did the focus go?
>
>Also, to clarify, the component to get focus doesn't need to be the top
>one on the panel. My earlier post may have been misleading on this point.
>In the focusGained event for the panel, I'm specifying exactly which
>component is to get focus.
>
>Thanks
>
>John
>



 

Re:jTabbedPane focus problem

John,
It works for me. (Just tried it) What surrounding container are you using
that doesn't have a validate() method? I assume you aren't using a JApplet?
If you type this.validate() are you sure this isn't a valid method?
validate() is a method of awt.Container, which many containers such as
JFrame inherit from.
I didn't need to request focus to the panel, I just called it directly on
the component that I wanted to end up with the focus, after calling
validate().
Perhaps you need to post a very simple example that demonstrates your
problem. You also haven't said which version of JBuilder and which JDK you
are using. Perhaps this is affecting what you are doing.
Arth
"John T. Dow" < XXXX@XXXXX.COM >wrote in message
Quote
Arthur, your technique doesn't work for me, because this.getContentPage()
and validate() aren't defined. I've been working with a state changed
event, but I created a mouseClicked event as you have and still no go.

 

Re:jTabbedPane focus problem

Arth
Quote
It works for me. (Just tried it) What surrounding container are you using
that doesn't have a validate() method? I assume you aren't using a JApplet?
If you type this.validate() are you sure this isn't a valid method?
validate() is a method of awt.Container, which many containers such as
JFrame inherit from.
1 - this.validate() and this.getContentPane() don't work. Neither is
defined. I don't know why. But, I can explicitly name the outermost
panel and validate, no problem. So I've tried that as a workaround.
2 - You probably changed the tab by clicking the mouse on the tab. I've
been trying to change the tab programmatically by doing
setSelectedIndex(appropriatetabindex).
I have found that clicking the tab made focus to go the desired text
field. In fact, validate wasn't necessary. But calling setSelectedIndex
does not work.
After playing with it some more, I find that clicking the tab doesn't
always work.
Displays I've put in show that the text field gets focus, then loses it.
At first it seemed that focus was going to some unknown text field (I
couldn't identify it by coordinates or size). Later on the focus was
going to one of my buttons (not on the tabbed pane but on an enclosing
panel). These buttons that weren't supposed to get focus, so I did
setFocusable(false) for all of them. Now the the focus goes to a
"RepeatButton". But I have no repeatbutton in my application!
Looks like a bug to me.
My java is 1.4.2_01-b06 (the version on the JBuilder CD).
My JBuilder is X Enterprise.
My application has over 20 internal frames, and the problem tabbed pane
is on one of them. It's a fairly complicated one, so I tried all of this
on a much simpler internal frame and got the same results.
Bottom line: calling component.requestFocus() in the stateChanged event
works some but not all of the time when the tab is clicked with the
mouse, but it never works when setSelectedIndex is called because the
component gets focus but then loses it to la-la land.
John
Quote

I didn't need to request focus to the panel, I just called it directly on
the component that I wanted to end up with the focus, after calling
validate().

Perhaps you need to post a very simple example that demonstrates your
problem. You also haven't said which version of JBuilder and which JDK you
are using. Perhaps this is affecting what you are doing.

Arth

"John T. Dow" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>Arthur, your technique doesn't work for me, because this.getContentPage()
>and validate() aren't defined. I've been working with a state changed
>event, but I created a mouseClicked event as you have and still no go.
>



 

Re:jTabbedPane focus problem

I'm using JBuilderX Ent too, (JDK 1.4.2_06-b03). If I've understood what you
are asking, the following works for me. Click any of the buttons or on the
tabs and the field I specified always seems to get focus. Hope this helps. I
assume you know you can search for bugs at www.javasoft.com. There do seem
to be some issues with JTabbedPanes. However, if you can narrow your code
down to always get a reproducible error and you can't find a bug then you
could post it here and someone may be able to help.
Arth
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Frame1
extends JFrame
{
JTabbedPane jTabbedPane1 = new JTabbedPane();
JPanel jPanel2 = new JPanel();
JPanel jPanel3 = new JPanel();
JButton jButton1 = new JButton("jButton1");
JButton jButton2 = new JButton("jButton1");
JPanel jPanel1 = new JPanel();
JTextField jTextField2 = new JTextField("jTextField2");
JTextField jTextField1 = new JTextField("jTextField1");
JTextField jTextField3 = new JTextField("jTextField3");
public Frame1()
{
try
{
jbInit();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
this.setSize(new Dimension(400, 300));
jTabbedPane1.addChangeListener(new javax.swing.event.ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
jTabbedPane1_stateChanged(e);
}
});
jButton1.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jButton1_actionPerformed(e);
}
});
jButton2.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jButton1_actionPerformed(e);
}
});
jButton2.setText("jButton2");
this.getContentPane().add(jTabbedPane1, BorderLayout.CENTER);
jTabbedPane1.add(jPanel2, "jPanel2");
jPanel2.add(jButton1, null);
jTabbedPane1.add(jPanel3, "jPanel3");
jPanel3.add(jButton2, null);
jTabbedPane1.add(jPanel1, "jPanel1");
jPanel1.add(jTextField1, null);
jPanel1.add(jTextField2, null);
jPanel1.add(jTextField3, null);
}
public static void main(String[] args)
{
Frame1 frame = new Frame1();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
frame.setLocation( (screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
}
void jTabbedPane1_stateChanged(ChangeEvent e)
{
if (jTabbedPane1.getSelectedIndex() == 2)
{
//this.validate(); works without validate here
jTextField2.requestFocus();
}
}
void jButton1_actionPerformed(ActionEvent e)
{
jTabbedPane1.setSelectedIndex(2);
this.validate(); // validate needed otherwise component doesn't retain
focus
jTextField2.requestFocus();
}
}
 

Re:jTabbedPane focus problem

Solution found!
Arth, your solution worked for me as a demo, but not in my application.
I had googled for a solution but didn't look for a bug. Doing so was
helpful. This bug is relevant:
Bug ID: 5089436 REGRESSION:requestFocusInWindow() fails for comp. on
JTabbedPane aftertab switch
The description indicates that the bug developed in later versions of
java, not the one I have, but the workaround (to use invokeLater) solved
the problem for me.
Here's what I have.
To change the tab programmatically:
jTabbedPane1.setSelectedIndex(indexOfNewTab);
Put this code in the jTabbedPane1_stateChanged event.
int index = jTabbedPane1.getSelectedIndex();
...
if (index == indexOfNewTab) {
Runnable ComponentOnNewTab_RequestFocusLater = new Runnable() {
public void run() {
ComponentOnNewTab.requestFocus();
}
};
SwingUtilities.invokeLater(ComponentOnNewTab_RequestFocusLater);
}
Finally, I had some requestFocusInWindow() calls in the focusLost events
for several components (on the old tab). These were to override the
default focus traversal policy of top to bottom, left to right. Somehow
these requestFocusInWindow calls can be honored even though the tab has
changed. So I found it necessary to explicitly test for that.
void ComponentOnOldTab_focusLost(FocusEvent e) {
if (jTabbedPane1.getSelectedIndex() == indexOfOldTab) {
NextComponentOnOldTab.requestFocusInWindow();
}
}
With these changes, every time I change the tab with the mouse the focus
goes to the proper componet (before it did some of the time). And every
time I change the tab programmatically focus goes to the proper
component (before it never did).
It would be nice to not have to test for the current tab before
requesting focus as I show with "ComponentOnOldTab" above. It would be
nice if the stateChanged event could somehow declare that focus is
leaving the current tab to so no more focus lost events should be
honored on the old tab.
Anyway, solution found.
Arth, thanks for your help.
John
Arthur Ore wrote:
Quote
I'm using JBuilderX Ent too, (JDK 1.4.2_06-b03). If I've understood what you
are asking, the following works for me. Click any of the buttons or on the
tabs and the field I specified always seems to get focus. Hope this helps. I
assume you know you can search for bugs at www.javasoft.com. There do seem
to be some issues with JTabbedPanes. However, if you can narrow your code
down to always get a reproducible error and you can't find a bug then you
could post it here and someone may be able to help.

Arth

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Frame1
extends JFrame
{
JTabbedPane jTabbedPane1 = new JTabbedPane();
JPanel jPanel2 = new JPanel();
JPanel jPanel3 = new JPanel();
JButton jButton1 = new JButton("jButton1");
JButton jButton2 = new JButton("jButton1");
JPanel jPanel1 = new JPanel();
JTextField jTextField2 = new JTextField("jTextField2");
JTextField jTextField1 = new JTextField("jTextField1");
JTextField jTextField3 = new JTextField("jTextField3");
public Frame1()
{
try
{
jbInit();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
this.setSize(new Dimension(400, 300));
jTabbedPane1.addChangeListener(new javax.swing.event.ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
jTabbedPane1_stateChanged(e);
}
});
jButton1.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jButton1_actionPerformed(e);
}
});
jButton2.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jButton1_actionPerformed(e);
}
});
jButton2.setText("jButton2");
this.getContentPane().add(jTabbedPane1, BorderLayout.CENTER);
jTabbedPane1.add(jPanel2, "jPanel2");
jPanel2.add(jButton1, null);
jTabbedPane1.add(jPanel3, "jPanel3");
jPanel3.add(jButton2, null);
jTabbedPane1.add(jPanel1, "jPanel1");
jPanel1.add(jTextField1, null);
jPanel1.add(jTextField2, null);
jPanel1.add(jTextField3, null);
}

public static void main(String[] args)
{

Frame1 frame = new Frame1();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
frame.setLocation( (screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
}

void jTabbedPane1_stateChanged(ChangeEvent e)
{
if (jTabbedPane1.getSelectedIndex() == 2)
{
//this.validate(); works without validate here
jTextField2.requestFocus();
}
}

void jButton1_actionPerformed(ActionEvent e)
{
jTabbedPane1.setSelectedIndex(2);
this.validate(); // validate needed otherwise component doesn't retain
focus
jTextField2.requestFocus();
}

}