[英]How to request focus on JComponent after changing JPanel in JFrame
I have these two classes: 我有这两节课:
class Test: 类测试:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
//frame
private static JFrame frame = new JFrame() {
private static final long serialVersionUID = 1L;
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
viewPanel = new JPanel(new BorderLayout());
add(viewPanel);
}
};
private static JPanel viewPanel;
//change the panels
public static void showView(JPanel panel) {
viewPanel.removeAll();
viewPanel.add(panel, BorderLayout.CENTER);
viewPanel.revalidate();
viewPanel.repaint();
}
//main method
public static void main (String [] args) {
SwingUtilities.invokeLater(() -> showView(Panels.panel1));
SwingUtilities.invokeLater(() -> {
frame.setVisible(true);
});
}
}
class Panels: 类面板:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
//panels
public class Panels {
//first panel
static JPanel panel1 = new JPanel() {
private static final long serialVersionUID = 1L;
{
JButton button = new JButton("Click here!");
add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
SwingUtilities.invokeLater(() -> Test.showView(panel2));
}
});
}
};
//second panel
static JPanel panel2 = new JPanel() {
private static final long serialVersionUID = 1L;
{
JTextField textField = new JTextField(5);
add(textField);
}
};
}
And as you can see, the JPanel changes inside the JFrame
, after clicking the JButton
: How can I change the JPanel from another Class? 如您所见,单击
JButton
后,JPanel在JFrame
内发生了变化: 如何从另一个类更改JPanel?
But how can I now set the focus on the JTextField
, after changing panel1 to panel2 ? 但是,在将panel1更改为panel2之后,现在如何在
JTextField
上设置焦点?
I've tried to add grabFocus();
我试图添加
grabFocus();
to the JTextField
, but it didn't work and requestFocus();
到
JTextField
,但是它不起作用并且requestFocus();
didn't work as well. 效果不佳。
Thanks in advance! 提前致谢!
showView(...)
with invokeLater. showView(...)
。 Your ActionListener is being called on the EDT, so this is unnecessary code. requestFocusInWindow()
on it after making it visible, and it should have focus. requestFocusInWindow()
,并且它应该具有焦点。 For example: 例如:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// SwingUtilities.invokeLater(() -> Test.showView(panel2)); // not needed
Test.showView(panel2);
Component[] comps = panel2.getComponents();
if (comps.length > 0) {
comps[0].requestFocusInWindow();
}
}
});
Myself, I would use CardLayout to do my swapping and would not use the kludge of getting components via getComponents()
but rather using much less brittle method calls. 我自己,我将使用CardLayout进行交换,并且不会使用通过
getComponents()
获取组件的麻烦,而是会使用不那么脆弱的方法调用。
For example: 例如:
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyPanelTest extends JPanel {
private TextFieldPanel textFieldPanel = new TextFieldPanel();
private CardLayout cardLayout = new CardLayout();
public MyPanelTest() {
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new ButtonAction("Press Me")));
setPreferredSize(new Dimension(400, 200));
setLayout(cardLayout);
add(buttonPanel, "button panel");
add(textFieldPanel, TextFieldPanel.NAME);
}
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(MyPanelTest.this, TextFieldPanel.NAME);
textFieldPanel.textFieldRequestFocus();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("My Panel Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyPanelTest());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class TextFieldPanel extends JPanel {
public static final String NAME = "TEXT_FIELD_PANEL";
private JTextField textField = new JTextField(10);
public TextFieldPanel() {
add(textField);
}
public void textFieldRequestFocus() {
textField.requestFocusInWindow();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.