Java 错误的组件(在单独的JPanel类中)获得焦点
我正在开发一个具有以下结构的应用程序:Java 错误的组件(在单独的JPanel类中)获得焦点,java,swing,focus,components,setfocus,Java,Swing,Focus,Components,Setfocus,我正在开发一个具有以下结构的应用程序: FrmMain(其中包含我要添加“布局”面板的面板) PnlNewCase(设置为接收区域特定面板的“布局”面板) PnlNewCaseNotes(添加到PnlNewCase的面板之一) pnlnewparts选择(我存在的祸根) 我的想法是,每当我在PnlNewPartsSelection中创建一个新页面时,每当它被实例化时,我都会聚焦一个特定的JTextField(tfNom),但每当我尝试这样做时,焦点都会被设置为另一个JTextField(tfAd
private void btnNewRepActionPerformed(java.awt.event.ActionEvent evt) {
tabs.addTab("R" + tabNo++, p);
tabs.setSelectedIndex(tabNo);
}
public PnlNewCase(boolean isNewRep) {
initComponents();
checkRepStatus(isNewRep);
}
private void checkRepStatus(boolean isNewRep) {
if (isNewRep) {
btnNewNote.setVisible(false);
PnlNewCaseNotes p1 = new PnlNewCaseNotes();
pnlNotes.add(p1);
PnlNewPartsSelection p2 = new PnlNewPartsSelection();
JTextField t = p2.getTfNom();
pnlPartsCustomer.add(p2);
t.requestFocusInWindow();
validate();
}
}
public PnlNewCaseNotes() {
initComponents();
}
public PnlNewPartsSelection() {
initComponents();
}
/* A bunch of method calls to add place holders */
public JTextField getTfNom() {
return tfNom;
}
JPanel PnlNewCase:
private void btnNewRepActionPerformed(java.awt.event.ActionEvent evt) {
tabs.addTab("R" + tabNo++, p);
tabs.setSelectedIndex(tabNo);
}
public PnlNewCase(boolean isNewRep) {
initComponents();
checkRepStatus(isNewRep);
}
private void checkRepStatus(boolean isNewRep) {
if (isNewRep) {
btnNewNote.setVisible(false);
PnlNewCaseNotes p1 = new PnlNewCaseNotes();
pnlNotes.add(p1);
PnlNewPartsSelection p2 = new PnlNewPartsSelection();
JTextField t = p2.getTfNom();
pnlPartsCustomer.add(p2);
t.requestFocusInWindow();
validate();
}
}
public PnlNewCaseNotes() {
initComponents();
}
public PnlNewPartsSelection() {
initComponents();
}
/* A bunch of method calls to add place holders */
public JTextField getTfNom() {
return tfNom;
}
JPanel pnlnewcase注释:
private void btnNewRepActionPerformed(java.awt.event.ActionEvent evt) {
tabs.addTab("R" + tabNo++, p);
tabs.setSelectedIndex(tabNo);
}
public PnlNewCase(boolean isNewRep) {
initComponents();
checkRepStatus(isNewRep);
}
private void checkRepStatus(boolean isNewRep) {
if (isNewRep) {
btnNewNote.setVisible(false);
PnlNewCaseNotes p1 = new PnlNewCaseNotes();
pnlNotes.add(p1);
PnlNewPartsSelection p2 = new PnlNewPartsSelection();
JTextField t = p2.getTfNom();
pnlPartsCustomer.add(p2);
t.requestFocusInWindow();
validate();
}
}
public PnlNewCaseNotes() {
initComponents();
}
public PnlNewPartsSelection() {
initComponents();
}
/* A bunch of method calls to add place holders */
public JTextField getTfNom() {
return tfNom;
}
JPanel pnlnewparts选择:
private void btnNewRepActionPerformed(java.awt.event.ActionEvent evt) {
tabs.addTab("R" + tabNo++, p);
tabs.setSelectedIndex(tabNo);
}
public PnlNewCase(boolean isNewRep) {
initComponents();
checkRepStatus(isNewRep);
}
private void checkRepStatus(boolean isNewRep) {
if (isNewRep) {
btnNewNote.setVisible(false);
PnlNewCaseNotes p1 = new PnlNewCaseNotes();
pnlNotes.add(p1);
PnlNewPartsSelection p2 = new PnlNewPartsSelection();
JTextField t = p2.getTfNom();
pnlPartsCustomer.add(p2);
t.requestFocusInWindow();
validate();
}
}
public PnlNewCaseNotes() {
initComponents();
}
public PnlNewPartsSelection() {
initComponents();
}
/* A bunch of method calls to add place holders */
public JTextField getTfNom() {
return tfNom;
}
如果需要,我也可以发布每个类的代码(我只是认为这应该足够了)
期待您的评论:)退后一步,浏览您的代码。让我们假设你正在做类似的事情
add(new PnlNewCase(true));
如果您浏览代码,您会发现它调用:
构造函数(为实例字段指定默认值)PnlNewCase
initComponents
。此时,您开始构建代码并调用checkRepStatus
t.requestFocusInWindow
- 调用
将add
的新实例传递到容器PnlNewCase
t.requestFocusInWindow
时,组件本身或其附加到的容器都没有添加到UI中,因此无法为字段指定焦点
相反,将组件添加到UI中,然后向字段请求焦点。由于框架的工作方式,您可能会发现还需要使用SwingUtilities.invokeLater
使焦点工作
也许做点像
public class PnlNewCase extends JPanel {
private PnlNewPartsSelection p2;
public PnlNewCase(boolean isNewRep) {
//...
}
private void checkRepStatus(boolean isNewRep) {
if (isNewRep) {
//...
p2 = new PnlNewPartsSelection();
//...
//t.requestFocusInWindow();
}
}
public void focusPrimaryField() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
p2.getTfNom().requestFocusInWindow();
}
});
}
}
PnlNewCase newCase = new PnlNewCase(true);
add(newCase);
revalidate();
repaint();
newCase.focusPrimaryField()
然后你可以做一些简单的事情,比如
public class PnlNewCase extends JPanel {
private PnlNewPartsSelection p2;
public PnlNewCase(boolean isNewRep) {
//...
}
private void checkRepStatus(boolean isNewRep) {
if (isNewRep) {
//...
p2 = new PnlNewPartsSelection();
//...
//t.requestFocusInWindow();
}
}
public void focusPrimaryField() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
p2.getTfNom().requestFocusInWindow();
}
});
}
}
PnlNewCase newCase = new PnlNewCase(true);
add(newCase);
revalidate();
repaint();
newCase.focusPrimaryField()
总的来说
您可能还想看一看,以便更好地理解,也许还有更多的想法调用
t.requestFocusInWindow()
时,PnlNewCase
不太可能在屏幕上显示物理属性,这会使调用静音。您需要首先在UI上实现PnlNewCase
,然后重定向控件。可能在您调用add
(和revalidate
/repaint
)之后,调用requestFocusInWindow
。。。您可能会发现您需要使用SwingUtilities.invokeLater
使其正常工作。感谢您花时间回答我的问题!你帮助我了解了问题所在,我为此感谢你。另一方面,我很难理解最后一段代码是如何发挥作用的。特别是newCase.focusPrimaryField()调用。据我所知,您将focusPrimaryField()方法添加到PnlNewCase类中,但我不知道最后一个片段应该在哪里。FrmMain?我们的想法是延迟请求焦点,直到您能够更好地保证在屏幕上建立ui。这里的重要部分是建立ui(添加组件,如果可能,在屏幕上实现)。您可以在setVisible
之前添加对focusPrimaryField
的调用,它“可能”会起作用,但在setVisible
调用之后添加它可能更安全,如果可能的话。我的结构是制表符创建、主面板追加、上下文面板追加,我已经尝试添加对focusPrimaryField的调用(在PnlNewCase中找到)在制表符创建过程结束时,这将对应于返回根调用,但它没有起作用。我可能很难理解你到底建议我如何处理你发布的内容。此外,我还向一些经验更丰富的同龄人求助,他们建议我使用自定义遍历策略,我已经尝试过了,但没有成功。