问题
I have a swing GUI with multiple JTabbedPane
s; each tab contains two JButtons
at the top, then a JTextArea
(for user input), and a JTextField
at the bottom for a result.
My problem is that I can't get the JTextArea
to gain focus after switching tabs without either clicking in it with the mouse or using the tab key on the keyboard?
I have...
frame.addWindowFocusListener(new WindowAdapter() {
public void windowGainedFocus(WindowEvent e) {
textArea_1.requestFocusInWindow();
...and this works well when the app is first run (the textArea in the first tab has focus) but when I switch to another tabbedpane the first button now has the focus instead of the textArea, and when I switch back to the first tab the textArea has lost focus and once again the first button has focus.
I've tried adding a requestFocus to each textArea, and I've tried "Bring to front" on each textArea, and I've messed around with Focus Traversal but nothing I do seems to make the textArea gain focus on a tab change?
This has had me stumped for a week so any help will be gratefully received?
回答1:
Add a ChangeListener to your JTabbedPane. Here's the general idea:
[Sorry, I used JTextFields instead of JTextAreas since I had an old stub laying around - but the idea is the same.]
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class JTabbedPaneDemo3 implements Runnable
{
JTextField txtFoo;
JTextField txtBar;
JTabbedPane tabbedPane;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new JTabbedPaneDemo3());
}
public void run()
{
txtFoo = new JTextField(10);
final JPanel pnlFoo = new JPanel();
pnlFoo.add(new JButton("Button 1"));
pnlFoo.add(new JLabel("Foo"));
pnlFoo.add(txtFoo);
txtBar = new JTextField(10);
final JPanel pnlBar = new JPanel();
pnlBar.add(new JButton("Button 3"));
pnlBar.add(new JLabel("Bar"));
pnlBar.add(txtBar);
tabbedPane = new JTabbedPane();
tabbedPane.addTab("Tab 1", pnlFoo);
tabbedPane.addTab("Tab 2", pnlBar);
tabbedPane.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
Component comp = tabbedPane.getSelectedComponent();
if (comp.equals(pnlFoo))
{
txtFoo.requestFocusInWindow();
}
else if (comp.equals(pnlBar))
{
txtBar.requestFocusInWindow();
}
}
});
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(460, 200);
frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
txtFoo.requestFocusInWindow();
}
}
回答2:
I couldn't make "getSelectedComponent()" work for me, it just wasn't seeing any changes made to the tab selection, but I modified your suggestion slightly and took MadProgrammer's advice and added invokeLater...
tabbedPane.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
JTabbedPane pane = (JTabbedPane) e.getSource();
int selectedIndex = pane.getSelectedIndex();
if (selectedIndex == 0)
{
SwingUtilities.invokeLater( new Runnable() {
public void run() {
textArea1.requestFocusInWindow(); }});
}
else if (selectedIndex == 1)
{
SwingUtilities.invokeLater( new Runnable() {
public void run() {
textArea2.requestFocusInWindow(); }});
}
else if (selectedIndex == 2)
{
SwingUtilities.invokeLater( new Runnable() {
public void run() {
textArea3.requestFocusInWindow(); }});
}
else if (selectedIndex == 3)
{
SwingUtilities.invokeLater( new Runnable() {
public void run() {
textArea4.requestFocusInWindow(); }});
}
else if (selectedIndex == 4)
{
SwingUtilities.invokeLater( new Runnable() {
public void run() {
textArea5.requestFocusInWindow(); }});
}
}
});
...and now all is right with the world again! Thanks to all.
来源:https://stackoverflow.com/questions/14265326/java-how-do-i-gain-focus-on-jtextarea-when-selecting-a-new-jtabbedpane